NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name OGLight Legacy // @namespace https://openuserjs.org/users/ricoux // @version 4.2.7 // @description OGLight script for OGame // @author Oz // @license MIT // @copyright 2019, Oz // @match https://*.ogame.gameforge.com/game/* // @updateURL https://openuserjs.org/meta/ricoux/OGLight_Legacy.meta.js // @downloadURL https://openuserjs.org/install/ricoux/OGLight_Legacy.user.js // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant GM_getTab // @grant GM_saveTab // @run-at document-start // ==/UserScript== 'use strict'; // ogl lazy loading if(new URL(window.location.href).searchParams.get('oglLazy') == 'true' && !document.hasFocus()) { window.onfocus = () => window.location.href = 'https://' + window.location.host + window.location.pathname + window.location.search.replace('&oglLazy=true', ''); localStorage.setItem('ogl-redirect', false); window.stop(); } // redirect user if needed let redirect = localStorage.getItem('ogl-redirect'); if(redirect?.indexOf('https') > -1) { GM_addStyle(` body { background:#000 !important; } body * { display:none !important; } `); setTimeout(() => window.location.replace(redirect)); localStorage.setItem('ogl-redirect', false); window.stop(); } // goodbye default tooltips function goodbyeTipped() { if(typeof Tipped !== 'undefined') { for(let [key] of Object.entries(Tipped)) { Tipped[key] = function() { return false; } } } else requestAnimationFrame(() => goodbyeTipped()); } goodbyeTipped(); // #region const oglcss = ` /*css*/ :root { /* primary */ --p0:hsl(210deg 32% 3%); --p1:hsl(210deg 32% 6%); --p2:hsl(210deg 32% 9%); --p3:hsl(210deg 32% 12%); --p4:hsl(210deg 32% 15%); --p5:hsl(210deg 32% 16%); --p6:hsl(210deg 32% 30%); /* ui */ --ui1:hsl(185deg 44% 46%); --ui2:hsl(227deg 39% 44%); --uigradient:linear-gradient(90deg,#59309b, #38d7b2); --uiradius:4px; /* neon */ --neon:hsl(199deg 64% 60%); --neonborder:hsl(199deg 100% 81%); /* text */ --textblue:hsl(212deg 19% 50%); --textcyan:hsl(197deg 22% 47%); --textgold:hsl(42deg 21% 46%); --textsand:hsl(42deg 44% 60%); --textpremium:hsl(44deg 81% 58%); --textdate:hsl(224deg 100% 79%); --texttime:hsl(33deg 100% 66%); /* colors */ --gray0:hsl(0deg 0% 35%); --gray1:hsl(0deg 0% 50%); --gray2:hsl(0deg 0% 65%); --yellow0:hsl(50deg 50% 35%); --yellow1:hsl(50deg 50% 50%); --yellow2:hsl(50deg 50% 65%); --orange0:hsl(19deg 92% 67%); --red0:hsl(0deg 50% 35%); --red1:hsl(0deg 50% 50%); --red2:hsl(0deg 50% 64%); --green0:hsl(170deg 50% 35%); --green1:hsl(170deg 50% 50%); --green2:hsl(170deg 50% 65%); --blue0:hsl(210deg 50% 35%); --blue1:hsl(210deg 50% 50%); --blue2:hsl(210deg 50% 65%); /* marker */ --blue:#5476f1; --red:#da3e3e; --violet:#b646da; --green:#32b199; --yellow:#e2b431; --gray:#171f29; --white:#bbb; /* rank */ --global:hsl(0deg 89% 72%); --economy:hsl(210deg 87% 75%); --techs:hsl(150deg 49% 58%); --fleet:hsl(303deg 63% 71%); --def:hsl(19deg 69% 64%); /* resources */ --metal:hsl(240deg 24% 68%); --crystal:hsl(199deg 72% 74%); --deut:hsl(172deg 45% 46%); --energy:#f5bbb4; --dm:#c688ec; --food:hsl(316deg 21% 70%); } body { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; -moz-text-size-adjust:none; text-size-adjust:none; } body.ogl_active { overflow:hidden; } .c-right, .c-left { display:none; } .icon:not(.sprite):not(.resource):not(.lifeformsprite), .material-icons { direction:ltr; display:inline-block; font-family:'Material Icons' !important; font-weight:normal !important; font-style:normal !important; font-size:inherit !important; image-rendering:pixelated; line-height:inherit !important; letter-spacing:normal; text-transform:none; transform:rotate(0.03deg); white-space:nowrap; word-wrap:normal; -webkit-font-feature-settings:'liga'; font-feature-settings:'liga'; -webkit-font-smoothing:antialiased; } .technology .icon .level, .technology .icon .amount { font-size:10px; white-space:nowrap; } .input_replacement, input[type="text"], input[type="email"], input[type="password"], input[type="search"], .technology input[type="number"], .technology input[type="text"] { background-color:#c8d1da !important; border:none !important; border-radius:2px !important; box-shadow:0 0 0 2px #eef7fb !important; color:var(--p2) !important; font-weight:bold !important; } .technology input[type="number"][disabled], .technology input[type="text"][disabled] { background:#333c44 !important; box-shadow:0 0 0 2px #52565a !important; } #fleet1 .technology.ogl_notEnoughShips input[type="number"], #fleet1 .technology.ogl_notEnoughShips input[type="text"] #fleet1 .technology.ogl_notEnoughShips input[type="number"][disabled], #fleet1 .technology.ogl_notEnoughShips input[type="text"][disabled] { background:#dd9292 !important; } .ogl_hidden { display:none !important; } .ogl_invisible { visibility:hidden !important; } .ogl_hiddenContent { font-size:0 !important; line-height:0; } .ogl_centered { text-align:center; } .ogl_noPointer { pointer-events:none !important; } .ogl_loader { animation:spin .7s infinite linear; background:var(--uigradient) border-box; border:4px solid transparent; border-radius:100%; height:40px; margin:30px; mask-composite:exclude; width:40px; -webkit-mask:linear-gradient(#888 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite:xor; } @keyframes spin { from { transform:rotate(0); } to { transform:rotate(360deg); } } #highscoreContent .ogl_loader { position:absolute; top:14px; right:0px; } .ogl_metal, #metal_box .value, .msg .resspan[data-type="metal"] { color:var(--metal) !important; } .ogl_crystal, #crystal_box .value, .msg .resspan[data-type="crystal"] { color:var(--crystal) !important; } .ogl_deut, #deuterium_box .value, .msg .resspan[data-type="deut"] { color:var(--deut) !important; } .ogl_dm, #darkmatter_box .value, .msg .resspan[data-type="dm"] { color:var(--dm) !important; } .ogl_energy, #energy_box .value { color:var(--energy) !important; } .ogl_food, #food_box .value, .msg .resspan[data-type="food"] { color:var(--food) !important; } .ogl_fleet { color:var(--fleet) !important; } .ogl_shipList { display:grid; grid-gap:5px; grid-template-columns:repeat(4, 1fr); } .ogl_shipList .ogl_shipIcon:hover { cursor:pointer; position:relative; } .ogl_shipList .ogl_shipIcon:hover:before { border-radius:4px; bottom:0; box-shadow:inset 0 0 2px 2px var(--neonborder), inset 0 0 12px 3px var(--neon); content:''; left:0; position:absolute; right:0; top:0; } .ogl_shipIcon { background-color:rgba(255,255,255,.1); background-position:center; background-size:cover !important; border:2px solid var(--p2); border-radius:4px; /*box-shadow:inset 0 0 0 2px rgba(0,0,0,.3);*/ box-sizing:border-box; height:40px; width:40px; } .ogl_shipIcon.ogl_0 { background:var(--red); } .ogl_shipIcon.ogl_0.ogl_active { background:var(--green); } .ogl_shipIcon.ogl_202 { background-image:url(https://gf2.geo.gfsrv.net/cdnd9/60555c3c87b9eb3b5ddf76780b5712.jpg); } .ogl_shipIcon.ogl_203 { background-image:url(https://gf1.geo.gfsrv.net/cdn34/fdbcc505474e3e108d10a3ed4a19f4.jpg); } .ogl_shipIcon.ogl_204 { background-image:url(https://gf2.geo.gfsrv.net/cdnd2/9ed5c1b6aea28fa51f84cdb8cb1e7e.jpg); } .ogl_shipIcon.ogl_205 { background-image:url(https://gf1.geo.gfsrv.net/cdnf1/8266a2cbae5ad630c5fedbdf270f3e.jpg); } .ogl_shipIcon.ogl_206 { background-image:url(https://gf2.geo.gfsrv.net/cdn45/b7ee4f9d556a0f39dae8d2133e05b7.jpg); } .ogl_shipIcon.ogl_207 { background-image:url(https://gf1.geo.gfsrv.net/cdn32/3f4a081f4d15662bed33473db53d5b.jpg); } .ogl_shipIcon.ogl_208 { background-image:url(https://gf1.geo.gfsrv.net/cdn6f/41a21e4253d2231f8937ddef1ba43e.jpg); } .ogl_shipIcon.ogl_209 { background-image:url(https://gf1.geo.gfsrv.net/cdn07/6246eb3d7fa67414f6b818fa79dd9b.jpg); } .ogl_shipIcon.ogl_210 { background-image:url(https://gf3.geo.gfsrv.net/cdnb5/347821e80cafc52aec04f27c3a2a4d.jpg); } .ogl_shipIcon.ogl_211 { background-image:url(https://gf1.geo.gfsrv.net/cdnca/4d55a520aed09d0c43e7b962f33e27.jpg); } .ogl_shipIcon.ogl_213 { background-image:url(https://gf3.geo.gfsrv.net/cdn2a/c2b9fedc9c93ef22f2739c49fbac52.jpg); } .ogl_shipIcon.ogl_214 { background-image:url(https://gf3.geo.gfsrv.net/cdn84/155e9e24fc1d34ed4660de8d428f45.jpg); } .ogl_shipIcon.ogl_215 { background-image:url(https://gf3.geo.gfsrv.net/cdn5a/24f511ec14a71e2d83fd750aa0dee2.jpg); } .ogl_shipIcon.ogl_218 { background-image:url(https://gf1.geo.gfsrv.net/cdn39/12d016c8bb0d71e053b901560c17cc.jpg); } .ogl_shipIcon.ogl_219 { background-image:url(https://gf3.geo.gfsrv.net/cdne2/b8d8d18f2baf674acedb7504c7cc83.jpg); } .ogl_shipIcon.ogl_metal, .ogl_shipIcon.ogl_crystal, .ogl_shipIcon.ogl_deut, .ogl_shipIcon.ogl_dm, .ogl_shipIcon.ogl_energy, .ogl_shipIcon.ogl_food { background-image:url(https://gf3.geo.gfsrv.net/cdned/7f14c18b15064d2604c5476f5d10b3.png) !important; background-size:302px !important; } .ogl_shipIcon.ogl_metal { background-position:-1px -44px !important; } .ogl_shipIcon.ogl_crystal { background-position:-39px -44px !important; } .ogl_shipIcon.ogl_deut { background-position:-76px -44px !important; } .ogl_shipIcon.ogl_dm { background-position:-153px -45px !important; } .ogl_shipIcon.ogl_energy { background-position:-114px -45px !important; } .ogl_shipIcon.ogl_food { background-position:-227px -45px !important; } .ogl_shipIcon[class*="ogl_mission"] { background-image:url(https://gf2.geo.gfsrv.net/cdn14/f45a18b5e55d2d38e7bdc3151b1fee.jpg); background-position:-39px -0; background-size:398px !important; } .ogl_shipIcon.ogl_mission1 { background-position:-292px 0 !important; } .ogl_shipIcon.ogl_mission2 { background-position:-364px 0 !important; } .ogl_shipIcon.ogl_mission3 { background-position:-183px 0 !important; } .ogl_shipIcon.ogl_mission4 { background-position:-111px 0 !important; } .ogl_shipIcon.ogl_mission5 { background-position:-255px 0 !important; } .ogl_shipIcon.ogl_mission6 { background-position:-219px 0 !important; } .ogl_shipIcon.ogl_mission7 { background-position:-75px 0 !important; } .ogl_shipIcon.ogl_mission8 { background-position:-147px 0 !important; } .ogl_shipIcon.ogl_mission9 { background-position:-329px 0 !important; } .ogl_shipIcon.ogl_mission15 { background-position:-2px 0 !important; } .ogl_inFlight, .ogl_inFlight:before, .ogl_inFlight:after { border-style:solid; border-width:3px 6px 3px 0; border-color:transparent #51708f transparent transparent; cursor:pointer; height:0 !important; position:absolute !important; right:auto; top:0 !important; transform:translateX(100%); width:0 !important; } .ogl_inFlight:before, .ogl_inFlight:after { border:inherit; } .ogl_inFlight { top:23px !important; } .ogl_inFlight:before { content:''; right:-6px !important; } .ogl_inFlight:after { bottom:0 !important; content:''; right:-6px !important; top:auto !important; } .ogl_inFlight.ogl_active, .ogl_inFlight.ogl_active:before, .ogl_inFlight.ogl_active:after, { border-color:transparent #fff transparent transparent; } .ogl_inFlight.ogl_warning, .ogl_inFlight.ogl_warning:before, .ogl_inFlight.ogl_warning:after { border-color:transparent var(--yellow) transparent transparent; } .ogl_inFlight.ogl_danger, .ogl_inFlight.ogl_danger:before, .ogl_inFlight.ogl_danger:after { border-color:transparent var(--red) transparent transparent; } .ogl_missionType.ogl_inFlight, .ogl_missionType.ogl_inFlight:before, .ogl_missionType.ogl_inFlight:after { border-color:transparent currentColor transparent transparent !important; } .ogl_inFlight.ogl_warning, .ogl_inFlight.ogl_danger { animation:blink 1s infinite; } .ogl_inFlight[data-mission-type="0"] { display:none; } @keyframes blink { 20% { opacity:1; } 50% { opacity:0; } 100% { opacity:1; } } .ogl_planetFleet { top:8px !important; right:55px !important; } [data-panel="resources"] .ogl_planetFleet { right:94px !important; } .ogl_moonFleet { right:37px !important; transform:rotate(180deg); } [data-panel="resources"] .ogl_moonFleet { right:76px !important; } .tpd-tooltip:not(.ogl_tooltip) { display:none !important; height:0px !important; overflow:hidden !important; pointer-events:none !important; width:0px !important; } .splitLine, .ogl_choseCapacity hr, .ogl_tooltip hr { background:var(--p4) !important; border:none !important; height:2px !important; margin:9px 0 !important; } .premiumHighligt span { color:var(--textpremium) !important; } .ogl_colorPicker { display:grid; grid-template-columns:repeat(2, 1fr); width:auto; } .ogl_colorButton { background:#151515; border:2px solid #1f252b; border-radius:20px; cursor:pointer; height:16px; right:7px; position:absolute; top:7px; transition:all .2s; user-select:none; width:25px; } .ogl_colorButton:hover { border-color:#263640; filter:brightness(1.2); } .ogl_colorPicker > div { border-radius:20px; box-shadow:inset 0 0 0 3px rgba(0,0,0,.3); cursor:pointer; filter:brightness(.9); height:20px; margin:2px; position:relative; transition:transform .2s, filter .2s; width:30px; } .ogl_colorPicker > div:hover { filter:brightness(1.3); transform:scale(1.2); z-index:2; } .ogl_colorPicker > div[data-color="none"]:before { content:'clear'; display:block; font-family:'material icons'; font-size:10px; height:100%; left:0; line-height:20px; position:absolute; text-align:center; top:0; width:100%; } [data-color="red"], [data-color="red"] .ogl_colorButton, [data-toggle="red"] { background:var(--red) !important; } [data-color="yellow"], [data-color="yellow"] .ogl_colorButton, [data-toggle="yellow"] { background:var(--yellow) !important; } [data-color="green"], [data-color="green"] .ogl_colorButton, [data-toggle="green"] { background:var(--green) !important; } [data-color="blue"], [data-color="blue"] .ogl_colorButton, [data-toggle="blue"] { background:var(--blue) !important; } [data-color="violet"], [data-color="violet"] .ogl_colorButton, [data-toggle="violet"] { background:var(--violet) !important; } [data-color="gray"] { opacity:.2 !important; } [data-color="gray"] .ogl_colorButton, [data-toggle="gray"] { background:var(--white) !important; } .ogl_colorPicker [data-color="gray"] { background:var(--white) !important;opacity:1 !important; } .galaxyTable .ctContentRow [data-color="gray"] { background:#0d1014;opacity:1 !important; } .galaxyTable .ctContentRow [data-color="gray"]:before { background:#0d1014; } .galaxyTable .ctContentRow [data-color="gray"] > div { opacity:.2 !important; } [data-color="halfred"], [data-color="halfred"] .ogl_colorButton, [data-toggle="halfred"] { background:repeating-linear-gradient(-45deg, var(--red), var(--red) 5px, #942424 5px, #942424 10px) !important; } [data-color="halfyellow"], [data-color="halfyellow"] .ogl_colorButton, [data-toggle="halfyellow"] { background:repeating-linear-gradient(-45deg, var(--yellow), var(--yellow) 5px, #947931 5px, #947931 10px) !important; } [data-color="halfgreen"], [data-color="halfgreen"] .ogl_colorButton, [data-toggle="halfgreen"] { background:repeating-linear-gradient(-45deg, var(--green), var(--green) 5px, #2b8055 5px, #2b8055 10px) !important; } [data-color="halfblue"], [data-color="halfblue"] .ogl_colorButton, [data-toggle="halfblue"] { background:repeating-linear-gradient(-45deg, var(--blue), var(--blue) 5px, #314a8c 5px, #314a8c 10px) !important; } [data-color="halfviolet"], [data-color="halfviolet"] .ogl_colorButton, [data-toggle="halfviolet"] { background:repeating-linear-gradient(-45deg, var(--violet), var(--violet) 5px, #5c2e6b 5px, #5c2e6b 10px) !important; } .ogl_timeZone.ogl_fulldate:before { content:attr(data-datezone); position:relative; left:-5px; } .ogl_timeZone:after { color:hsl(187deg 72% 71%); content:attr(data-timezone); } .ogl_timeZone:before, .ogl_timeZone:after { display:inline-block; font-size:11px !important; line-height:1; } .ogl_endTime { font-size:10px; font-weight:bold; margin-top:8px; text-align:center; } .ogl_endTime, .ogl_fulldate { color:var(--textdate) !important; } .ogl_fulldate.ogl_danger, .ogl_fulldate.ogl_danger.ogl_timeZone:after { color:var(--red) !important; } .ogl_endTime span, .ogl_fulldate span { color:var(--texttime) !important; } .ogl_ping { color:#aaa; font-size:10px; font-weight:bold; position:absolute; right:-14px; top:14px; } .ogl_danger { color:var(--red); } .ogl_warning { color:var(--orange0); } .ogl_caution { color:var(--yellow); } .ogl_ok { color:var(--green); } .ogl_none { color:#41515e; } #siteFooter .material-icons { font-size:14px !important; vertical-align:middle; } #darkmatter_box img { display:none; } #chatMsgList .msg_date { position:relative; top:6px; } .chat_msg .msg_date { position:relative; top:3px; } .chat_msg .ogl_timeZone:before, .chat_msg .ogl_timeZone:after { font-size:9px !important; } #planetbarcomponent #rechts #myPlanets .smallplanet a.alert { bottom:17px !important; left:3px !important; position:absolute !important; top:auto !important; z-index:3 !important; } #planetbarcomponent #rechts #myPlanets .smallplanet a.constructionIcon, #planetbarcomponent #rechts #cutty a.constructionIcon, #planetbarcomponent #rechts #norm a.constructionIcon { bottom:3px !important; left:3px !important; position:absolute !important; top:auto !important; z-index:3 !important; } #planetbarcomponent #rechts #myPlanets .smallplanet a.constructionIcon.moon, #planetbarcomponent #rechts #cutty a.constructionIcon.moon, #planetbarcomponent #rechts #norm a.constructionIcon.moon { left:134px !important; } #planetbarcomponent #rechts #myPlanets[data-panel="resources"] .smallplanet a.constructionIcon.moon, #planetbarcomponent #rechts #cutty[data-panel="resources"] a.constructionIcon.moon, #planetbarcomponent #rechts [data-panel="resources"] a.constructionIcon.moon { left:96px !important; } .smallplanet a.wreckFieldIcon { left:-4px !important; top:14px !important; z-index:2; } [data-multi]::before { border:2px solid #4f8290; border-radius:10px; border-right:0; bottom:-3px; content:''; display:block; height:100%; left:-3px; position:absolute; transform:translateY(-50%); width:3px; z-index:2; } [data-multi="0"]::before { border-color:#00bcd4; } [data-multi="1"]::before { border-color:#ffeb3b; } [data-multi="2"]::before { border-color:#009688; } [data-multi="3"]::before { border-color:#673ab7; } [data-multi="4"]::before { border-color:#3f51b5; } [data-multi="5"]::before { border-color:#ff5722; } [data-multi="6"]::before { border-color:#9c27b0; } [data-multi="7"]::before { border-color:#ff9800; } [data-multi="8"]::before { border-color:#4caf50; } [data-multi="9"]::before { border-color:#e91e63; } [data-multi="10"]::before { border-color:#ffc107; } .btn_blue { padding:2px 10px !important; } .ogl_button, .btn_blue, #fleet1 .secondcol > * { background:linear-gradient(0deg, #151c22, #232f40) !important; border:2px solid var(--p1) !important; border-radius:4px !important; box-shadow:inset 0 2px #283546 !important; box-sizing:border-box !important; color:#495c72 !important; cursor:pointer !important; font-weight:bold !important; line-height:20px !important; position:relative; text-align:center !important; text-decoration:none !important; text-shadow:-1px 2px var(--p2) !important; user-select:none !important; } .ogl_button:hover, .btn_blue:hover { filter:brightness(1.3) !important; } .ogl_button { line-height:24px !important; } .ogl_button .material-icons { font-size:18px !important; vertical-align:middle; } .ogl_button.ogl_disabled { opacity:.7; pointer-events:none; } .btn_blue[disabled] { background:hsl(0deg 0% 33%) !important; color:hsl(0deg 0% 71%) !important; filter:grayscale(1); } #galaxyHeader .btn_blue { height:18px !important; line-height:14px !important; max-width:94px; min-width:20px !important; overflow:hidden; padding:0 2px !important; text-overflow:ellipsis; white-space:nowrap; } /* JUMPGATE ----------------------------*/ #jumpgateForm .ship_selection_table > tbody { background:var(--p1); } #jumpgateForm .ship_selection_table .ship_txt_row { padding:0 5px !important; } #jumpgateForm .ship_selection_table .ship_txt_row p { padding-bottom:18px; } #jumpgateForm .ship_input_row { box-sizing:border-box; } #jumpgateForm input { border-radius:3px !important; margin-left:3px !important; padding:0 5px !important; width:64px !important; } #jumpgateForm .ogl_delta { background:var(--p3) !important; border-radius:2px; bottom:3px; box-shadow:inset 0 9px var(--p4), 0 0 0 2px var(--p0); color:var(--textcyan) !important; cursor:pointer; font-size:16px; height:18px; left:40px; line-height:18px; position:absolute; text-align:center; text-decoration:none; width:40px; } #jumpgateForm .ogl_delta:hover { box-shadow:inset 0 0 1px 2px var(--neonborder), inset 0 0 12px 3px var(--neon);; color:#fff !important; } /* LEFT MENU ----------------------------*/ .ogl_universeName { color:#aeaac1; font-size:12px; font-weight:bold; line-height:12px; pointer-events:none; position:absolute; text-align:right; top:92px; width:138px; } .ogl_universeName div { color:var(--textsand); font-size:11px; } .ogl_planetsCount { color:var(--gray2); } .ogl_planetsCount .material-icons { display:inline-block; font-size:15px !important; margin-left:3px; vertical-align:sub; } #tutorialiconcomponent #helper a { transform:scale(.75); } #links .menubutton { filter:hue-rotate(-7deg); position:relative; } #links .menubutton span { color:hsl(208deg 27% 58%); position:relative; } #links .menubutton.selected span, #links .menubutton:hover span { color:hsl(194deg 66% 93%); } #links .menubutton[data-oglupdate="true"] span { color:#ff9109 !important; } #links .menubutton.ogl_active span { color:#97dfb0 !important; text-shadow:0 0 11px #000 !important; } #links .menubutton.ogl_active:after { background:hsl(180deg, 100%, 50%, 15%); border-radius:3px; bottom:5px; box-shadow:inset 0 0 5px 0px hsl(155deg, 100%, 75%, 40%); content:''; display:block; left:6px; position:absolute; right:7px; top:3px; } .ogl_stats { background:var(--p2); border-radius:var(--uiradius); box-shadow:0 0 0 2px #0a0f14; box-sizing:border-box; font-weight:bold; margin:12px 0; padding:8px; position:relative; text-shadow:1px 1px #000; width:132px; } .ogl_stats .ogl_button { font-size:18px !important; height:29px; line-height:29px; padding:0; position:absolute; right:-4px; top:-2px; transform:translateX(100%); width:29px; } .ogl_stats .ogl_button:nth-of-type(2) { top:29px; } .ogl_stats .ogl_button:nth-of-type(3) { top:60px; } .ogl_statsDetails h3, .ogl_statsItem { background:#1c2736; white-space:nowrap; } .ogl_statsDetails { user-select:none; } .ogl_statsDetails h3 { /*border:2px solid hsl(210deg 26% 24%);*/ border-radius:4px; color:var(--textblue); font-size:11px; font-weight:bold; line-height:25px; overflow:hidden; padding:0 10px; text-overflow:ellipsis; text-transform:uppercase; } .ogl_statsDetails h3 u { color:#fff; text-decoration:none; } .ogl_statsDetails h3 u:hover { text-decoration:underline; } .ogl_statsDetails > div:last-child { display:flex; flex-direction:column; justify-content:space-between; } .ogl_statsRecap { display:grid; grid-gap:14px; grid-template-columns:160px 120px 120px 120px 120px; margin-top:20px; } .ogl_statsRecap > div:first-child { color:var(--textblue); } .ogl_statsRecap > div { background:#1c2736 !important; /*border:2px solid #0e151c;*/ border-radius:4px; font-size:14px; font-weight:bold; line-height:36px; padding:2px 9px; position:relative; text-align:center; text-shadow:-1px -1px 0 rgba(0,0,0,.3); } .ogl_statsRecap > div:nth-child(1) { background:linear-gradient(230deg, #619fdf, #3c2d4e); } .ogl_statsRecap > div:nth-child(2) { background:linear-gradient(230deg, #3f9dfd, #274189); } .ogl_statsRecap > div:nth-child(3) { background:linear-gradient(230deg, #2ead84, #194056); } .ogl_statsRecap > div:nth-child(4) { background:linear-gradient(230deg, #935fe7, #3b2a46); } .ogl_statsRecap > div div { background:#2c3b50; border-radius:10px; color:#f76363 !important; font-size:10px; line-height:10px; padding:3px 6px; position:absolute; right:-1px; top:-3px; } .ogl_statsTables { display:grid; } .ogl_statsColumn { border-radius:8px; display:block; font-size:11px; } .ogl_statsColumn > div { display:grid; grid-gap:3px 14px; grid-template-columns:160px 120px 120px 120px 120px; } .ogl_statsColumn > div:not(:last-child) { margin-bottom:3px; } .ogl_shipsArea { display:grid; grid-gap:5px; grid-template-columns:repeat(5, 1fr); margin-bottom:20px; } .ogl_statsItem { /*border:2px solid hsl(210deg 26% 24%);*/ border-radius:4px; display:grid; font-weight:bold; grid-template-columns:40px auto; line-height:25px; padding:0 8px 0 2px; text-align:right; } .ogl_statsItem.ogl_newLine { grid-row:6; } .ogl_statsItem div { text-indent:4px; } .ogl_dateArea > div:nth-child(1) { display:grid; grid-gap:4px; grid-template-columns:repeat(5, 1fr); margin-bottom:5px; } .ogl_dateArea > div:nth-child(2) { background:#1c2736; border-radius:6px; display:grid; grid-gap:4px; grid-template-columns:repeat(16, 1fr); margin:20px 0; overflow:hidden; padding:10px; } .ogl_dateArea > div:nth-child(1) > div { background:#1c2736; border-radius:14px; color:var(--textblue); cursor:pointer; font-weight:bold; line-height:30px; text-align:center; } .ogl_dateArea > div:nth-child(1) > div:hover { filter:brightness(1.3); } .ogl_dateArea > div > div.ogl_active { color:#b3934b !important; } .ogl_dateArea .ogl_button { line-height:21px !important; } .ogl_dateArea .ogl_calendarIcon { color:#6e8eaf; font-size:22px !important; line-height:24px !important; opacity:.3; text-align:center; } .ogl_statsDetails .ogl_calendar { color:var(--textsand); overflow:hidden; max-width:400px; user-select:none; } .ogl_statsDetails .ogl_calendar > div { display:grid; grid-gap:4px 0; grid-template-columns:repeat(7, 1fr); } .ogl_dateArea > div:nth-child(2) > div { background:#222f40 !important; border:none !important; border-radius:14px !important; box-shadow:none !important; text-shadow:none !important; } .ogl_dateArea > div:nth-child(2) > div.ogl_disabled { background:none !important; opacity:.3; pointer-events:none; } .ogl_statsDetails .ogl_calendar .month { display:inline-block; font-weight:bold; } .ogl_statsDetails .ogl_calendar .cell { color:#fff; line-height:26px; position:relative; text-align:center; width:35px; } .ogl_statsDetails .ogl_calendar .day { color:var(--textblue); font-size:10px; font-weight:bold; line-height:25px; } .ogl_statsDetails .ogl_calendar .ogl_beforeDate { background: linear-gradient(90deg, transparent 60%, var(--textsand)); } .ogl_statsDetails .ogl_calendar .ogl_firstDate { border-bottom-left-radius:8px; border-top-left-radius:8px; } .ogl_statsDetails .ogl_calendar .ogl_lastDate { border-bottom-right-radius:8px; border-top-right-radius:8px; } .ogl_statsDetails .ogl_calendar .cell:not(.day):not(.empty) { cursor:pointer; } .ogl_statsDetails .ogl_calendar .cell:not(.day):not(.empty):hover { background:var(--p5); color:#fff; } .ogl_statsDetails .ogl_calendar .ogl_disabled { opacity:.2; pointer-events:none; } .ogl_statsDetails .ogl_calendar .ogl_active { background:var(--textsand); color:var(--p1); font-weight:bold; } .ogl_statsDetails .ogl_shipIcon { height:21px; margin:auto; } .ogl_statsDetails .ogl_statsArea { background:var(--p2); border-radius:0 0 var(--uiradius) var(--uiradius); padding:10px; position:relative; } /*.ogl_statsDetails .ogl_statsArea:last-child:before, .ogl_statsDetails .ogl_statsArea:last-child:after { background:var(--p2); border-radius:0 5px 5px 0; bottom:41px; color:var(--textsand); content:'ø / day'; line-height:21px; padding:0 10px; position:absolute; left:0; transform:translateX(-100%); } .ogl_statsDetails .ogl_statsArea:last-child:after { bottom:10px; content:'ø / day + prod'; }*/ .ogl_statsDetails .ogl_statsArea > h3 { color:hsl(208deg 23% 33%); font-size:11px; font-weight:bold; padding:20px 0 14px 0; text-align:center; } .ogl_statsDetails .ogl_statsArea > div { display:grid; grid-gap:5px; grid-template-columns:repeat(4, 1fr); position:relative; z-index:1; } .ogl_statsDetails .ogl_statsArea > div > div { background:#0e141a; border:2px solid #151f28; border-radius:8px; display:grid; justify-content:center; padding:2px 4px; text-align:center; } .ogl_statsDetails .ogl_statsArea > div > div > div:not(.ogl_shipIcon) { font-size:11px; } .ogl_statsDetails .ogl_statsArea .ogl_newLine { grid-row:5; } .ogl_dateFilters { bottom:0; display:grid; grid-auto-flow:column; left:0; line-height:26px; position:absolute; user-select:none; width:100%; } .ogl_dateFilters > div.material-icons { color:var(--textblue); pointer-events:none; text-decoration:none; } .ogl_dateFilters > div { cursor:pointer; text-align:center; text-decoration:underline; } .ogl_dateFilters > div:hover, .ogl_dateFilters > div.ogl_active { color:var(--textsand); } .ogl_dateFilters > div.ogl_active { pointer-events:none; } .ogl_labelLimit { background:hsl(210deg 27% 18%); border-radius:2px; box-shadow:0 3px 5px rgba(0,0,0,.8); display:block !important; font-weight:bold; left:-6px; padding:3px 5px; position:absolute; text-shadow:none; top:-10px; z-index:2; } .ogl_labelLimit.tooltipRight { cursor:pointer; } .ogl_stats .ogl_date { color:#4f5b73; display:block; font-size:10px; margin-top:5px; text-align:right; } .ogl_stats h2 { margin-bottom:10px; text-align:center; } .ogl_stats .ogl_0 { background:#252d3e; font-size:22px !important; text-align:center; } .ogl_stats .ogl_0:before { color:#fff; content:'functions'; } .ogl_stats > div { color:#a9bbda; display:grid; font-size:10px; grid-template-columns:40px auto; } .ogl_stats .ogl_shipIcon, .ogl_sideView .ogl_shipIcon { background-position:center; border:none; border-radius:0; border-right:1px solid #0d1013; height:18px !important; width:37px !important; } .ogl_stats .number { color:var(--yellow); font-size:11px; line-height:17px; padding:0 5px; text-align:right; } /* DETAILS ----------------------------*/ #technologydetails .ogl_detailAction { display:grid; grid-gap:2px; grid-template-columns:repeat(4, 1fr); left:3px; position:absolute; right:3px; top:3px; } #shipyard .ogl_detailAction, #defense .ogl_detailAction { grid-template-columns:repeat(1, 1fr); } #technologydetails .costs li.ogl_noMoney { color:var(--red); } #technologydetails .costs li.ogl_active { color:var(--green); } #technologydetails > .sprite_large:before { background:rgba(92,142,214,.4); box-shadow:inset 0 0 56px #000, inset 0 0 0 1px #000; content:''; height:100%; left:0; left:0; position:absolute; top:0; width:100%; } #technologydetails .technology_tree { border-radius:0 5px 0 0; } #technologydetails .ogl_button { color:var(--textcyan); font-size:18px !important; height:30px; line-height:26px !important; width:100%; } #technologydetails .ogl_detailActions { display:grid; grid-gap:4px; grid-template-columns:repeat(4, 1fr); padding:4px; } .ogl_lockBuild.ogl_disabled { opacity:.5; } .ogl_lockBuild.ogl_active, .ogl_lockBuild.ogl_active:hover { color:var(--textpremium) !important; } #technologydetails h3 { background:none !important; color:var(--textblue) !important; font-size:16px !important; text-indent:7px !important; top:3px !important; } #technologydetails h3::before { display:none !important; } #technologydetails > .description { background:var(--p1); box-shadow:0 -2px var(--p0); } #technologydetails .content { background:linear-gradient(to bottom, var(--p2), var(--p3)); height:203px !important; left:203px !important; } #technologydetails .level, #technologydetails .amount { color:#606f8c !important; font-size:12px !important; font-weight:bold !important; left:7px !important; top:25px !important; } #technologydetails .level i { font-size:20px !important; vertical-align:bottom; } #technologydetails .level span { color:var(--textpremium); font-size:16px; vertical-align:bottom; } #technologydetails .build_duration strong { display:none; } #technologydetails .build_duration { bottom:23px; margin:0 !important; padding-left:24px; position:absolute; top:auto; } #technologydetails .build_duration:before { color:var(--textpremium); content:'hourglass_top'; font-family:'material icons'; font-size:21px; left:0; position:absolute; top:8px; } #technologydetails .build_duration .ogl_timeZone { font-weight:bold; left:29px; position:absolute; width:230px; } #technologydetails .build_duration .bonus { display:none; } #technologydetails .possible_build_start { bottom:55px; margin:0; position:absolute; right:10px; top:auto; } #technologydetails .additional_energy_consumption, #technologydetails .energy_production { bottom:81px; margin:0 !important; padding-left:24px; position:absolute; right:10px; } #technologydetails .research_laboratory_levels_sum { bottom:81px; margin:0 !important; padding-left:24px; position:absolute; right:10px; } #technologydetails .research_laboratory_levels_sum:before { color:var(--textpremium); content:'science'; font-family:'material icons'; font-size:21px; left:0; position:absolute; top:1px; } #technologydetails .additional_energy_consumption:before, #technologydetails .energy_production:before { color:var(--textpremium); content:'flash_on'; font-family:'material icons'; font-size:21px; left:0; position:absolute; top:1px; } #technologydetails .information .ogl_endTime { display:block; margin:0; } #technologydetails .costs { font-size:12px !important; font-weight:bold !important; top:59px !important; } #technologydetails .resource.icon { display:block !important; height:21px !important; line-height:21px !important; margin:0 !important; width:fit-content !important; width:-moz-fit-content !important; } #technologydetails .resource.icon::before { display:inline-block !important; image-rendering:-webkit-optimize-contrast !important; margin:0 5px 0 -24px !important; transform:scale(0.5) !important; transform-origin:top right !important; vertical-align:text-top !important; } #technologydetails .costs p { display:none; } #technologydetails .bonus { color:var(--green1) !important; } /* RIGHT MENU ----------------------------*/ #commandercomponent { margin-right:9px; } #planetList { background:var(--p2); border-radius:var(--uiradius) var(--uiradius) 0 0; box-shadow:0 0 0 2px #0a0f14; box-sizing:border-box; margin-top:5px; padding:5px; width:162px !important; } .smallplanet { border-radius:0 !important; display:grid; grid-column-gap:20px; grid-template-columns:auto 36px; height:auto !important; font-size:10px; margin:0 0 3px 0!important; position:relative !important; width:100% !important; } .smallplanet * { box-sizing:border-box; font-size:inherit !important; font-weight:normal !important; } .smallplanet img { background:#284563; border-radius:50% !important; box-shadow:0 0 0 1px #000 !important; height:14px; left:3px !important; margin:0 !important; position:absolute !important; top:12px !important; transition:transform .3s; width:14px; z-index:2; } .smallplanet .planetlink img { top:10px !important; height:18px; width:18px; } .planetlink, .moonlink { background:linear-gradient(225deg, transparent, #212b39); background-position:0 !important; border:none !important; border-radius:5px; height:36px !important; overflow:hidden; position:relative !important; transition:box-shadow .3s; z-index:1; } .planetlink *, .moonlink * { pointer-events:none; } .planetlink { background:linear-gradient(155deg, transparent, #212b39); } .planetlink:hover, .smallplanet .planetlink.active { background:linear-gradient(155deg, transparent, #384883); } .moonlink:hover, .smallplanet .moonlink.active { background:linear-gradient(225deg, transparent, #384883); } .smallplanet .planetlink { left:0 !important; text-align:left; top:0 !important; } .smallplanet .moonlink { bottom:0 !important; left:0 !important; text-align:left; top:auto !important; } .smallplanet .planet-name, .smallplanet .planet-koords { left:26px !important; position:absolute !important; } .smallplanet .planet-koords { color:hsl(208deg 3% 57%) !important; letter-spacing:-0.05em; top:18px !important; } .smallplanet .planet-name { color:hsl(208deg 32% 63%) !important; font-weight:bold !important; max-width:89px; overflow:hidden; text-overflow:ellipsis; top:5px !important; } .ogl_linkedHarvest { height:0; margin-bottom:0; transform:scale(0) translateY(-60px); transition:transform .2s, height .2s, margin .2s; width:100%; } .ogl_linkedHarvest.ogl_active { font-size:10px !important; height:25px; margin-top:5px; margin-bottom:5px; transform:scale(1) translateY(0); } .smallplanet .ogl_shortcut { bottom:3px; color:var(--textsand); font-size:16px !important; right:1px; pointer-events:none; position:absolute; transform:scale(0); transition:transform .2s; z-index:3; } .ogl_shortcuts .ogl_shortcut { transform:scale(1); } .ogl_shortcuts .smallplanet .ogl_timer { display:none; } .ogl_shortcuts .smallplanet a { cursor:crosshair; } .ogl_shortcuts[data-panel="resources"] img { transform:translatex(-25px); } .ogl_shortcuts .ogl_stock { transform:translatex(-16px); } div#banner_skyscraper { transform:translateX(55px) !important; } #bannerSkyscrapercomponent { margin-left:180px !important; } #pageContent { display:grid; grid-gap:0 12px; grid-template-columns:150px 670px 180px; width:1030px !important; } #top, #box, #mainContent { background-repeat:no-repeat; grid-column:1 / -1; } #rechts { margin:-55px 0 0 0 !important; } #right #top, #info, #box, #mainContent, #rechts, #cutty, #myPlanets, #countColonies, #planetList, .ogl_resourcesSum, .ogl_keyList { width:100% !important; } #planetbarcomponent { width:180px !important; } #countColonies { background:var(--p2) !important; border-radius:var(--uiradius); box-shadow:0 0 0 2px #0a0f14; color:transparent !important; font-size:10px; height:58px !important; line-height:20px !important; margin:0 !important; user-select:none; } #countColonies p { display:none; } #netz #tabs { padding:6px 16px 0 14px; } #netz #alliance ul#tab-ally { display:grid; grid-template-columns:repeat(5, 1fr); } #alliance #inhalt .tabsbelow li { font-size:11px; } .ogl_menuOptions { display:grid; font-size:16px; grid-gap:2px; grid-template-columns:repeat(4, 1fr); margin-top:3px; overflow:hidden; padding:5px; } .ogl_menuOptions .ogl_manageData { color:#c54f4f !important; } .ogl_menuOptions .ogl_harvest { color:#50deec !important; } .ogl_menuOptions .ogl_shipPicker { color:#e4b633 !important;font-size:11px;font-weight:bold; } .ogl_menuOptions .ogl_missionPicker3 { color:#c2f75a !important; } .ogl_menuOptions .ogl_missionPicker4 { color:#43ec77 !important; } .ogl_menuOptions .ogl_button { line-height:22px !important; } .ogl_menuOptions .ogl_button.ogl_active, .ogl_shortcuts .ogl_menuOptions .ogl_harvest.ogl_active { border-color:var(--neonborder) !important; box-shadow:inset 0 10px hsl(0deg 0% 100% / 7%), 0 0 5px 0px var(--neon) !important; } .ogl_panel { bottom:4px; box-sizing:border-box; display:grid; font-size:12px; grid-gap:2px; grid-template-columns:repeat(4, 1fr); padding:0 5px; position:absolute; right:0; text-align:center; width:100%; } .ogl_panel > div { cursor:pointer; height:20px; line-height:16px !important; } [data-panel="resources"] .planet-name, [data-panel="resources"] .planet-koords, [data-panel="resources"] .ogl_timer, [data-panel="resources"] .ogl_jumpGateTimer { opacity:0 !important; pointer-events:none; } [data-panel="resources"] .smallplanet { grid-template-columns:repeat(2, 1fr); } [data-panel="resources"] .ogl_stock { display:grid; } .ogl_stock { display:none; grid-template-rows:repeat(3, 1fr); line-height:10px; pointer-events:none; position:absolute; right:5px; text-align:right; top:4px; transition:transform .3s; } .ogl_stock > * { font-size:9px !important; font-weight:bold !important; } .ogl_stock > .ogl_full { color:var(--red) !important; } .ogl_prod { grid-template-columns:repeat(4, 1fr) !important; } .ogl_mines { font-weight:bold; } .ogl_sideLock { bottom:0; color:var(--yellow1); cursor:pointer; font-size:16px !important; position:absolute; right:-20px; } .ogl_sideLock:hover { color:#fff; } .planetlink .ogl_timer, .moonlink .ogl_timer { bottom:3px; color:var(--red0) !important; content:''; font-size:11px !important; font-weight:bold !important; position:absolute; right:4px; } .ogl_timer[data-timer]:before { content:attr(data-timer); } .planetlink .ogl_timer.ogl_medium, .moonlink .ogl_timer.ogl_medium, .ogl_medium { color:var(--yellow0) !important; } .planetlink .ogl_timer.ogl_short, .moonlink .ogl_timer.ogl_short, .ogl_short { color:var(--green0) !important; } .ogl_resourcesSum { background:var(--p2); border-radius:0 0 var(--uiradius) var(--uiradius); box-shadow:0 0 0 2px #0a0f14; box-sizing:border-box; display:grid; font-size:11px; font-weight:bold; grid-template-columns:auto 52px; line-height:15px; padding:8px; position:relative; text-align:right; text-shadow:1px 1px #000; user-select:none; width:146px; } .ogl_resourcesSum .ogl_loader { border-width:3px; height:15px; margin:0 0 -4px 3px; width:15px; } .ogl_resourcesSum > *, .ogl_resourcesSum .ogl_sub { opacity:1; transition:transform .1s; } .ogl_resourcesSum.ogl_active > *, .ogl_resourcesSum.ogl_active .ogl_sub { opacity:0; transform:translateX(30px); } .ogl_resourcesSum:after { color:#98bfcd; content:'chevron_right'; cursor:pointer; font-family:"material icons"; font-size:24px; position:absolute; right:-22px; top:50%; transform:translateY(-50%); } .ogl_resourcesSum .ogl_shipIcon { height:20px; } .ogl_resourcesSum i { color:hsl(210deg 21% 29%); font-size:22px !important; left:4px; position:absolute; bottom:10px; } .ogl_resourcesSum .ogl_sub { display:inline-block; font-size:9px !important; margin-left:4px; opacity:.7; } .ogl_planetCount .material-icons { font-size:12px !important; margin-right:5px; vertical-align:bottom; } .ogl_resourcesSum .splitLine { margin:4px 0 !important; } .ogl_keyList { background:var(--p2); border-radius:var(--uiradius); box-shadow:0 0 0 2px #0a0f14; box-sizing:border-box; display:grid; grid-gap:5px; grid-template-columns:repeat(3, 1fr); font-size:11px; font-weight:bold; margin-bottom:40px; margin-top:7px; padding:4px; position:relative; width:162px; } .ogl_key { background:linear-gradient(to top left, var(--p3) 45%, var(--p1)); background-position:0 !important; border:none !important; border-radius:3px; box-shadow:inset 0 1px rgba(255, 255, 255, .07), 0 0 0 2px var(--p1); box-sizing:border-box; border-radius:5px; color:#7790c1; cursor:pointer; font-size:10px; font-weight:bold; line-height:24px !important; text-align:center; width:100%; } .ogl_key:hover { background:linear-gradient(to top left, var(--p5) 45%, var(--p3)); color:#fff; } .ogl_planetCount { color:var(--p6); } /* TOOLTIP ----------------------------*/ .ogl_tooltip { background:var(--p3); border-image:var(--uigradient) 1; border-style:solid; border-width:2px 0 0 0; box-sizing:border-box !important; display:block; font-size:11px; height:auto; max-height:600px !important; max-width:440px; min-width:20px; opacity:0; overflow:initial !important; padding:12px 16px; pointer-events:none; position:absolute; transform-style:preserve-3d; width:auto; z-index:1000000; } .ogl_tooltip.ogl_active { /*animation:show .15s;*/ opacity:1; pointer-events:auto; } @keyframes show { 0% { opacity:0; } 50% { opacity:0; } 100% { opacity:1; } } .ogl_close { background:var(--p2); border:5px solid var(--p5); border-radius:30px; color:#bbb; cursor:pointer; font-size:16px !important; padding:2px; position:absolute; right:-10px; top:-10px; user-select:none; z-index:3; } .ogl_tooltip .ogl_close { right:-14px; top:-14px; } .ogl_close:hover { color:#fff; } .ogl_tooltip .ogl_value { color:var(--textpremium); font-size:10px; font-weight:bold; } .ogl_tooltip:before { background:rgba(0, 0, 0, .8); bottom:-10px; content:''; display:block; filter:blur(10px); left:-10px; pointer-events:none; position:absolute; right:-10px; top:-10px; transform:translateZ(-1px); z-index:-1; } .ogl_tooltip:after { background:var(--p3); bottom:-5px; box-shadow:0 0 10px #000; content:''; display:block; height:12px; left:50%; pointer-events:none; position:absolute; transform:translateX(-50%) rotate(45deg) translateZ(-1px); width:12px; z-index:-1; } .ogl_tooltip.ogl_left:after { border:none; bottom:auto; left:auto; margin-top:-8px; top:50%; transform:rotate(45deg) translateZ(-1px); right:-5px; } .ogl_tooltip.ogl_right:after { border:none; bottom:auto; left:-5px; transform:rotate(45deg) translateZ(-1px); margin-top:-8px; top:50%; } .ogl_tooltip.ogl_rightTop:after { border:none; bottom:auto; left:-5px; transform:rotate(45deg) translateZ(-1px); bottom:14px; } .ogl_tooltip.ogl_bottom:after { border:none; bottom:auto; left:50%; top:-5px; transform:translateX(-50%) rotate(45deg) translateZ(-1px); } .ogl_tooltip > div > div[style*="display: none"], .ogl_tooltip > div > div[style*="display:none"] { display:block !important; } .ogl_tooltip .galaxyTooltip .ogl_actions { display:grid; font-family:"Material Icons"; grid-gap:5px; grid-template-columns:repeat(5, 1fr); margin:5px 0; } .ogl_tooltip .galaxyTooltip .ogl_actions > * { background:var(--p1); border:2px solid var(--p1); border-radius:3px; box-shadow:inset 0 11px rgba(255,255,255,.04); box-sizing:border-box; color:var(--textcyan); cursor:pointer; font-size:16px !important; line-height:22px !important; text-align:center; text-decoration:none !important; text-shadow:1px 2px var(--p2); width:100% !important; } .ogl_tooltip .galaxyTooltip .ogl_actions > *:hover { background:var(--p1) !important; color:#fff !important; } .ogl_tooltip .ogl_stalkInfo { display:grid; grid-gap:8px; grid-template-columns:auto minmax(min-content, 125px); margin:10px 0 10px 0; } .ogl_tooltip .ogl_stalkActions { display:grid; grid-gap:5px; grid-template-columns:repeat(5, 1fr); } .ogl_tooltip .ogl_stalkActions .ogl_button { font-size:14px !important; margin-bottom:5px; width:100%; } .ogl_stalkPoints { background:var(--p2); border:2px solid var(--p1); border-radius:3px; color:#bdc1c9; display:grid; grid-auto-rows:min-content; grid-column:2; grid-row:1; grid-gap:3px; padding:5px; } .ogl_stalkPoints > div { align-self:end; background:var(--p3); border-radius:0; font-size:10px; font-weight:bold; line-height:18px; grid-template-columns:min-content auto; padding:2px 8px 2px 28px; position:relative; text-align:right; white-space:nowrap; } .ogl_stalkPoints > div i { font-size:16px !important; position:absolute; left:3px; } .ogl_stalkPoints > div:nth-child(1) { color:var(--global); } .ogl_stalkPoints > div:nth-child(2) { color:var(--economy); } .ogl_stalkPoints > div:nth-child(3) { color:var(--techs); } .ogl_stalkPoints > div:nth-child(4) { color:var(--fleet); } .ogl_stalkPoints > div:nth-child(5) { color:var(--def); } .ogl_stalkPoints > div:nth-child(1):before { background-position:0 -3px; } .ogl_stalkPoints > div:nth-child(2):before { background-position:100% -3px; } .ogl_stalkPoints > div:nth-child(3):before { background-position:80% -3px; } .ogl_stalkPoints > div:nth-child(4):before { background-position:60% -3px; } .ogl_stalkPoints > div:nth-child(5):before { background-position:60% -3px; filter:hue-rotate(27deg) brightness(1.75); } .ogl_stalkPoints > div:nth-child(6):before { background-position:60% -3px; filter:hue-rotate(67deg) brightness(1.75); } .ogl_tooltip .ogl_stalk { color:var(--textcyan); } .ogl_tooltip .ogl_stalk .float_right, .ogl_tooltip .ogl_stalk .float_left { font-weight:bold; } .ogl_actionsContainer { display:grid; grid-gap:5px; grid-template-columns:repeat(4, 1fr); margin-top:5px; } .ogl_actionsContainer .material-icons { font-size:18px !important; } .ogl_stalkPlanets [data-multi]:before { height:calc(100% + 2px); } .ogl_stalkPlanets .ogl_mainPlanet { color:var(--textpremium); position:relative; margin-left:2px; z-index:1; } .ogl_tooltip .ogl_stalkPlanets { background:var(--p2); border:2px solid var(--p1); border-radius:5px; box-sizing:border-box; display:grid; grid-auto-rows:min-content; grid-gap:5px; max-height:300px; padding:5px 15px; overflow-x:hidden; overflow-y:auto; overscroll-behavior:none; width:100%; } .ogl_tooltip .ogl_stalkPlanets > div { background:var(--p6); box-shadow: 0 0 5px #000; color:#fff; font-weight:bold; grid-gap:5px; padding:6px 5px 8px 5px; position:relative; width:120px; } .ogl_tooltip .ogl_stalkPlanets > div:after { background:hsl(210deg 27% 15%); content:''; height:25px; left:0; position:absolute; top:0; width:100%; } .ogl_tooltip .ogl_stalkPlanets > div > span { cursor:pointer; position:relative; z-index:1; } .ogl_tooltip .ogl_stalkPlanets > div > span:hover { color:var(--textsand); text-decoration:underline; } .ogl_tooltip .ogl_stalkPlanets .ogl_planetIcon, .ogl_tooltip .ogl_stalkPlanets .ogl_moonIcon { color:var(--textblue); cursor:pointer; font-size:18px !important; position:absolute; right:5px; top:4px; z-index:1; } .ogl_tooltip .ogl_stalkPlanets .ogl_planetIcon { right:25px; } .ogl_tooltip .ogl_stalkPlanets .ogl_moonIcon { opacity:.2; pointer-events:none; } .ogl_tooltip .ogl_stalkPlanets .ogl_moonIcon.ogl_active { opacity:1; pointer-events:auto; } .ogl_tooltip .ogl_stalkPlanets .ogl_planetIcon:hover, .ogl_tooltip .ogl_stalkPlanets .ogl_moonIcon:hover { color:var(--textsand); } .galaxyTooltip.ogl_stalk h1 { margin-bottom:10px !important; } .galaxyTooltip .ListImage { background:var(--p4); border:2px solid var(--p5); border-radius:5px; padding:6px; text-align:center; width:75px; } .galaxyTooltip .ListImage > li > * { margin:auto; } .galaxyTooltip .ListLinks { border-radius:5px; padding:6px; min-width:100px; width:auto !important; } .htmlTooltip h1, .galaxyTooltip h1 { text-align:center; margin-bottom:20px !important; } .htmlTooltip h1 span, .galaxyTooltip h1 span { color:var(--textcyan); font-size:14px; font-weight:bold; } .galaxyTooltip h1 a { font-size:11px; font-weight:bold; } .ogl_ranking { font-size:12px !important; margin-left:5px; } .ogl_ranking, .ogl_ranking a { color:var(--textsand) !important; text-decoration:none !important; } .ogl_ranking:hover, .ogl_ranking:hover a { color:#fff !important; } .ogl_colors { display:grid; grid-gap:2px; grid-template-columns:repeat(12, 1fr); margin:6px 0 14px 0; width:100%; } .ogl_colorAll { margin:10px 0; } .ogl_colorAll .ogl_colors { margin:0; } .ogl_colorAll .ogl_colors > * { border:none; border-radius:65px; } .ogl_colorAll .ogl_colors > *:hover { transform:scale(1.2); } .ogl_colorAll div[data-color="none"] { background:var(--p2); } .ogl_colors > * { border:2px solid var(--p2); border-radius:3px; box-sizing:border-box; cursor:pointer; font-size:10px !important; height:18px; position:relative; transition:all .2s; width:100%; } .ogl_colors > *:hover { filter:brightness(1.2); transform:scale(1.25); z-index:3; } .ogl_colorAll .ogl_colors > * { width:100%; } .ogl_colorAll div[data-color="gray"] { background:var(--white); opacity:1 !important; } .ogl_colorAll div[data-color="none"] { border-color:var(--p5); } .ogl_colorAll div[data-color="none"]:before { border-radius:inherit; content:'clear'; display:block; font-family:'material icons'; font-size:10px; height:100%; left:0; line-height:18px; position:absolute; text-align:center; top:0; width:100%; } .ogl_colorAll.ogl_tooltipColor div[data-color="none"]:before { line-height:20px; } .ogl_tooltipColor .ogl_colors { display:grid; grid-template-columns:repeat(2, 1fr); margin:0 !important; } .ogl_tooltipColor .ogl_colors > * { height:20px !important; width:30px !important; } .ogl_choseCapacityAll { color:var(--textpremium) !important; margin-right:5px; text-transform:none !important; } .ogl_choseCapacity > div { display:grid; grid-template-columns:40px auto; margin-bottom:4px; } .ogl_choseCapacity .ogl_shipIcon { border-color:var(--p6); border-radius:0; border-right:none; color:#ffc729 !important; cursor:pointer; font-size:22px !important; height:26px; text-align:center; text-shadow:0 0 5px #000; } .ogl_choseCapacity .ogl_shipIcon:hover { color:#ffdd61 !important; } .ogl_choseCapacity button, .ogl_resourceToKeep button { color:var(--green1); float:right; font-weight:bold; text-transform:uppercase; } .ogl_choseCapacity h2 { color:var(--textcyan); font-weight:bold; margin-bottom:20px; text-align:center; } .ogl_choseCapacity input { border-radius:0 3px 3px 0 !important; box-shadow:0 0 0 1px #000 !important; height:22px !important; padding:0 5px !important; text-align:right; width:140px !important; } .ogl_tooltip .ogl_metal, .ogl_tooltip .ogl_crystal, .ogl_tooltip .ogl_deut, .ogl_tooltip .ogl_food { display:inline-block; font-size:10px !important; font-weight:bold !important; border-radius:3px; } .ogl_tooltip .ogl_metal .value, .ogl_tooltip .ogl_crystal .value, .ogl_tooltip .ogl_deut .value, .ogl_tooltip .ogl_food .value { font-size:10px !important; font-weight:bold !important; } .ogl_inFlightTable, table.fleetinfo:not(.ogl_ignored) tbody { display:grid; grid-gap:3px; grid-template-columns:repeat(4, 1fr); } .ogl_inFlightTable tr:not(.ogl_full), table.fleetinfo:not(.ogl_ignored) tr { background:var(--p2); border-radius:4px; } .ogl_inFlightTable .value, table.fleetinfo:not(.ogl_ignored) td.value { display:table-cell !important; padding:3px 7px; } .ogl_inFlightTable .ogl_shipIcon, table.fleetinfo .ogl_shipIcon { background-position:center; display:table-cell !important; height:20px !important; width:36px !important; } .ogl_inFlightTable .ogl_full, table.fleetinfo:not(.ogl_ignored) .ogl_full { grid-column:1 / -1; height:7px; padding:0; visibility:hidden; } table.fleetinfo:not(.ogl_ignored) tr.ogl_metal, .ogl_inFlightTable tr.ogl_metal { background:hsl(240deg 14% 18%) !important; } table.fleetinfo:not(.ogl_ignored) tr.ogl_crystal, .ogl_inFlightTable tr.ogl_crystal { background:hsl(205deg 45% 18%) !important; } table.fleetinfo:not(.ogl_ignored) tr.ogl_deut, .ogl_inFlightTable tr.ogl_deut { background:hsl(170deg 32% 18%) !important; } table.fleetinfo:not(.ogl_ignored) tr.ogl_food, .ogl_inFlightTable tr.ogl_food { background:hsl(321deg 23% 16%) !important; } table.fleetinfo .fleetDetailsName { box-sizing:border-box; color:#bba862; justify-self:center; grid-column:1 / 3; max-width:70px; overflow:hidden; padding:0 5px; text-align:center; text-overflow:ellipsis; white-space:nowrap; width:100%; } .ogl_shipData { min-width:120px; } .ogl_shipData h3 { color:var(--textcyan); font-weight:bold; text-align:center; } .ogl_shipData span { color:var(--textsand); float:right; font-weight:bold; } .ogl_economy { border:2px solid var(--p1); border-bottom:0; border-radius:5px; } .ogl_economy .ogl_total { background:var(--p1); padding:10px 12px; } .ogl_economy > div:not(.ogl_total):hover { box-shadow:inset 0 0 12px 3px var(--neon); cursor:pointer; } .ogl_economy .ogl_total .ogl_metal > div, .ogl_economy .ogl_total .ogl_crystal> div, .ogl_economy .ogl_total .ogl_deut > div { display:inline-block; text-align:center; } .ogl_economy .ogl_total b { font-size:16px; } .ogl_economy > div { background:var(--p2); border-bottom:2px solid var(--p1); display:grid; grid-template-columns:auto 120px 120px 120px; font-size:10px; padding:1px 12px 2px 12px; position:relative; text-align:right; } .ogl_economy > div b { display:inline-block; font-size:12px; margin:1px 0; } .ogl_economy > div i { display:inline-block; font-size:10px; position:relative; opacity:.7; text-align:left; text-indent:4px; top:-1px; vertical-align:bottom; width:64px; } .ogl_economy > div h3 { color:#fff; font-size:10px; margin:2px 0; text-align:left; } .ogl_economy > div h3 span { color:#969696; display:inline-block; width:65px; } .ogl_blackHole { border-radius:5px; display:grid; grid-gap:7px 20px; grid-template-columns:repeat(4, 1fr); } .ogl_blackHole > div { display:grid; grid-template-columns:40px 120px; position:relative; } .ogl_blackHole .ogl_shipIcon { background-position:center; border-radius:4px 0 0 4px !important; height:26px; } .ogl_blackHole input { border-radius:0 4px 4px 0 !important; bottom:0; box-shadow:none !important; height:22px !important; line-height:22px !important; top:0; } .ogl_chartArea { align-items:center; background:#1c2736; border:2px solid hsl(208deg 29% 16%); border-radius:6px; display:grid; grid-gap:20px; grid-template-columns:125px auto; margin-bottom:20px; padding:14px; } .ogl_pie { background:rgba(255,255,255,.1); border-radius:50%; display:block; height:110px; position:relative; text-align:center; transform:rotate(-90deg); width:110px; } .ogl_pie:before { background:#1c2736; border-radius:50%; content:''; height:1px; left:50%; padding:25%; position:absolute; top:50%; transform:translate(-50%, -50%); width:1px; } .ogl_pieLabel, .ogl_pieItems { position:relative; z-index:1; } .ogl_pieLabel { background:#222f40; border-radius:4px; box-sizing:border-box; color:var(--textblue); display:block; padding:10px; white-space:nowrap; width:100%; } .ogl_pieLabel > span { display:grid; font-weight:bold; grid-gap:6px; grid-template-columns:15px 120px 50px 50px; margin:4px; } .ogl_pieLabel > span > span { overflow:hidden; text-overflow:ellipsis; } .ogl_pieLabel > span > span:last-child { color:#fff; } .ogl_pieLabel > span b { color:var(--textgold); text-align:right; } .ogl_pieLabel > div span:last-of-type { color:#fff; } .ogl_pieLabel > div b { opacity:.7; text-align:right; } .ogl_pieLabel > div > div { border-radius:50%; display:inline-block; height:10px; margin-top:3px; width:10px; } /* POPUP ----------------------------*/ .ogl_overlay, .ogl_popup { display:none; } .ogl_overlay.ogl_active { align-items:center; background:rgba(0,0,0,.7); display:flex; justify-content:center; left:0; position:fixed; top:0; height:100%; width:100%; z-index:10000; } .ogl_popup.ogl_active { background:var(--p3); border-radius:0 0 3px 3px; border-top:3px solid; border-image:var(--uigradient) 1; box-shadow:0 0 16px 2px #000; display:block; position:relative; } .ogl_popup.ogl_active.ogl_cleaned { background:none; border:none; box-shadow:none; } .ogl_popup.ogl_active.ogl_cleaned .ogl-loader { background:none; } .ogl_popup.ogl_active.ogl_cleaned .ogl_close { display:none; } .ogl_popup.ogl_active > div:not(.ogl_close) { box-sizing:border-box; max-height:calc(90vh - 40px); overflow-x:hidden; overflow-y:auto; } .ogl_popup.ogl_active > div:not(.ogl_close) > div:first-child:not(.ogl_loader) { padding:25px; } .ogl_popup.ogl_active img { border:2px dashed #303d4e; border-radius:5px; display:block; margin:20px; } .ogl_popup.ogl_active input { height:16px; width:120px; } .ogl_planetList .ogl_linkedMoon { margin-bottom:10px; } .ogl_planetList .ogl_button { width:100%; } .ogl_planetList div[data-coords] { background:var(--p2); border:2px solid var(--p1); border-width:2px 2px 0 2px; display:grid; font-size:11px; grid-gap:10px; grid-template-columns:180px auto; line-height:25px; padding:2px 5px; position:relative; white-space:nowrap; } .ogl_planetList div[data-coords]:nth-child(2) { border-radius:6px 6px 0 0; } .ogl_planetList div[data-coords]:last-child { border-bottom:2px solid var(--p1); border-radius:0 0 6px 6px; } .ogl_planetList .ogl_coords { display:grid; grid-template-columns:70px auto; overflow:hidden; } .ogl_planetList .ogl_coords b { color:var(--textgold); } .ogl_planetList .ogl_actions { color:var(--textblue); display:grid; grid-gap:10px; grid-template-columns:repeat(2, 1fr); } .ogl_planetList .ogl_actions .ogl_planet { cursor:pointer; font-size:17px !important; line-height:21px !important; width:33px !important; } .ogl_planetList .ogl_actions .ogl_planet:hover { color:var(--textsand); } .ogl_planetList .ogl_actions .ogl_planet.ogl_disabled { background:hsl(354deg 23% 14%) !important; color:var(--red2) !important; opacity:.5; pointer-events:none; } .ogl_lockedIcon { color:var(--textpremium); bottom:-2px; cursor:pointer; font-size:15px !important; position:absolute; right:-20px; } .ogl_lockedIcon.ogl_ok { color:var(--green); } .ogl_lockedIcon:hover { color:#fff; } .ogl_lockInfo { width:auto; } .ogl_lockInfo hr { border:none; grid-column:1 / 6; height:24px; margin:0; width:100%; } .ogl_lockLine { align-items:center; background:var(--p2); border:2px solid var(--p1); box-shadow:inset 0 43px var(--p1), inset 0 -43px var(--p1); display:grid; font-size:12px; grid-gap:2px 0; grid-template-columns:auto 140px 140px 140px 130px; justify-items:flex-end; overflow:hidden; padding:8px; white-space:nowrap; } .ogl_lockLine:nth-child(1) { margin-bottom:10px; } .ogl_lockLine > div { align-self:normal; height:25px; line-height:25px; padding:0 8px; text-align:right; } .ogl_lockInfo .ogl_type { text-align:left; } .ogl_lockLine .ogl_shipIcon { border-color:var(--p6); height:28px; margin:-1px 0 0 auto; padding:0 5px; } .ogl_lockLine .material-icons { font-size:16px !important; } .ogl_lockLine .ogl_button { margin-left:3px; padding:0 5px; } .ogl_lockLine .ogl_ok.material-icons { font-size:22px !important; margin-left:5px; vertical-align:middle; } .ogl_lockLine .ogl_delete { cursor:pointer; } .ogl_fullGrid { grid-column-end:-1; grid-column-start:1; } .ogl_lockPopup { display:grid; grid-gap:20px; } .ogl_lockedContainer { align-items:center; display:grid; grid-gap:5px; grid-template-columns:140px 80px 120px 120px 120px 40px 40px 40px; line-height:24px; } .ogl_lockedContainer .ogl_header { grid-row-start:1; } .ogl_lockedContainer .ogl_button { border-left:none; border-radius:0; box-shadow:inset 0 14px rgb(255 255 255 / 7%); height:32px; line-height:28px !important; font-size:16px !important; padding:0; text-align:center; width:100%; } .ogl_lockedContainer .ogl_button.ogl_disabled { background:#2c2c2c !important; color:#545454; pointer-events:none; opacity:.5; } .ogl_mineContainer { align-items:center; display:grid; grid-gap:7px; grid-template-columns:auto auto auto auto auto auto auto; line-height:24px; user-select:none; } .ogl_mineContainer > *, .ogl_lockedContainer > * { background:#1c2736; border-radius:4px; padding:0 16px; white-space:nowrap; } .ogl_mineContainer .material-icons, .ogl_lockedContainer .material-icons { color:var(--textblue); cursor:pointer; font-size:16px !important; padding:0; text-align:center; } .ogl_mineContainer .material-icons:hover, .ogl_lockedContainer .material-icons:hover { color:var(--textsand); } .ogl_mineContainer .ogl_header, .ogl_lockedContainer .ogl_header { background:#202d3e; } .ogl_mineContainer b.ogl_header { color:var(--textblue); font-size:15px; font-weight:bold; text-align:right; } .ogl_mineContainer span, .ogl_lockedContainer span { color:var(--textblue); font-size:11px; font-weight:bold; overflow:hidden; position:relative; text-align:left; text-overflow:ellipsis; } .ogl_mineContainer span[data-multi], .ogl_lockedContainer span[data-multi] { overflow:visible; } .ogl_lockedContainer span.ogl_header { color:#fff; } .ogl_mineContainer i, .ogl_lockedContainer i { color:var(--textblue); font-size:11px; font-weight:normal; } .ogl_mineContainer strong, .ogl_lockedContainer strong { color:#fff; } .ogl_mineContainer b, .ogl_lockedContainer b { display:inline-block; font-size:12px; text-align:left; } .ogl_mineContainer div { float:right; font-size:9px; margin-left:15px; opacity:.5; font-style:italic; } /* OVERVIEW ----------------------------*/ .ogl_storage { background:rgba(0,0,0,.8); border-top:1px solid #000; color:var(--yellow2); display:none; font-size:9px; font-weight:bold; height:32px; line-height:14px; padding-top:4px; pointer-events:none; position:absolute; top:14px; width:49px; } #resourcesbarcomponent:hover .ogl_storage { display:block; } #resourcesbarcomponent #resources .value { font-weight:bold; } #resourcesbarcomponent * { pointer-events:none; } #resourcesbarcomponent #darkmatter_box a, #resourcesbarcomponent [class*="tooltip"] { pointer-events:all; } #overviewcomponent #planetdata { bottom:47px; position:absolute !important; right:0; } .ogl_hiddenCopy { left:-10000px; position:fixed; top:-10000px; z-index:-1; } /* GALAXY ----------------------------*/ .galaxyTable, #galaxytable { background:#0d1014; border-collapse:collapse; } #galaxyLoading:after { background:rgba(0,0,0,.7); border-radius:8px; content:attr(data-currentposition); font-size:13px; font-weight:bold; left:50%; padding:5px; position:absolute; top:50%; transform:translate(-50%, -50%); } #galaxyheadbg2 { border-left:none; border-right:none; display:grid; grid-template-columns:66px 140px 35px 50px auto 80px 90px; line-height:25px; width:auto; } #galaxyheadbg2 > th { width:100% !important; } .galaxyTable .ctContentRow:not([class*="filtered_"]), .ogl_spyTable tr, #galaxytable .row:not([class*="filtered_"]) { height:30px; opacity:1; position:relative; } .galaxyTable .ctContentRow:not(.bdaySlot):before, #galaxytable .row:not(.bdaySlot):before { background:linear-gradient(to right, rgba(23,31,41,.6) 10px, rgba(23,31,41,.96) 200px); content:''; height:33px; left:0; position:absolute; width:100%; } .galaxytable .expeditionDebrisSlot:before, #galaxytable .expeditionDebrisSlot:before { height:64px; } .galaxyTable .ctContentRow > div, #galaxytable .row > div { background:none !important; border-radius:0; box-shadow:inset 1px 0 rgba(255,255,255,.03), inset -1px 0 rgba(0,0,0,.5), inset 0 1px rgba(255,255,255,.03), inset 0 -1px rgba(0,0,0,.5); filter:brightness(100%) !important; font-size:11px; font-weight:normal; line-height:17px !important; padding:0 5px; text-shadow:1px 1px var(--p1); transition:background .2s; white-space:nowrap; z-index:10; } .galaxyTable .ctContentRow .cellPlanetName span { margin-right:auto; max-width:90px; overflow:hidden; text-align:left; text-overflow:ellipsis; } .galaxyTable .ctContentRow[class*="filtered_filter_"]:not([data-color]):before, #galaxytable .row[class*="filtered_filter_"]:not([data-color]):before { background:#0d1014; } .galaxyTable .ctContentRow[class*="filtered_filter_"]:not([data-color]) td { opacity:.2; } .galaxyTable .ctContentRow * { white-space:nowrap; } .galaxyTable .ctContentRow .cellPlayerName span[class*="status_"] { cursor:pointer; } .galaxyTable .ctContentRow .cellPlayerName span:hover { text-decoration:underline; } .galaxyTable .ctContentRow .cellPlayerName .float_right { color:var(--textsand); margin-left:auto; text-decoration:none; } .galaxyTable .phalanxlink, .galaxyTable .phalanxInctive { margin-right:36px !important; } .galaxyTable .galaxyRow .galaxyCell.cellPlayerName > span:not(.ownPlayerRow) { cursor:pointer; display:inline-block; max-width:70px; overflow:hidden; margin-right:4px; text-overflow:ellipsis; } #galaxytable tr.row { display:grid; grid-gap:3px; grid-template-columns:22px 40px 162px 38px 38px 162px 70px 101px; height:33px !important; margin-bottom:2px; } #galaxytable tr.row:last-child { margin:0; } #galaxytable .moon, #galaxytable .moon_a { background-size:100%; filter:brightness(100%); margin:1px 3px; } #galaxytable tr.row td { background:none !important; box-shadow:inset 1px 0 rgb(255 255 255 / 3%), inset -1px 0 rgb(0 0 0 / 50%), inset 0 1px rgb(255 255 255 / 3%), inset 0 -1px rgb(0 0 0 / 50%); box-sizing:border-box; height:33px !important; line-height:33px !important; margin:0 !important; position:relative; width:100% !important; } #galaxytable div.activity { border:none !important; border-radius:2px !important; box-shadow:0 0 3px 1px rgba(0,0,0,.7); color:#000 !important; font-size:11px !important; font-weight:bold !important; height:14px !important; line-height:14px !important; margin-left:-5px !important; margin-top:-2px !important; padding:0 !important; text-align:center !important; width:20px !important; z-index:10; } #galaxytable div.activity.minute15 { background:#b70000 !important; line-height:18px !important; width:14px !important; } #galaxytable div.activity.minute15:before { content:'*'; color:#fff; line-height:15px; } #galaxytable div.activity.minute60 { display:none !important; } #galaxytable div.activity.showMinutes { background:#ffa800 !important; } #galaxytable .planetname img { height:16px; position: absolute; right:43px; top:8px; width:16px; } #galaxytable td.playername { width:240px; } #galaxytable .playername .float_right, #galaxytable .playername .float_right a { color:var(--textgold); } #galaxytable .ListImage .planetTooltip, #galaxytable tr.row td.moon img { margin-left:-5px; } #galaxytable td.moon { width:30px; } #galaxytable tr.row td.planetname, #galaxytable tr.row td.planetname1 { text-align:left; text-indent:10px; } #galaxytable tr td.action { padding-top:3px !important; } #galaxytable tr td.playername { padding:0 5px !important; } #galaxytable tr td.playername span[class^="status_"] { cursor:pointer; } #galaxytable tr td.playername span[class^="status_"]:hover { text-decoration:underline; } #galaxytable .playername a { display:inline-block; max-width:72px; overflow:hidden; text-overflow:ellipsis; vertical-align:unset; white-space:nowrap; } #galaxytable tr.row td span.status { margin-left:-2px !important; vertical-align:top !important; } #galaxytable .playername .honorRank { margin:2px 0 0 -1px !important; pointer-events:none; position:relative; top:6px; vertical-align:top; } .status_abbr_longinactive { color:#616161!important; } .status_abbr_inactive { color:#989898!important; } #galaxytable .playername { text-align:left; } #galaxytable .activity, #galaxytable .fleetAction { pointer-events:none; } .galaxyTable .cellDebris { text-align:center; } .galaxyTable .microdebris, #galaxytable .debrisField { background:none !important; color:#fff; font-size:10px; left:0; line-height:14px; padding:0; position:absolute; white-space:nowrap; width:100% !important; } .galaxyTable .cellDebris.ogl_active, #galaxytable .debris.ogl_active { background:#ad5b21 !important; opacity:1 !important; } #galaxytable .debris.ogl_active a { color:#fff !important; padding-top:1px; } #galaxytable td.debris a { font-size:10px; line-height:14px; text-decoration:none; width:100% !important; white-space:nowrap; } .expeditionDebrisSlot { background:var(--p3); } .expeditionDebrisSlot:before { display:none; } .expeditionDebrisSlotBox { align-items:center; background:none !important; border:none !important; box-shadow:none !important; display:grid !important; grid-template-columns:20% auto auto auto !important; margin:6px 0 5px 0 !important; padding:4px 0 5px 0 !important; width:642px !important; } .expeditionDebrisSlotBox li { list-style:none; } .expeditionDebrisSlotBox > img { float:right; justify-self:center; } .expeditionDebrisSlotBox > div { line-height:1.6; text-align:left; } .expeditionDebrisSlotBox a { color:var(--green1); } .expeditionDebrisSlotBox a:hover { text-decoration:underline; } #galaxytable .status_abbr_ally_own { color:hsl(140deg 47% 46%) !important; } .galaxyTooltip h1 { margin:0 !important; } /* SIDEVIEW ----------------------------*/ .ogl_sideView { background:var(--p3); bottom:0; box-sizing:border-box; padding:50px 20px 40px 20px; position:fixed; top:0; transition:transform .3s; transform:translateX(100%); right:0; user-select:none; width:300px; z-index:10000; } .ogl_sideView.ogl_opened { transition:none; } .ogl_sideView.ogl_active { box-shadow:0 0 10px #000; transform:translateX(0%); } .ogl_sideView .ogl_close { right:20px; top:10px; } .ogl_sideView .ogl_loader { left:calc(50% - 65px); position:absolute; top:calc(50% - 65px); } .ogl_sideView .ogl_stalkList.ogl_disabled { opacity:.2; pointer-events:none; } .ogl_sideView .ogl_stalkList > div { margin-bottom:10px; } .ogl_sideView .ogl_stalkPlanets { background:var(--p2); border:2px solid var(--p1); border-radius:3px; overflow-y:auto; padding:10px; height:calc(100vh - 325px); } .ogl_sideView .ogl_stalkPlanets > div { align-items:center; background:var(--p6); box-shadow:0 0 5px #000; box-sizing:border-box; color:#fff; display:grid; font-size:10px; font-weight:bold; grid-gap:5px; grid-template-columns:60px auto 20px 20px 20px; line-height:25px; margin-bottom:5px; padding:0 7px 2px 7px; position:relative; } .ogl_sideView .ogl_stalkPlanets > div > div { position:relative; white-space:nowrap; z-index:1; } .ogl_sideView .ogl_stalkPlanets > div > div:nth-child(1) { color:#fff; cursor:pointer; } .ogl_sideView .ogl_stalkPlanets > div > div:nth-child(1):hover { text-decoration:underline; } .ogl_stalkPlanets > div.ogl_currentSystem > div:nth-child(1) { color:var(--textsand); } .ogl_sideView .ogl_stalkPlanets > div > div:nth-child(2) { font-style:italic; overflow:hidden; text-overflow:ellipsis; } .ogl_ptreIcon { fill:#353a3c; height:20px; vertical-align:middle; } .ptreFrames { display:grid; grid-gap:5px; grid-template-columns:repeat(6, 1fr); } .ptreLegend { color:var(--textblue); font-size:10px; margin-top:20px; text-align:left; } .ptreContent .ptreBestReport .ogl_button { color:var(--textcyan); padding:5px; } .ptreContent h3 { color:var(--textcyan); font-weight:bold; padding:10px 0; text-align:left; } .ptreContent [data-check] { align-self:center; background:currentColor; border-radius:50%; height:0; left:50%; position:absolute; top:50%; transform:translate(-50%, -50%); width:0; } .ptreContent [data-check].ogl_active { background:none; box-shadow:inset 0 0 0 3px currentColor; } .ptreActivities > span { color:var(--red2); } .ptreActivities > div { display:grid; grid-gap:5px; grid-template-columns:repeat(12, 1fr); } .ptreActivities > div > * { align-items:center; background:var(--p2); color:#656f78; display:grid; grid-gap:5px; grid-template-rows:18px auto; padding:5px 3px; } .ptreActivities > div > * > * { display:inline-block; margin:auto; } .ptreActivities .ptreDotStats { height:30px; position:relative; width:30px; } .ptreContent { text-align:center; } .ptreBestReport { display:grid; grid-template-rows:45px auto; } .ogl_sideView .ogl_stalkPoints { grid-gap:2px; margin:0; } .ogl_sideView .ogl_stalkPoints > div { border-color:var(--p2); } .ogl_pinnedContent.ogl_stalkPlanets > div { display:block; font-size:11px; } .ogl_pinnedContent.ogl_stalkPlanets > div.ogl_new > span { border-bottom:1px dashed; } .ogl_currentSystem { color:var(--textpremium); } .ogl_pinnedContent.ogl_stalkPlanets .ogl_checked { color:var(--green1); font-size:14px !important; position:absolute; right:2px; } .msg_title { position:relative; } .msg_title .ogl_checked { color:var(--green1); font-size:14px !important; margin-left:7px; position:absolute; vertical-align:sub; } .ogl_sideView .ogl_stalkPlanets > div:after { background:var(--p3); content:''; height:25px; left:0; position:absolute; top:0; width:100%; } .ogl_sideView .ogl_stalkPlanets > div.ogl_active:after { background:var(--p5); } .ogl_sideView .ogl_stalkPlanets > div > span { position:relative; z-index:1; } .ogl_sideView .ogl_stalkPlanets .ogl_playerName { color:var(--textcyan); cursor:pointer; overflow:hidden; position:relative; white-space:nowrap; z-index:1; } .ogl_sideView .ogl_stalkPlanets .ogl_playerName:hover { color:var(--textsand); } .ogl_sideView h1 { color:var(--textcyan); font-size:16px; font-weight:bold; text-align:center; } .ogl_pinnedHistory { float:left; font-size:20px !important; margin-right:10px; } .ogl_pinnedContent.ogl_stalkPlanets > div span { line-height:24px; position:relative; z-index:1; } .ogl_sideView .ogl_stalkPlanets > div .ogl_planetIcon, .ogl_sideView .ogl_stalkPlanets > div .ogl_moonIcon, .ogl_sideView .ogl_stalkPlanets > div .ogl_flagIcon { border-radius:50%; color:var(--textblue); cursor:pointer; font-size:18px !important; justify-self:end; } .ogl_stalkPlanets > div .ogl_planetIcon.ogl_done, .ogl_stalkPlanets > div .ogl_moonIcon.ogl_done { color:#34952e; } .ogl_sideView .ogl_stalkPlanets > div .ogl_planetIcon:hover, .ogl_sideView .ogl_stalkPlanets > div .ogl_moonIcon:hover, .ogl_sideView .ogl_stalkPlanets > div .ogl_flagIcon:hover, .ogl_sideView .ogl_stalkPlanets > div .ogl_flagIcon.ogl_active { color:#fff; } .ogl_stalkPlanets > div .ogl_planetIcon.ogl_noPointer, .ogl_stalkPlanets > div .ogl_moonIcon.ogl_noPointer, .ogl_stalkPlanets > div .ogl_flagIcon.ogl_noPointer { opacity:.2; } .ogl_stalkPlanets > div .ogl_planetIcon.ogl_disabled, .ogl_stalkPlanets > div .ogl_moonIcon.ogl_disabled, .ogl_stalkPlanets > div .ogl_flagIcon.ogl_disabled { color:hsl(111deg 56% 49%) !important; } .ogl_stalkPlanets > div .ogl_planetIcon.ogl_danger, .ogl_stalkPlanets > div .ogl_moonIcon.ogl_danger, .ogl_stalkPlanets > div .ogl_flagIcon.ogl_danger { color:hsl(0deg 67% 52%) !important; } .ogl_stalkPlanets > div .ogl_planetIcon.ogl_loading, .ogl_stalkPlanets > div .ogl_moonIcon.ogl_loading, .ogl_stalkPlanets > div .ogl_flagIcon.ogl_loading { color:var(--yellow1) !important; pointer-events:none; } .ogl_pinnedContent.ogl_stalkPlanets > div .ogl_planetIcon, .ogl_pinnedContent.ogl_stalkPlanets > div .ogl_moonIcon { float:right; margin-right:40px; } .ogl_pinnedContent.ogl_stalkPlanets > div .ogl_planetActivity, .ogl_pinnedContent.ogl_stalkPlanets > div .ogl_moonActivity { position:absolute; top:0; } .ogl_pinnedContent.ogl_stalkPlanets > div .ogl_planetActivity { right:85px; } .ogl_pinnedContent.ogl_stalkPlanets > div .ogl_moonActivity { right:28px; } .ogl_pinnedContent.ogl_stalkPlanets div[data-activity] { color:var(--yellow1) !important; } .ogl_pinnedContent.ogl_stalkPlanets div[data-activity].ogl_short { color:var(--red1) !important; } .ogl_pinnedContent.ogl_stalkPlanets div[data-activity="60"] { color:#fff !important; opacity:.2; } .ogl_sideView .ogl_stalkList > div:nth-child(1) { background:var(--p2); border-radius:3px; display:grid; grid-gap:3px; grid-template-columns:repeat(8, 1fr); padding:5px; } .ogl_sideView .ogl_stalkList > div:nth-child(2), .ogl_sideView .ogl_stalkList > div:nth-child(3), .ogl_pinnedSelector { background:var(--p2); border-radius:3px; display:grid; grid-gap:5px; padding:5px; text-align:center; } .ogl_sideView .ogl_stalkList > div:nth-child(2) { grid-template-columns:repeat(6, 1fr); } .ogl_sideView .ogl_stalkList > div:nth-child(3) { grid-template-columns:repeat(5, 1fr); } .ogl_sideView .ogl_stalkList > div:nth-child(2) > div, .ogl_sideView .ogl_stalkList > div:nth-child(3) > div { background:var(--p4); border-radius:3px; cursor:pointer; font-weight:bold; line-height:22px; } .ogl_historyButton { font-size:20px !important; margin-right:7px; padding:0 10px; } .ogl_historyList { background:var(--p2); display:grid; grid-gap:5px; max-height:calc(100vh - 116px); overflow:auto; padding:15px } .ogl_historyList .ogl_button { background:#19242e !important; border:2px solid #1e2b38; box-shadow:0 0 5px #000; display:grid; grid-template-columns:90px auto auto; font-size:11px; font-weight:normal !important; padding:0 10px; text-align:left; white-space:nowrap; } .ogl_historyList .ogl_button:hover { background:var(--p5) !important; text-shadow:none !important; } .ogl_historyList .ogl_button > * { line-height:23px !important; } .ogl_historyList .ogl_button b { display:inline-block; max-width:90px; overflow:hidden; text-align:left; text-overflow:ellipsis; } .ogl_historyList .ogl_button span { color:var(--textsand); display:inline-block; font-size:10px; text-align:left; } .ogl_historyList .ogl_button .float_right { color:var(--fleet) !important; text-align:right; } .ogl_pinnedSelector { background:none; padding:0; } .ogl_pinnedSelector > li { font-size:11px; padding:3px 10px; text-align:left; } .ogl_pinnedSelector > li span { color:var(--textsand); font-size:10px; } .ogl_sideView .ogl_stalkList > div:nth-child(2) > div.ogl_disabled, .ogl_sideView .ogl_stalkList > div:nth-child(3) > div.ogl_disabled { background:none; opacity:.2; pointer-events:none; } .ogl_sideView .ogl_stalkList > div:nth-child(2) > div:hover, .ogl_sideView .ogl_stalkList > div:nth-child(3) > div:hover { box-shadow:inset 0 0 12px 3px var(--neon); color:#fff !important; } .ogl_sideView .ogl_stalkList > div:nth-child(2) > div.ogl_active, .ogl_sideView .ogl_stalkList > div:nth-child(3) > div.ogl_active { box-shadow:inset 0 0 1px 1px var(--neonborder), inset 0 0 12px 3px var(--neon); color:#fff !important; } .ogl_sideView .ogl_toggleGalaxies { background:var(--p2); border-radius:3px; display:grid; grid-gap:3px; grid-template-columns:repeat(6, 1fr); margin-top:20px; } .ogl_sideView .ogl_toggleSystems { background:var(--p2); border-radius:3px; display:grid; grid-gap:5px; grid-template-columns:repeat(5, 1fr); margin:20px 0 20px 0; } .ogl_sideView .ogl_toggleGalaxies > div, .ogl_sideView .ogl_toggleSystems > div { color:#fff; border-radius:3px; cursor:pointer; font-weight:bold; line-height:26px; text-align:center; } .ogl_sideView .ogl_toggleGalaxies > div:hover, .ogl_sideView .ogl_toggleSystems > div:hover { background:var(--p4); } .ogl_sideView .ogl_toggleGalaxies .ogl_active, .ogl_sideView .ogl_toggleSystems .ogl_active { background:var(--p1) !important; box-shadow: inset 0 0 1px 2px var(--neonborder), inset 0 0 12px 3px var(--neon); color:#fff; } .ogl_sideView .ogl_toggleGalaxies .ogl_disabled, .ogl_sideView .ogl_toggleSystems .ogl_disabled { background:none !important; box-shadow:none !important; color:hsl(210deg 30% 18%); pointer-events:none; } .ogl_sideView .ogl_toggleColors { display:grid; grid-template-columns:repeat(6, 1fr); } .ogl_sideView .ogl_toggle, .ogl_sideView .ogl_sideSelection { border:2px solid var(--p3); border-radius:20px; box-sizing:border-box; cursor:pointer; font-size:14px !important; height:20px; opacity:.3; position:relative; width:100%; } .ogl_sideView .ogl_stalkPlanets > div > span:hover { color:var(--textsand); cursor:pointer; } .ogl_sideView .ogl_toggle:hover { filter:brightness(1.2); } .ogl_sideView .ogl_toggle.ogl_active { opacity:1; } .ogl_sideSelection { background:var(--p2); color:var(--textcyan) !important; grid-column:-3; grid-row:2; line-height:16px !important; opacity:1 !important; text-align:center; } .ogl_sideSelection:hover { color:#fff !important; } .ogl_sideSelection:last-child { grid-column:-2; grid-row:2; } /* MESSAGE ----------------------------*/ .msg { border-radius:5px; box-shadow:0 0 0 2px var(--p1) !important; overflow:hidden; } .msg .ogl_metal, .msg .ogl_crystal, .msg .ogl_deut, .msg .ogl_food, .msg [data-type] { background:hsl(206deg 30% 21%); display:inline-block; padding:2px; font-size:10px; font-weight:bold; border-radius:3px; } .msg_status { box-shadow:2px 0 var(--p1); } .msg_status:before { background:none !important; } .ogl_expeResult { background:hsl(207deg 33% 13%); border-bottom:2px solid var(--p1); color:var(--textpremium); font-size:10px; font-weight:bold; padding:3px 0; z-index:1; text-align:center; position:relative; } .ogl_expeResult > div:not(.ogl_button) { background:none !important; font-size:11px !important; margin:0 4px; } .msg_new .ogl_expeResult { background:hsl(204deg 23% 27%); } .ogl_button.ogl_ignoreRaid { box-shadow:inset 0 8px rgb(255 255 255 / 7%); color:var(--textcyan) !important; font-size:18px !important; left:8px; line-height:16px !important; position:absolute; top:1px; width:30px; } .ogl_button.ogl_ignoreRaid:hover { color:#fff !important; } .ogl_button.ogl_ignoreRaid.ogl_active { color:var(--red1) !important; } .ogl_button.ogl_ignoreRaid:before { content:'toggle_off'; } .ogl_button.ogl_ignoreRaid.ogl_active:before { content:'toggle_on'; } /* CONFIG ----------------------------*/ .ogl_scriptTitle { font-size:45px; font-weight:bold; } .ogl_scriptTitle span { color:#85a0c1; font-size:16px; font-weight:normal; } .ogl_globalConfig { display:grid; grid-gap:20px; grid-template-columns:repeat(2, 1fr); } .ogl_globalConfig > div:nth-child(1) { align-items:center; display:flex; flex-direction:column; justify-content:center; } .ogl_globalConfig p { margin-bottom:10px; padding:10px 0; } .ogl_globalConfig input[type="number"] { background-color:#c8d1da !important; border:none !important; border-radius:2px !important; box-shadow:0 0 0 2px #eef7fb !important; color:var(--p2) !important; font-size:12px; font-weight:bold !important; line-height:20px; padding:2px 5px; -webkit-appearance:textfield; -webkit-box-sizing:content-box; } .ogl_kofi { background:var(--ui1); border:2px solid var(--darkblue); border-radius:4px; color:#fff !important; display:block; line-height:36px !important; padding:0 14px; text-decoration:none !important; text-shadow:1px 1px rgba(0,0,0,.3); } .ogl_kofi:after { color:var(--red); content:'favorite'; font-family:'material icons'; font-size:16px !important; margin-left:7px; text-shadow:none; vertical-align:bottom; -webkit-text-stroke:2px var(--p3); } .ogl_kofi:hover { background:var(--ui2); } .ogl_config { background:var(--p2); border-radius:4px; display:grid; grid-gap:10px; padding:20px; } .ogl_config a:hover { color:var(--sunset); } .ogl_globalConfig h2 { border-bottom:2px dashed #1e2a36; color:var(--textsand); font-size:10px; font-weight:bold; margin-top:7px; padding:7px 0; text-align:left; } .ogl_globalConfig hr { background:none; border:none; height:2px; margin:5px 0; width:100%; } .ogl_config hr { margin:10px 0; } .ogl_globalConfig .ogl_button { color:var(--textcyan); padding:0 8px; } .ogl_config > div { display:grid; grid-gap:30px; grid-template-columns:auto max-content; line-height:22px; white-space:nowrap; } .ogl_config > .ogl_manageData { grid-gap:5px; grid-template-columns:repeat(3, 1fr); } .ogl_config > .ogl_manageData > * { font-size:11px; font-weight:bold; } .ogl_config > .ogl_manageData > *:first-child { color:#d55757; } .ogl_confToggle { background:#304050; border-radius:50px; cursor:pointer; font-size:11px; font-weight:bold; position:relative; width:50px; } .ogl_confToggle.ogl_active:hover { background:var(--ui2); } .ogl_confToggle:hover { background:#3c4f62; } .ogl_confToggle.ogl_active { background:var(--ui1); } .ogl_confToggle:before { box-sizing:border-box; content:'OFF'; height:100%; padding:0 5px; position:absolute; text-align:right; width:100%; } .ogl_confToggle.ogl_active:before { content:'ON'; text-align:left; } .ogl_confToggle:after { background:#fff; border-radius:50px; box-shadow:0 0 4px rgba(0,0,0,.5); content:''; height:16px; left:3px; position:absolute; top:3px; transition:left .2s; width:16px; } .ogl_confToggle.ogl_active:after { left:calc(50px - 20px); } /* FLEET1 ----------------------------*/ #fleet1 #buttonz .content { margin-bottom:35px; } #fleet1 #continueToFleet2, #fleet2 #sendFleet, #fleet2 #backToFleet1, .ogl_fleetBtn { background:linear-gradient(to bottom right, var(--p3) 45%, var(--p1)) !important; border:2px solid var(--p1) !important; border-radius:4px; box-shadow:inset 0 1px rgba(255,255,255,.07); color:var(--green1) !important; height:auto !important; text-decoration:none !important; } #fleet1 #continueToFleet2:hover, #fleet2 #sendFleet:hover, #fleet2 #backToFleet1:hover, .ogl_fleetBtn:hover { color:#fff !important; } #fleet1 #continueToFleet2, .ogl_fleetBtn { cursor:pointer; font-size:12px; font-weight:bold; margin:0 !important; line-height:34px; text-align:center; text-transform:uppercase; user-select:none; width:120px; } #fleet2 #backToFleet1 { color:var(--red1) !important } #fleet1 #continueToFleet2 span { height:34px !important; line-height:34px !important; } #fleet1 #continueToFleet2.off, #fleet2 #sendFleet.off { background:linear-gradient(to top left, var(--p3) 45%, var(--p1)) !important; color:var(--red1) !important; opacity:.7; } #fleet1 #continueToFleet2 span, #fleet2 #sendFleet span, #fleet2 #backToFleet1 span { color:inherit !important; padding:0 !important; } #fleet1 #continueToFleet2.off span, #fleet2 #sendFleet.off span { color:inherit !important; } #fleet1 #buttonz .header { display:none !important; } #fleet1 #buttonz #battleships { margin-left:8px !important; width:441px !important; } #fleet1 #buttonz #battleships ul, #fleet1 #buttonz #civilships ul, #shipyard #technologies_battle ul, #shipyard #technologies_civil ul { padding:0 !important; } #shipyard #technologies_battle { margin-left:0 !important; width:400px !important; } #shipyard #technologies_civil { margin-left:0 !important; width:240px !important; } #fleet1 #allornone { padding-bottom:10px; } #fleet1 #allornone .info { display:none; } #fleet1 .allornonewrap { align-items:end !important; background:none !important; border:none !important; display:grid !important; grid-gap:2px !important; grid-template-columns:118px auto min-content !important; margin-top:7px !important; padding:0 !important; width:637px !important; } #fleet1 .allornonewrap .secondcol { align-items:end !important; background:none !important; border:none !important; display:grid !important; float:right !important; grid-column-start:1 !important; grid-row-start:1 !important; grid-gap:2px !important; grid-template-columns:repeat(4, 1fr) !important; margin:0 !important; padding:0 !important; } #fleet1 .allornonewrap .firstcol { background:var(--p1); border-radius:4px; bottom:-27px !important; padding:4px; position:absolute !important; right:19px !important; width:auto !important; } #fleet1 .allornonewrap .secondcol .clearfloat { display:none !important; } #fleet1 .send_all, #fleet1 .send_none, #fleet1 .ogl_expeButton, #fleet1 .show_fleet_apikey, .ogl_capacityContainer { background:linear-gradient(to bottom right, var(--p3) 45%, var(--p1)) !important; border:2px solid var(--p1) !important; border-radius:4px; box-shadow:inset 0 1px rgba(255,255,255,.07); color:#fff !important; cursor:pointer; font-size:12px; font-weight:bold; grid-row-start:1; height:auto; position:relative; text-decoration:none !important; width:38px; } #fleet1 .send_all:before, #fleet1 .send_none:before, #fleet1 .ogl_expeButton:before, #fleet1 .show_fleet_apikey:before { content:''; line-height:34px !important; width:100%; } #fleet1 .send_all:hover, #fleet1 .send_none:hover, #fleet1 .ogl_expeButton:hover, #fleet1 .show_fleet_apikey:hover { color:#fff !important; } #fleet1 .send_all, #fleet1 .send_none { font-family:"Material Icons"; font-size:20px; } #fleet1 #sendall, #fleet1 #resetall { background:none; height:100%; left:-1px; padding:1px; position:absolute; text-align:center; top:-1px; width:100%; } #fleet1 .send_all { color:#d0af37 !important; } #fleet1 .send_none { color:#bd4d4d !important; } #fleet1 .ogl_expeButton { color:#4087f1 !important;display:none; } #fleet1 .show_fleet_apikey { color:#9c9c9c !important;grid-column-start:3; } #fleet1 .send_all:before { content:'double_arrow'; } #fleet1 .send_none:before { content:'exposure_zero'; } #fleet1 .ogl_expeButton:before { content:'EXP'; } #fleet1 .show_fleet_apikey:before { content:'API'; } #fleet1 .ogl_capacityContainer { box-sizing:border-box; grid-column-start:2; grid-row-start:1; height:38px; padding:5px; position:relative; width:100% !important; } #fleet1 .ogl_capacityContainer i { font-size:17px !important; position:absolute; right:7px; top:7px; } #fleet1 .ogl_capacityContainer:hover i { color:var(--textsand); } #fleet1 .ogl_capacityInfo { background:#0c1014; border:2px solid #0c1014; bottom:4px; box-sizing:border-box; font-size:10px; font-weight:bold; height:8px; left:7px; line-height:16px; position:absolute; right:30px; } #fleet1 .ogl_capacityInfo p { pointer-events:none; transform:translate(0px, -22px); } #fleet1 .ogl_capacityInfo p b:nth-child(1) { color:var(--textsand); } #fleet1 .ogl_capacityInfo .ogl_capacityCurrent, #fleet1 .ogl_capacityInfo .ogl_capacityRequired { display:block; height:100%; left:0; position:absolute; top:0; z-index:-1; } #fleet1 .ogl_capacityInfo .ogl_capacityCurrent { background:#b18b22; min-width:1px; transition:width .3s; width:0%; } #fleet1 .ogl_capacityInfo .ogl_capacityRequired { color:var(--skyblue); text-align:left; transform:translate(0px, -22px); white-space:nowrap; } #fleet1 .ogl_capacityInfo .ogl_capacityRequired > div { background:repeating-linear-gradient(-45deg, #303e6f, #303e6f 5px, transparent 5px, transparent 10px); height:100%; transform:translate(0px, 6px); width:100%; } .ogl_preloadResources { display:grid; grid-template-columns:38px 180px; grid-gap:10px 2px; } .ogl_preloadResources div:last-child { display:grid; grid-gap:5px; grid-template-columns:repeat(2, 1fr); } .ogl_preloadResources .ogl_shipIcon { color:var(--textpremium) !important; cursor:pointer; font-size:22px !important; height:24px; padding:0; text-align:center; text-shadow:0 0 4px #000; } .ogl_preloadResources input { border:none !important; box-shadow:none !important; } .ogl_preloadResources h2 { color:var(--textcyan); font-weight:bold; padding:10px 0; text-align:left; } .ogl_preloadResources div:last-child, .ogl_preloadResources h2 { grid-column-start:1; grid-column-end:3; } #fleet1 .ogl_required { background:var(--p2); border-bottom:2px solid var(--p1); color:#fff; font-size:10px; line-height:20px; padding:0 4px; user-select:none; } #fleet1 .ogl_required:hover { color:var(--textsand); } #fleet1 .ogl_delta { background:var(--p2); border-bottom:2px solid var(--p1); border-radius:0 0 0 6px; color:var(--textcyan); font-size:15px !important; line-height:20px !important; padding:0 3px; position:absolute; right:0; top:0; user-select:none; } #fleet1 .ogl_delta:hover { color:var(--textsand); } #fleet1 .technology input[type="number"], #fleet1 .technology input[type="text"] { border-radius:0 0 2px 2px !important; bottom:-16px !important; height:18px !important; } .ogl_emptyGrid { color:#fff; display:grid; font-size:12px; font-weight:normal; float:right; grid-gap:5px; grid-template-columns:repeat(4, auto); margin:0 16px; overflow:hidden; width:fit-content; width:-moz-fit-content; } .ogl_emptyShip { background:hsl(0deg 36% 21%); border:1px solid #000; border-radius:3px; display:grid; grid-template-columns:32px auto; line-height:15px; } .ogl_emptyGrid .ogl_shipIcon { background-position:center; border:none !important; border-right:1px solid #000 !important; border-radius:0 !important; height:15px; image-rendering:-webkit-optimize-contrast; width:32px; } .ogl_emptyShip span { display:inline-block; padding:0 8px; } #fleetdispatchcomponent #warning p { margin:30px auto 18px auto; } /* FLEET2 ----------------------------*/ #fleet2 .percentageBarWrapper, #fleet2 #fleetboxmission, #fleet2 ul#missions span.textlabel, #fleet2 div#mission .missionHeader, #missionNameWrapper, #fleet2 .resbuttons { display:none !important; } #fleet2 #buttonz ul#missions { background:var(--p2); border:2px solid var(--p3); border-radius:5px; display:grid; grid-template-columns:repeat(12, 1fr); height:auto !important; margin:0 !important; margin-left:14px !important; padding:4px 0 !important; width:637px !important; } #fleet2 #buttonz ul#missions [data-mission] { border-radius:6px; } #fleet2 #buttonz ul#missions .selected:before, #fleet2 #buttonz ul#missions [data-mission]:hover:before { box-shadow:inset 0 0 1px 2px var(--neonborder), inset 0 0 12px 3px var(--neon); border-radius:6px; content:''; display:block; height:100%; width:100%; } #fleet2 #mission ul li { color:var(--textcyan) !important; list-style:disc !important; } #fleet2 #fleetboxbriefingandresources #start, #fleet2 #resources { background:var(--p2) !important; border:2px solid var(--p3); } #fleet2 div#mission { column-gap:16px !important; margin-top:23px !important; } #fleetboxdestination h2 { visibility:hidden; } #fleet2 .briefing_overlay { margin-top:-50px !important; min-height:calc(100% + 60px) !important; } #fleet2 .res { display:grid; grid-template-columns:auto 23px 23px 23px 42px; grid-gap:6px; height:auto; margin:0 !important; position:relative; width:auto !important; } #fleet2 .res .min, #fleet2 .res .max, #fleet2 .ogl_resourceSaver, #fleet2 .ogl_delta { background:var(--p3) !important; border-radius:2px; bottom:0; box-shadow:inset 0 12px var(--p4), 0 0 0 2px var(--p1); color:var(--textcyan) !important; cursor:pointer; font-size:16px; height:24px; left:auto !important; line-height:24px !important; position:relative !important; text-align:center !important; text-decoration:none !important; top:auto !important; width:100% !important; } #fleet2 .res .min:hover, #fleet2 .res .max:hover, #fleet2 .ogl_resourceSaver:hover, #fleet2 .ogl_delta:hover { box-shadow:inset 0 0 1px 2px var(--neonborder), inset 0 0 12px 3px var(--neon);; color:#fff !important; } #fleet2 .res .min img, #fleet2 .res .max img { display:none; } #fleet2 .res .min:before { content:'double_arrow'; display:block; font-family:'Material Icons'; transform:scaleX(-1); } #fleet2 .res .max:before { content:'double_arrow'; display:block; font-family:'Material Icons'; } #fleet2 .res input { border-radius:3px !important; box-shadow:0 0 0 1px #000 !important; height:18px !important; padding:0 5px !important; text-align:right; width:91px !important; } #fleet2 .res_wrap:nth-child(1) input { border:2px solid #bb8aa7 !important; } #fleet2 .res_wrap:nth-child(2) input { border:2px solid var(--metal) !important; } #fleet2 .res_wrap:nth-child(3) input { border:2px solid var(--crystal) !important; } #fleet2 .res_wrap:nth-child(4) input { border:2px solid var(--deut) !important; } .ogl_choseCapacity > div:nth-child(1) input { border:2px solid red !important; } .ogl_choseCapacity > div:nth-child(2) input { border:2px solid red !important; } .ogl_choseCapacity > div:nth-child(3) input { border:2px solid red !important; } .ogl_choseCapacity > div:nth-child(4) input { border:2px solid red !important; } #fleet2 .resourceIcon { border-radius:6px !important; height:24px !important; margin-right:3px !important; } #fleet2 #resources .res_wrap { background:none !important; border:none !important; border-radius:1px !important; box-shadow:none !important; height:auto !important; padding:0 !important; margin:7px !important; text-align:right !important; width:290px !important; } #fleet2 .ogl_resourceSaver, #fleet2 .ogl_delta { background:var(--p3); border:none; color:#fff; cursor:pointer; display:inline-block; padding:0; text-align:center; top:auto; width:15px; } #fleet2 .ogl_delta { font-size:14px !important; } #fleet2 .ogl_resourceSaver { font-size:20px !important; top:auto; width:100%; } #fleet2 .ogl_resourceSaver.ogl_active { color:var(--red1) !important; font-size:10px !important; font-weight:bold; white-space:nowrap; } .ogl_fleetSpeed { border:2px solid var(--p3); border-radius:5px; color:var(--textcyan); display:grid; grid-template-columns:repeat(10, 1fr); margin:15px; overflow:hidden; position:relative; text-align:center; top:11px; width:635px; } .ogl_fleetSpeed.ogl_big { grid-template-columns:repeat(20, 1fr); } .ogl_fleetSpeed > div { background:var(--p2); cursor:pointer; font-size:11px; font-weight:bold; line-height:20px; padding:5px 1px 5px 0; position:relative; transition:all .2s; } .ogl_fleetSpeed.ogl_big > div:nth-child(odd) { color:#607486; } .ogl_fleetSpeed > div.ogl_active, .ogl_fleetSpeed > div:hover { border-radius:3px; box-shadow:inset 0 0 12px 3px var(--neon); color:#fff; opacity:1; } .ogl_fleetSpeed > div.ogl_active { box-shadow:inset 0 0 1px 2px var(--neonborder), inset 0 0 12px 3px var(--neon); } #loadAllResources { background:none !important; bottom:11px; display:grid !important; font-size:0 !important; height:24px !important; left:auto !important; position:absolute !important; right:7px !important; top:auto !important; width:auto !important; } .ogl_unloadAllResources { font-weight:bold; /*background:hsl(0deg 100% 62%) !important; box-shadow:inset 0 12px hsl(8deg 78% 42% / 11%), inset 0 -11px 17px 6px hsl(210deg 30% 9%), 0 0 0 2px var(--p1); bottom:11px; color:hsl(0deg 64% 67%) !important; cursor:pointer; font-size:16px; font-weight:bold; height:24px !important; line-height:24px !important; margin:0 !important; padding:0 !important; position:absolute; right:53px; text-align:center !important; text-decoration:none !important; width:40px !important;*/ } #loadAllResources a, .ogl_unloadAllResources { background:linear-gradient(0deg, #151c22, #232f40) !important; border-radius:4px !important; box-shadow:inset 0 2px #283546, 0 0 0 2px var(--p1) !important; color:#efae37 !important; cursor:pointer !important; font-size:20px; height:24px !important; line-height:24px !important; margin:0 !important; padding:0 !important; text-align:center !important; text-decoration:none !important; text-shadow:-1px 2px var(--p2) !important; user-select:none !important; width:40px !important; /* background:hsl(174deg 100% 67%) !important; box-shadow:inset 0 12px hsl(8deg 78% 42% / 11%), inset 0 -11px 17px 6px hsl(210deg 30% 9%), 0 0 0 2px var(--p1); color:hsl(161deg 34% 68%) !important; cursor:pointer; font-size:20px; height:24px !important; line-height:24px !important; margin:0 !important; padding:0 !important; text-align:center !important; text-decoration:none !important; width:40px !important;*/ } .ogl_unloadAllResources { bottom:11px; color:#c14242 !important; font-size:16px; position:absolute; right:53px; } #loadAllResources a:hover, .ogl_unloadAllResources:hover { box-shadow: inset 0 0 1px 2px var(--neonborder), inset 0 0 12px 3px var(--neon) !important; color:#fff !important; } #loadAllResources a:before { content:'double_arrow'; display:block; font-family:'Material Icons'; } #loadRoom { bottom:12px !important; font-size:0 !important; left:7px !important; position:absolute !important; top:auto !important; } #loadRoom > div { font-size:10px !important; } .planetlink.ogl_active, .moonlink.ogl_active { box-shadow:inset 0 0 1px 2px var(--neonborder), inset 0 0 10px 2px hsl(233deg 43% 53%), 0 0 0 2px var(--p1) !important; } .ogl_acsInfo .value span { display:inline-block; margin-left:5px; } /* MESSAGES ----------------------------*/ .ogl_spyTable { background:var(--p2); border-radius:5px; box-shadow:0 0 0 2px var(--p1); color:var(--textcyan); counter-reset:count; font-size:10px; margin:60px auto 0 auto; text-align:center; user-select:none; width:100%; } .ogl_spyTable > div > div, .ogl_spyTable .ogl_totalSum { align-items:center; display:grid; grid-gap:2px; grid-template-columns:52px 105px 95px auto 65px 65px minmax(127px, min-content); position:relative; } .ogl_spyTable > div:nth-child(1) { text-transform:uppercase; } .ogl_spyTable .ogl_totalSum { border-top:2px solid var(--p1); text-align:right; } .ogl_spyTable > div:nth-child(2) > div { background:var(--p3) !important; border-top:2px solid var(--p1); counter-increment:count 1; height:22px; transition:height .2s; } .ogl_spyTable .ogl_totalSum th:nth-child(3):before { content:counter(count); } .ogl_spyTable th { font-weight:bold; padding:5px; position:relative; } .ogl_spyTable th.ogl_headerActions { display:grid; grid-template-columns:repeat(4, 1fr); padding:3px; } .ogl_spyTable th.ogl_headerActions > div:nth-child(1) { grid-column:-2; } .ogl_spyTable .ogl_headerActions .ogl_button { color:var(--text); font-size:15px !important; } .ogl_spyTable th.ogl_active { color:var(--textpremium); } .ogl_spyTable th[data-filter] { cursor:pointer; } .ogl_spyTable th[data-filter]:hover { color:#fff !important; } .ogl_spyTable th[data-filter]:after { content:'unfold_more'; font-family:'material icons'; font-size:14px; opacity:.5; text-transform:initial; vertical-align:sub; } .ogl_spyTable td { background:var(--p3); box-sizing:border-box; overflow:hidden; padding:5px; position:relative; text-overflow:ellipsis; white-space:nowrap; } .ogl_spyTable .ogl_attacked td { background:hsl(0deg 22% 14%); opacity:.8; } .ogl_spyTable td:not(:first-child) { box-shadow:-2px 0 var(--p2); } .ogl_spyTable a { text-decoration:none; } .ogl_spyTable .ogl_danger, #fleet2 #mission ul li span.ogl_danger { color:var(--red2) !important; } .ogl_spyTable .ogl_warning { color:var(--yellow2) !important; } #fleet2 #mission ul li span.ogl_warning { color:var(--orange0) !important; } .ogl_spyTable a:hover { color:var(--textsand) !important; } .ogl_spyTable .ogl_coords { text-align:left; text-indent:14px; } .ogl_spyTable .ogl_coords .ogl_type { font-size:14px !important; left:-12px; position:absolute; top:4px; vertical-align:middle; } .ogl_spyTable .ogl_inFlight { border-color:transparent red transparent transparent !important; bottom:2px; left:-1px; top:auto !important; transform:scale(.7) rotate(180deg); transform-origin:right; right:auto !important; } .ogl_spyTable .ogl_name a { color:inherit !important; font-weight:bold; } .ogl_spyTable .ogl_name a:hover { color:var(--textsand) !important; } .ogl_spyTable .ogl_renta { padding:0; } .ogl_spyTable .ogl_important, .ogl_spyTable .ogl_important a { color:#fff; } .ogl_spyTable .ogl_renta a { display:block; padding:5px; } .ogl_spyTable .ogl_renta div { font-weight:bold; text-align:right; } .ogl_spyTable .ogl_renta span, .ogl_spyTable .ogl_renta:hover div { display:none; } .ogl_spyTable .ogl_renta:hover span { display:block; font-weight:bold; text-align:right; } .ogl_spyTable .ogl_colorButton { background:var(--p1); border:none; border-radius:20px; cursor:pointer; height:15px; margin:0; overflow:hidden; padding:0; position:absolute; right:2px; top:4px; width:24px; } .ogl_spyTable .ogl_colorDiv .ogl_colorButton { border:none !important; bottom:0 !important; height:100% !important; left:0 !important; right:0 !important; top:0 !important; width:100% !important; } .ogl_spyTable .ogl_reportOptions { align-items:center; display:grid; grid-auto-flow:column; grid-gap:5px; height:22px; justify-content:space-around; padding:0 5px; } .ogl_spyTable aside { background:linear-gradient(to bottom, var(--p3), var(--p1)); border-top:2px solid var(--p1); color:var(--textpremium); display:none; font-weight:bold; grid-gap:0; grid-template-columns:repeat(5, 1fr); padding:5px; } .ogl_spyTable aside.ogl_active { display:grid; } .ogl_spyTable aside ul { padding:5px 0; } .ogl_spyTable aside ul:nth-child(1) { padding-top:25px; } .ogl_spyTable aside ul .ogl_shipIcon { background-position:center; height:20px; margin:auto; } .ogl_spyTable aside ul a { color:#fff; } .ogl_spyTable aside ul a.ogl_disabled { color:#777; pointer-events:none; text-decoration:none; } .ogl_spyTable aside ul > *:not(.ogl_shipIcon) { padding:3px 0; width:100%; } .ogl_reportOptions > * { background:hsl(205deg 26% 22%); border-radius:3px; color:#fff !important; cursor:pointer; font-size:12px; height:16px; line-height:17px !important; user-select:none; text-align:center; text-decoration:none !important; width:16px; } .ogl_reportOptions > *.material-icons { font-size:14px !important; } .ogl_reportOptions > div:hover, .ogl_reportOptions > a:hover { box-shadow:inset 0 0 4px 2px var(--neon); color:#fff !important; } .ogl_spyTable .ogl_expand:before { content:'expand_more'; } .ogl_spyTable .ogl_extended .ogl_expand:before { content:'expand_less'; } .ogl_spyTable .ogl_added { display:block; } .ogl_sim { background:linear-gradient(to top, #1a2027, #2e3948) !important; box-shadow:inset 0 1px 3px #374454; border-radius:5px; color:#9ea5af !important; cursor:pointer; float:left; font-size:16px; font-weight:bold; line-height:26px; text-align:center; } .ogl_sim:hover { background:linear-gradient(to bottom, #1a2027, #2e3948) !important; box-shadow:inset 0 -1px 3px #374454; } .ogl_sim ~ .ogl_sim { margin-left:7px; } #subtabs-nfFleetTrash { width:627px; right:7px; } #subtabs-nfFleetTrash { background-image:none !important; } #subtabs-nfFleetTrash .trash_box { left:0 !important; } #subtabs-nfFleetTrash .btn_trash { width:96px; } #subtabs-nfFleetTrash .ogl_trash { font-size:16px !important; line-height:23px !important; position:absolute; right:98px; top:0; width:40px; } #subtabs-nfFleetTrash .ogl_trash:hover { color:#fff; } #messages .tab_favorites, #messages .tab_inner { background:hsl(210deg 11% 9%) !important; box-shadow:0 0 0 2px var(--p0); border-radius:5px; } #messages .tab_favorites:before, #messages .tab_inner:before { display:none !important; } /* FLEET EVENTS ----------------------------*/ #eventboxContent h2 .ogl_button { background:linear-gradient(to bottom, #405887, #324979) !important; border-radius:5px !important; box-shadow:inset 0 0 0 1px #475a82 !important; color:#fff !important; font-size:16px !important; line-height:16px !important; position:absolute; right:53px; top:5px; } #eventboxContent .eventFleet { box-shadow:inset 0 -1px #0d1014; } #eventboxContent .eventFleet .ogl_timeZone:before, #eventboxContent .eventFleet .ogl_timeZone:after, #eventboxContent .allianceAttack .ogl_timeZone:before, #eventboxContent .allianceAttack .ogl_timeZone:after { font-size:10px !important; } .eventFleet[data-mission-type="1"], .fleetDetails[data-mission-type="1"], .ogl_missionType[data-mission-type="1"] { color:#ea463e !important; } .eventFleet[data-mission-type="2"], .fleetDetails[data-mission-type="2"], .ogl_missionType[data-mission-type="2"] { color:#ff6046 !important; } .eventFleet[data-mission-type="3"], .fleetDetails[data-mission-type="3"], .ogl_missionType[data-mission-type="3"] { color:#7cd157 !important; } .eventFleet[data-mission-type="4"], .fleetDetails[data-mission-type="4"], .ogl_missionType[data-mission-type="4"] { color:#2ADCA3 !important; } .eventFleet[data-mission-type="5"], .fleetDetails[data-mission-type="5"], .ogl_missionType[data-mission-type="5"] { color:#e48d50 !important; } .eventFleet[data-mission-type="6"], .fleetDetails[data-mission-type="6"], .ogl_missionType[data-mission-type="6"] { color:#cabe6e !important; } .eventFleet[data-mission-type="7"], .fleetDetails[data-mission-type="7"], .ogl_missionType[data-mission-type="7"] { color:#62C5DC !important; } .eventFleet[data-mission-type="8"], .fleetDetails[data-mission-type="8"], .ogl_missionType[data-mission-type="8"] { color:#7EBA89 !important; } .eventFleet[data-mission-type="9"], .fleetDetails[data-mission-type="9"], .ogl_missionType[data-mission-type="9"] { color:#fd2e2e !important; } .eventFleet[data-mission-type="10"], .fleetDetails[data-mission-type="10"], .ogl_missionType[data-mission-type="10"] { color:#6f899d !important; } .eventFleet[data-mission-type="15"], .fleetDetails[data-mission-type="15"], .ogl_missionType[data-mission-type="15"] { color:#6d98e2 !important; } .eventFleet[data-mission-type="16"], .fleetDetails[data-mission-type="16"], .ogl_missionType[data-mission-type="16"] { color:#72c4d4 !important; } #eventContent .ogl_loader { margin:30px auto; } #eventContent tbody { outline:1px solid #000; } #eventContent tr, #eventContent .odd, #eventContent .part-even { background:#101920; line-height:22px; } #eventContent tr td { font-size:10px; padding:0; position:relative; text-align:left; vertical-align:middle; } #eventContent tr td * { font-size:inherit !important; } #eventContent tr td *:not(.textBeefy):not(a) { color:inherit; } #eventContent tr td a:not(.icon_link) { background:rgba(0,0,0,.4); border-radius:40px; text-decoration:none; } .sendProbe .icon_link { background:none; } #eventContent tr td figure { margin-right:2px; } #eventContent tr .icon_movement, #eventContent tr .icon_movement_reserve { background-position-y:center; height:100%; padding:0; } #eventContent tr .icon_movement span, #eventContent tr .icon_movement_reserve span { left:0; position:absolute; top:0; } .detailsFleet { width:auto !important; } .eventFleet[data-return-flight="true"] { box-shadow:inset 0 150px 0 rgba(0,0,0,.5); } #eventContent td a:hover { color:#73a7c5; } #eventContent tr[data-return-flight="true"] td { opacity:.5; } #eventContent .originFleet span, #eventContent .destFleet span { pointer-events:none !important; display:block !important; overflow:visible; width:auto; } #eventContent .originFleet span:after, #eventContent .destFleet span:after { content:attr(title); font-size:10px; overflow:hidden; text-align:center; text-overflow:ellipsis; vertical-align:middle; } .eventFleet .countDown, .eventFleet .arrivalTime { text-align:left; text-indent:5px; } #eventContent .countDown { text-align:left; text-indent:5px; text-shadow:1px 1px #000; } #eventboxContent .eventFleet, #eventboxContent .allianceAttack { align-items:center; display:grid; grid-gap:2px; grid-template-columns:85px 72px 23px 95px 70px auto 16px 95px 70px 20px 20px 20px; grid-template-columns:85px 72px 23px 97px 69px auto 19px 87px 70px 20px 21px 20px; white-space:nowrap; } #eventboxContent .eventFleet td:not(.icon_movement):not(.icon_movement_reserve) { overflow:hidden; text-overflow:ellipsis; } .eventFleet .missionFleet img { position:relative; top:2px; vertical-align:top !important; } .fleetDetails.detailsOpened { height:auto !important; } #movement .fleetDetails { background:var(--p3); border:2px solid #09161e; border-radius:4px; } #movement .fleetDetails > *:not(.ogl_topLine):not(.ogl_shipDetail):not(.ogl_actions) { display:none !important; } #movement .fleetDetails[data-return-flight="1"] { background:var(--p2); } #movement .fleetDetails[data-return-flight="1"] > div { opacity:.5; } #movement .fleetDetails .ogl_shipIcon[class*="ogl_mission"] { border-radius:5px !important; height:34px !important; } #movement .fleetDetails .ogl_topLine { color:#fff; display:grid; grid-template-columns:80px 60px 66px 112px 16px 112px 66px 60px 80px; padding:2px; } #movement .fleetDetails .ogl_topLine > *:first-child { display:none; } #movement .fleetDetails.detailsClosed .ogl_topLine { grid-template-columns:18px 80px 60px 66px 103px 16px 103px 66px 60px 80px; } #movement .fleetDetails.detailsClosed .ogl_topLine > *:first-child { display:block; } #movement .fleetDetails .ogl_topLine * { bottom:auto !important; font-size:10px !important; height:24px !important; left:auto !important; margin:0 !important; position:relative !important; right:auto !important; top:auto !important; width:100% !important; } #movement .fleetDetails .ogl_topLine *:not(.ogl_shipIcon) { background-position:center !important; } #movement .fleetDetails .ogl_topLine .ogl_timeZone { font-size:0 !important; } #movement .fleetDetails .ogl_topLine .ogl_timeZone:after { font-size:10px !important; } #movement .fleetDetails .ogl_topLine > * { background:#1c2736; box-sizing:border-box; padding:0 2px; overflow:hidden; text-align:center; text-overflow:ellipsis; white-space:nowrap; } /*#movement .fleetDetails .ogl_topLine > .ogl_active:after { background:currentColor; content:''; height:100%; left:0; opacity:.2; position:absolute; top:0; width:100%; }*/ #movement .fleetDetails .ogl_topLine figure { margin-right:5px !important; width:16px !important; } #movement .fleetDetails .ogl_shipDetail { box-sizing:border-box; color:#ababab; display:grid; grid-gap:3px; grid-template-columns:repeat(19, 1fr); padding:2px; width:100%; } #movement .fleetDetails .ogl_shipDetail .ogl_movementItem { background:#1c2736; border-radius:3px; line-height:14px; text-align:center; } #movement .fleetDetails .ogl_shipDetail .ogl_movementItem:nth-child(5) { /*visibility:hidden;*/ } #movement .fleetDetails .ogl_shipDetail .ogl_shipIcon { border:none; border-radius:3px; box-shadow:none; display:inline-block; height:17px; width:100%; } #movement .fleetDetails .ogl_actions { background:#1c2736; direction:rtl; height:16px; margin:0 2px; overflow:hidden; } #movement .fleetDetails .ogl_actions * { bottom:auto !important; font-size:10px !important; left:auto !important; line-height:16px !important; margin:0 !important; position:relative !important; right:auto !important; text-align:center; top:auto !important; } #movement .fleetDetails .ogl_actions > * { direction:ltr; display:inline-block; height:16px !important; margin-left:5px !important; } #movement .fleetDetails .ogl_actions .ogl_backTime { width:140px; } #movement .fleetDetails .ogl_actions .ogl_agsName { width:70px; } #movement .fleetDetails .ogl_actions .ogl_agsName > * { padding:0 !important; position:absolute !important; right:0 !important; } #movement .fleetDetails .ogl_actions .ogl_timeZone { background:#1c2736; border-radius:3px; height:16px; position:absolute !important; right:0 !important; text-indent:2px; } #movement .fleetDetails .mission { color:inherit !important; display:block; height:16px; line-height:12px !important; } #movement .fleetDetails .mission:before { background:currentColor; border-radius:3px; content:''; display:block; height:16px; left:0; opacity:.2; position:absolute; top:0; width:100%; } #movement .fleetDetails.detailsClosed { height:auto !important; } #movement .fleetDetails.detailsClosed .absTime { visibility:visible; } #movement .fleetDetails.detailsClosed .ogl_shipDetail { display:none; } #movement .fleetDetails.detailsClosed .ogl_shipDetail >*:not(:first-child) { display:none; } #movement .fleetDetails .ogl_timeZone:before, #movement .fleetDetails .ogl_timeZone:after { font-size:10px !important; } #movement .fleetDetails .ogl_topLine .ogl_shipIcon[class*="ogl_mission"] { border:none !important; height:32px !important; top:4px !important; transform:scale(.5); transform-origin:top left; width:32px !important; } #movement .originPlanet .honorRank, #movement .destinationPlanet .honorRank { display:none; } /* .detailsOpened .ogl_backTimer { background:#232f3a !important; border-radius:2px !important; right:205px !important; line-height:16px !important; padding:0 9px !important; position:absolute !important; top:3px !important; } .ogl_backTimer:before, .ogl_backTimer:after { font-size:10px !important; vertical-align:middle !important; } .detailsOpened .marker01, .detailsOpened .marker02 { visibility:hidden !important; } .ogl_shipDetail { color:hsl(214deg 10% 68%); display:grid; grid-gap:2px; grid-template-columns:repeat(21, 1fr); height:18px; pointer-events:none; position:absolute; left:85px; text-align:center; top:25px; white-space:nowrap; } .ogl_shipDetail > div { display:grid; } .ogl_shipDetail .ogl_shipIcon { border:none; border-radius:4px 4px 0 0; box-shadow:none; display:inline-block; height:24px; image-rendering:-webkit-optimize-contrast; margin:auto; position:relative; width:24px; z-index:-1; } .ogl_shipDetail span { background:hsl(210deg 29% 8%); border-radius:2px; line-height:14px; margin-top:-6px; font-weight:bold; font-size:9px; } .fleetDetails.detailsOpened { border-radius:4px; height:59px !important; } .detailsOpened .timer { font-size:10px !important; font-weight:bold !important; left:7px !important; top:23px !important; width:auto !important; } .detailsClosed .timer { top:-4px !important; } .detailsOpened .absTime { left:7px !important; top:36px !important; } .detailsClosed .absTime { left:6px !important; position:absolute !important; top:10px !important; visibility:visible !important; } .detailsOpened .nextTimer { font-size:10px !important; font-weight:bold !important; left:auto !important; right:7px !important; top:24px !important; width:auto !important; } .detailsOpened .nextabsTime { left:auto !important; right:7px !important; top:40px !important; width:auto !important; } .detailsOpened .nextabsTime:after { font-size:10px !important; } .detailsOpened .allianceName { top:45px; } .detailsClosed .nextTimer, .detailsClosed .nextabsTime, .detailsClosed .nextMission, .detailsClosed .ogl_fulldate { display:none !important; } .detailsClosed .fleetDetailButton { display:none !important; } .detailsClosed .reversal { top:2px !important; } .detailsClosed .starStreak .route > a { background:none !important; left:326px !important; margin:0 !important; top:-3px !important; } .detailsOpened .originData { left:107px !important; text-align:right !important; } .detailsOpened .destinationData { left:470px !important; text-align:left !important; } .fleetDetails { background:hsl(210deg 29% 11%) !important; border:2px solid var(--p0) !important; box-shadow:inset 0 23px var(--p2) !important; margin:12px 5px 0 5px !important; } .fleetDetails.detailsOpened .mission { border-radius:2px !important; color:inherit !important; display:inline-block !important; left:7px !important; padding:1px 10px !important; top:3px !important; width:92px !important; } .fleetDetails .mission { color:inherit !important; } .fleetDetails .mission:before { background:currentColor; content:''; display:block; height:100%; left:0; opacity:.2; position:absolute; top:0; width:100%; } .detailsOpened .nextMission, #movementcomponent .starStreak .origin, #movementcomponent .starStreak .destination { display:none !important; } .detailsOpened .starStreak { background:none !important; border:none !important; overflow:initial !important; } .detailsOpened .reversal { left:auto !important; right:338px !important; top:1px !important; z-index:2 !important; } .detailsOpened .fedAttack { left:auto !important; right:43px !important; top:1px !important; } .detailsOpened .sendMail { left:auto !important; right:22px !important; top:1px !important; } .detailsOpened .originData, .detailsOpened .destinationData { color:#fff !important; width:168px !important; } .detailsOpened .originPlanet, .detailsOpened .destinationPlanet { display:inline-block !important; position:relative !important; top:auto !important; left:auto !important; max-width:100px !important; right:auto !important; vertical-align:middle !important; width:auto !important; } .detailsOpened .destinationPlanet { max-width:60px !important; } .detailsOpened .absTime:after { font-size:10px !important; } .detailsClosed .mission { border-radius:4px; height:20px; line-height:17px; text-align:center; } #movementcomponent .detailsOpened .starStreak .route a { background:none !important; left:103px !important; margin-left:0 !important; margin-top:5px !important; position:absolute !important; top:-33px !important; transform:scaleX(1) !important; transform-origin:right !important; } #movementcomponent .detailsOpened .starStreak .route a.fleet_icon_forward { transform:scaleX(-1) !important; transform-origin:right !important; }*/ #highscoreContent div.content table#ranks tbody tr td { height:22px; } #highscoreContent div.content table#ranks tbody tr:nth-child(odd) td { background:hsl(214deg 27% 10%) !important; } #highscoreContent div.content table#ranks tbody tr:nth-child(even) td { background:hsl(212deg 26% 8%) !important; } #highscoreContent div.content table#ranks tbody tr.buddyrank td { background:hsl(258deg 33% 16%) !important; } #highscoreContent div.content table#ranks tbody tr.allyrank td { background:hsl(177deg 33% 16%) !important; } #highscoreContent div.content table#ranks tbody tr.myrank td { background:hsl(212deg 29% 26%) !important; } #highscoreContent .honorRank { position:absolute; } #highscoreContent .honorScore { pointer-events:none; } #highscoreContent .playername { color:#eee; display:inline-block; font-weight:bold; overflow:hidden; position:relative; text-overflow:ellipsis; text-indent:21px; vertical-align:bottom; white-space:nowrap; } #highscoreContent .playername:hover { text-decoration:underline; } #highscoreContent a { position:relative; } #highscoreContent .ally-tag { float:right; font-weight:bold; } #highscoreContent .ally-tag > a { color:hsl(213deg 22% 56%) !important; } #highscoreContent .honorScore { display:none !important; font-size:0 !important; left:20px; position:absolute; top:6px; } #highscoreContent .honorScore span, #highscoreContent .stats_counter { font-size:9px !important; font-weight:bold; } #highscoreContent #ranks tbody .score { color:hsl(208deg 17% 47%) !important; font-size:11px; padding:2px 4px; position:relative; vertical-align:top; } #highscoreContent #ranks tbody .score .ogl_scoreDiff { bottom:0; font-size:10px; position:absolute; right:4px; } #highscoreContent #ranks tbody .score .small { color:hsl(210deg 11% 57%); font-size:10px; font-weight:bold; } .ogl_inFlightTable hr { grid-column:1 / -1; } .ogl_missionList [data-mission-type] { border:2px solid var(--p2); border-radius:4px; display:inline-block; height:34px; margin-right:2px; position:relative; width:17px; } .ogl_missionList [data-mission-occurence]:after { background:var(--p2); bottom:0; color:#fff; content:attr(data-mission-occurence); dispay:block; height:17px; line-height:17px; position:absolute; right:0; text-align:center; width:17px; } .ogl_missionList [data-mission-type="1"] { background:url(https://gf1.geo.gfsrv.net/cdn9a/cd360bccfc35b10966323c56ca8aac.gif); } .ogl_missionList [data-mission-type="3"] { background:url(https://gf1.geo.gfsrv.net/cdn38/2af2939219d8227a11a50ff4df7b51.gif); } .ogl_missionList [data-mission-type="4"] { background:url(https://gf3.geo.gfsrv.net/cdnb0/4dab966bded2d26f89992b2c6feb4c.gif); } .ogl_missionList [data-mission-type="7"] { background:url(https://gf3.geo.gfsrv.net/cdn8a/0bbcbc3a6d6b102c979413d82bac47.gif); } .ogl_missionList [data-mission-type="8"] { background:url(https://gf1.geo.gfsrv.net/cdn08/26dd1bcab4f77fe67aa47846b3b375.gif); } .ogl_missionList [data-mission-type="15"] { background:url(https://gf1.geo.gfsrv.net/cdnf7/892b08269e0e0bbde60b090099f547.gif); } .ogl_ptreLogs, .ogl_logs { background:var(--p2); border:1px solid #000; border-radius:4px; overflow:auto; margin:0 auto 50px auto; padding:10px 0; position:relative; text-indent:10px; width:654px; } .ogl_logs { color:#e96e6e; } .ogl_logs h3 { color:grey; margin-bottom:5px; } .ogl_logs u { color:#aaa; text-decoration:none; } .ogl_ptreLogs h3 { color:grey; margin-bottom:5px; } .ogl_ptreLogs div { font-size:12px; margin:3px 0; opacity:.5; } .ogl_ptreLogs div:last-child { opacity:1; } .ogl_ptreLogs div > span { color:var(--textdate); } .ogl_ptreLogs div > b { color:#b1a465; } .ogl_leftMenuIcon { background:linear-gradient(to bottom, #1b2024 50%, #000 50%); border-radius:4px; display:block; height:27px; margin-right:11px; user-select:none; text-align:center; width:27px !important; } .ogl_leftMenuIcon a { color:#353a3c !important; } .ogl_leftMenuIcon a:hover, .ogl_leftMenuIcon svg:hover { color:#d39343 !important; fill:#d39343 !important; } .ogl_leftMenuIcon a .ogl_danger { color:#a74545 !important; } .ogl_leftMenuIcon a, .ogl_leftMenuIcon a i { display:block; height:100%; width:100%; } .ogl_leftMenuIcon .material-icons { font-size:20px !important; line-height:27px !important; } .information .required_population { position:relative; top:15px; } div.alert_triangle { top:55px !important; } .ogl_share { background: var(--p3); border-radius:0 0 3px 3px; border-top:3px solid; border-image:var(--uigradient) 1; box-shadow:0 0 16px 2px #000; padding:20px; } /*!css*/ `; GM_addStyle(oglcss); // #endregion // ogl // #region class OGLight { constructor(cache) { //if(!document.body) document.location.reload(); //document.body.classList.add('ogl_noPointer'); if(document.querySelector('#fleet1 .allornonewrap .secondcol')) { document.querySelector('#fleet1 .allornonewrap .secondcol').prepend(document.querySelector('#fleet1 .show_fleet_apikey')); document.querySelector('#fleetboxbriefingandresources form').prepend(document.querySelector('#fleetboxmission #missions')); } if(redirect && redirect.indexOf('https') > -1) return; this.performances = [['Initial',performance.now()]]; this.mode = new URLSearchParams(window.location.search).get('ogl_mode') || 0; // 1:collect 2:raid 3:locked 4:linked this.page = new URL(window.location.href).searchParams.get('component') || new URL(window.location.href).searchParams.get('page'); this.id = GM_getValue('ogl_id') || false; this.ptre = localStorage.getItem('ogl-ptreTK') || false; this.ptre = (this.ptre && this.ptre.indexOf('false') > -1) ? false : this.ptre; this.version = GM_info.script.version.indexOf('b') > -1 ? 'beta' : 'v'+GM_info.script.version; this.ogameVersion = document.querySelector('meta[name="ogame-version"]').getAttribute('content'); this.updateQueue = []; this.observerQueue = {}; this.mutationList = {}; this.observerExcludedID = ['tempcounter', 'resources_metal', 'resources_crystal', 'resources_deuterium', 'resources_darkmatter', 'resources_energy', 'promotionCountdown']; this.observerExcludedClass = ['OGameClock', 'textBeefy', 'ogl_endTime', 'planetlink', 'moonlink', 'ogl_stock', 'ogl_resourcesSum', 'ogl_panel', 'ogl_metal', , 'ogl_crystal', 'ogl_deut', 'ogl_stats', 'ogl_menuOptions']; this.maxPinnedTargets = 30; this.observerTimers = []; this.galaxyLoaded = false; this.observer = new MutationObserver(mutations => { (() => { let now = performance.now(); for(let i=0, len=mutations.length; i<len; i++) { let mutation = mutations[i]; if(this.observerExcludedID.indexOf(mutation.target.id) > -1) return; if(mutation.target.className.trim().split(' ').filter(e => this.observerExcludedClass.includes(e)).length > 0) return; /*if(mutation.target.id && mutation.target.id != "") console.log('#'+mutation.target.id+': '+(performance.now()-this.perf)); else if(mutation.target.className && mutation.target.className != "") console.log('.'+mutation.target.className+': '+(performance.now()-this.perf)); else console.log(mutation.target.outerHTML+': '+(performance.now()-this.perf));*/ if(this.page == 'galaxy' && (mutation.target.classList.contains('microplanet') || mutation.target.classList.contains('planetMoveIcons') || mutation.target.id == 'amountColonized') && !this.galaxyLoaded && document.querySelector('#galaxyLoading').style.display.trim() != '') { this.galaxyLoaded = true; this.galaxyCoords = [galaxy, system]; this.mutationList['crawler'] = now; this.mutationList['galaxy'] = now; } else if(mutation.target.id == 'stat_list_content') { this.mutationList['crawler'] = now; this.mutationList['highscore'] = now; } else if(mutation.target.classList.contains('ui-tabs-panel')) { this.mutationList['messagesdate'] = now; this.mutationList['tablereport'] = now; } else if(mutation.target.id == 'technologydetails_content') { this.mutationList['details'] = now; } else if(mutation.target.classList.contains('ui-dialog-content')) { let dialogType = mutation.target.getAttribute('data-page'); if(dialogType == 'jumpgatelayer') this.mutationList['jumpgate'] = now; else if(dialogType == 'phalanx') this.mutationList['tooltip'] = now; else if(dialogType == 'messages') this.mutationList['simbutton'] = now; } else if(mutation.target.id == 'eventboxContent') { this.mutationList['eventbox'] = now; } else if(mutation.target.className.indexOf('tooltip') && !mutation.target.classList.contains('ogl_tooltipReady')) { this.mutationList['tooltip'] = now; } /*else if(this.observerQueue['tooltip']) { this.mutationList['tooltip'] = now; }*/ } })(); if(Object.keys(this.mutationList).length > 0) tryUpdate(); }); let tryUpdate = () => { Object.keys(this.mutationList).forEach(k => { if(typeof this.observerQueue[k] === 'function') this.observerQueue[k](); delete this.mutationList[k]; }); } // fix resources tooltips if(!document.querySelector('#metal_box')?.getAttribute('title') && this.mode != 1 && this.mode != 4) getAjaxResourcebox(); this.loop(); window.addEventListener('beforeunload', () => this.save()); this.observer.observe(document.documentElement, {childList:true, subtree:true, attributes:true}); // player data this.account = {}; this.account.id = document.querySelector('head meta[name="ogame-player-id"]').getAttribute('content'); this.account.name = document.querySelector('head meta[name="ogame-player-name"]').getAttribute('content'); this.account.rank = document.querySelector('#bar a[href*="page=highscore"').parentNode.textContent.match(/\d+/g)[0]; this.account.planetCount = document.querySelector('#countColonies span').textContent.match(/\d+/g)[0]; this.account.planetMax = document.querySelector('#countColonies span').textContent.match(/\d+/g)[1]; this.account.class = document.querySelector('#characterclass .sprite').classList.contains('miner') ? 1 : document.querySelector('#characterclass .sprite').classList.contains('warrior') ? 2 : 3; this.account.totalResources = [0,0,0]; this.account.totalProd = [0,0,0]; this.account.planetsCount = document.querySelector('#countColonies .textCenter span').textContent; // universe data this.universe = {}; this.universe.ecoSpeed = document.querySelector('head meta[name="ogame-universe-speed"]').getAttribute('content'); this.universe.fleetSpeedHolding = document.querySelector('head meta[name="ogame-universe-speed-fleet-holding"]').getAttribute('content'); this.universe.fleetSpeedWar = document.querySelector('head meta[name="ogame-universe-speed-fleet-war"]').getAttribute('content'); this.universe.fleetSpeedPeaceful = document.querySelector('head meta[name="ogame-universe-speed-fleet-peaceful"]').getAttribute('content'); this.universe.name = document.querySelector('head meta[name="ogame-universe-name"]').getAttribute('content'); this.universe.number = window.location.host.replace(/\D/g,''); this.universe.lang = document.querySelector('head meta[name="ogame-language"]').getAttribute('content'); this.universe.timestamp = document.querySelector('head meta[name="ogame-timestamp"]').getAttribute('content') * 1000; // current planet data this.current = {}; this.current.smallplanet = document.querySelector('.smallplanet.hightlightPlanet') || document.querySelector('.smallplanet.hightlightMoon') || document.querySelector('.smallplanet'); this.current.type = document.querySelector('head meta[name="ogame-planet-type"]').getAttribute('content'); this.current.coords = this.current.smallplanet.querySelector('.planetlink .planet-koords').textContent.slice(1,-1).split(':'); this.current.id = document.querySelector('head meta[name="ogame-planet-id"]').getAttribute('content'); this.current.metal = Math.floor(resourcesBar.resources.metal.amount); this.current.crystal = Math.floor(resourcesBar.resources.crystal.amount); this.current.deut = Math.floor(resourcesBar.resources.deuterium.amount); this.current.energy = Math.floor(resourcesBar.resources.energy.amount); this.current.food = Math.floor(resourcesBar.resources.food?.amount || 0); this.current.population = Math.floor(resourcesBar.resources.population?.amount || 0); this.cache = cache || {}; this.next = {}; this.next.smallplanet = this.current.smallplanet.nextElementSibling || document.querySelectorAll('.smallplanet')[0]; this.prev = {}; this.prev.smallplanet = this.current.smallplanet.previousElementSibling || document.querySelectorAll('.smallplanet')[document.querySelectorAll('.smallplanet').length - 1]; if(document.querySelector('.moonlink')) { if(document.querySelectorAll('.moonlink').length > 1) { this.next.smallplanetWithMoon = this.next.smallplanet; if(!this.next.smallplanetWithMoon.querySelector('.moonlink')) { do this.next.smallplanetWithMoon = this.next.smallplanetWithMoon.nextElementSibling || document.querySelectorAll('.moonlink')[0].parentNode; while(!this.next.smallplanetWithMoon.querySelector('.moonlink')); } this.prev.smallplanetWithMoon = this.prev.smallplanet; if(!this.prev.smallplanetWithMoon.querySelector('.moonlink')) { do this.prev.smallplanetWithMoon = this.prev.smallplanetWithMoon.previousElementSibling || document.querySelectorAll('.moonlink')[document.querySelectorAll('.moonlink').length - 1].parentNode; while(!this.prev.smallplanetWithMoon.querySelector('.moonlink')); } } else { this.next.smallplanetWithMoon = this.current.smallplanet; this.prev.smallplanetWithMoon = this.current.smallplanet; } } let universeInfo = `<div> <ul> <li>Economy : ${this.universe.ecoSpeed}</li> <li>Peaceful fleets : ${this.universe.fleetSpeedPeaceful}</li> <li>War fleets : ${this.universe.fleetSpeedWar}</li> <li>Holding fleets : ${this.universe.fleetSpeedHolding}</li> </ul> </div>`; (document.querySelector('#pageReloader') || document.querySelector('#logoLink')).classList.add('tooltipBottom'); (document.querySelector('#pageReloader') || document.querySelector('#logoLink')).setAttribute('title', universeInfo); document.querySelector('#pageContent').appendChild(Util.createDom('div', {'class':'ogl_universeName'}, `${this.universe.name}.${this.universe.lang}`)); document.querySelector('#bar ul').appendChild(Util.createDom('li', {'class':'ogl_planetsCount'}, `${this.account.planetsCount}<span class="material-icons">language</span>`)); this.ptreIcon = ` <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg class="ogl_ptreIcon" width="100%" height="100%" viewBox="0 0 280 290" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"> <g transform="matrix(1,0,0,1,-1101.56,-1607.07)"> <path d="M1262.77,1770.22C1262.48,1770.26 1262.18,1770.28 1261.87,1770.28C1258.35,1770.28 1255.49,1767.42 1255.49,1763.9C1255.49,1760.37 1258.35,1757.51 1261.87,1757.51C1262.02,1757.51 1262.17,1757.52 1262.32,1757.53L1262.32,1757.52L1286.56,1757.52C1286.56,1757.52 1286.56,1757.52 1286.56,1757.51L1320.4,1757.51L1320.42,1757.52L1322.46,1757.52C1322.53,1757.52 1322.61,1757.52 1322.68,1757.52C1326.2,1757.52 1329.06,1760.38 1329.06,1763.9C1329.06,1764.05 1329.06,1764.19 1329.05,1764.33C1328.84,1775.83 1319.09,1785.49 1307.19,1785.49C1297.26,1785.49 1288.87,1779.03 1286.24,1770.22L1262.77,1770.22ZM1159.8,1770.02C1159.51,1770.06 1159.21,1770.08 1158.9,1770.08C1155.38,1770.08 1152.52,1767.22 1152.52,1763.69C1152.52,1760.17 1155.38,1757.31 1158.9,1757.31C1159.05,1757.31 1159.2,1757.31 1159.34,1757.32L1159.34,1757.32L1183.59,1757.32C1183.59,1757.31 1183.59,1757.31 1183.59,1757.31L1217.43,1757.31L1217.45,1757.32L1219.49,1757.32C1219.56,1757.31 1219.63,1757.31 1219.7,1757.31C1223.23,1757.31 1226.09,1760.17 1226.09,1763.69C1226.09,1763.84 1226.08,1763.99 1226.07,1764.13C1225.87,1775.63 1216.11,1785.28 1204.21,1785.28C1194.28,1785.28 1185.89,1778.83 1183.27,1770.02L1159.8,1770.02ZM1118.14,1732.74C1117.85,1732.78 1117.55,1732.8 1117.24,1732.8C1113.72,1732.8 1110.86,1729.94 1110.86,1726.42C1110.86,1722.89 1113.72,1720.03 1117.24,1720.03C1117.39,1720.03 1117.54,1720.04 1117.68,1720.05L1117.68,1720.04L1147.5,1720.04L1180.12,1607.07L1240.55,1647.87L1302.84,1622.64L1339.85,1720.04L1363.42,1720.04C1363.74,1719.99 1364.06,1719.97 1364.38,1719.97C1367.9,1719.97 1370.77,1722.83 1370.77,1726.36C1370.77,1729.88 1367.9,1732.74 1364.38,1732.74C1364.35,1732.74 1364.32,1732.74 1364.3,1732.74L1364.3,1732.74L1118.14,1732.74ZM1101.56,1896.65L1101.56,1792.25L1240.99,1833.55L1381.11,1792.88L1381.11,1896.72L1101.56,1896.65Z"/> </g> </svg> `; // ogl database this.DBName = `ogl_test_${this.universe.number}-${this.universe.lang}_${this.account.id}`; //this.db = this.DBName == localStorage.getItem('ogl_lastKeyUsed') && ogldb ? ogldb : JSON.parse(GM_getValue(this.DBName) || '{}'); this.db = JSON.parse(GM_getValue(this.DBName) || '{}'); this.db.players = this.db.players || []; this.db.positions = this.db.positions || []; this.db.stats = this.db.stats || { total:{} }; this.db.loca = this.db.loca || {}; this.db.ships = this.db.ships || {}; this.db.me = this.db.me || {}; this.db.me.techs = this.db.me.techs || {}; this.db.me.planets = this.db.me.planets || {}; this.db.myActivities = this.db.myActivities || {}; this.db.pinnedList = this.db.pinnedList || []; this.db.spyProbesCount = this.db.spyProbesCount || 6; this.db.topScore = this.db.topScore || [0, 0]; this.db.checkedSystems = this.db.checkedSystems || []; this.db.lastEmpireUpdate = this.db.lastEmpireUpdate || 0; this.db.lastVersionCheck = this.db.lastVersionCheck || 0; this.db.newVersion = this.db.newVersion || 0; this.db.servertTimezone = this.db.servertTimezone || 0; this.db.clientTimezone = this.db.clientTimezone || 0; if(!this.db.ships?.[202] && this.page != 'fleetdispatch') { window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch`; return; } this.db.options = this.db.options || {}; this.db.options.rval = this.db.options.rval || 300000 * this.universe.ecoSpeed; this.db.options.defaultShip = this.db.options.defaultShip || 202; this.db.options.defaultMission = this.db.options.defaultMission || 3; this.db.options.resSaver = this.db.options.resSaver || [0,0,0,0]; this.db.options.spyFilter = this.db.options.spyFilter || '$'; this.db.options.togglesOff = this.db.options.togglesOff || ['autoclean', 'fleetDetailsName', 'bigShip', 'rightMenuTooltips', 'ignoreExpeShips']; this.db.options.excludedColors = this.db.options.excludedColors || []; this.db.options.targetFilter = this.db.options.targetFilter || []; this.db.options.dateFilter = this.db.options.dateFilter || 7; this.db.options.tooltipDelay = this.db.options.tooltipDelay || 600; this.current.techs = this.db.me.planets[this.current.coords.join(':')]?.techs || {}; this.checkTopScore(); this.betterInputs(); this.db.checkedSystems = Array.from(new Set(this.db.checkedSystems)); // update old player positions if(!this.db.dataFormat || this.db.dataFormat < 4) { let oldDB = JSON.parse(localStorage.getItem('ogl_redata') || '{}'); if(oldDB.stalkList) { if(confirm('Do you want to import your V3 targets ?')) { for(let v of Object.values(oldDB.stalkList)) { let newObj = {}; newObj.id = v.id; newObj.playerID = v.player; newObj.coords = v.coords; newObj.rawCoords = v.coords.split(':').map(x => x.padStart(3, '0')).join(''); newObj.moonID = v.moonID || -1; newObj.color = v.color; if(v.color && v.id == -1) { newObj.id = -2; newObj.playerID = -2; } let entryID = this.find(this.db.positions, 'coords', v.coords)[0] ?? this.db.positions.length; this.db.positions[entryID] = {...this.db.positions[entryID], ...newObj}; } } this.db.dataFormat = 4; } else this.db.dataFormat = 4; //this.saveAsync(); } // clear old empty player positions if(this.db.dataFormat < 5) { let tmpDB = []; this.db.positions.forEach(e => { if(e.id != '-1') tmpDB.push(e); }); this.db.positions = tmpDB; this.db.dataFormat = 5; } // clear badly formatted PTRE key if(this.db.dataFormat < 6) { if(this.ptre && (this.ptre.replace(/-/g, '').length != 18 || this.ptre.indexOf('TM') != 0)) { localStorage.removeItem('ogl-ptreTK'); } this.db.dataFormat = 6; } // generate a new id if(!this.id || !this.id[0]) { let uuid = [crypto.randomUUID(), 0]; GM_setValue('ogl_id', uuid); this.id == uuid; } // check OGL version this.checkVersion(); // ogl components this.component = {}; this.component.lang = new LangManager(this); this.component.popup = new PopupManager(this); this.component.crawler = new CrawlerManager(this); this.component.galaxy = new GalaxyManager(this); this.component.highscore = new HighscoreManager(this); this.component.fleet = new FleetManager(this); this.component.keyboard = new KeyboardManager(this); this.component.sidebar = new SidebarManager(this); this.component.tooltip = new TooltipManager(this); this.component.color = new ColorManager(this); this.component.time = new TimeManager(this); this.component.message = new MessageManager(this); this.component.jumpgate = new JumpgateManager(this); this.component.empire = new EmpireManager(this); this.component.menu = new MenuManager(this); if(this.page == 'galaxy' && !this.galaxyLoaded) { document.querySelector('#amountColonized').textContent = document.querySelector('#amountColonized').textContent; } this.performances.push(['Loaded',performance.now()]); this.displayPerformances(); } delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } findRaw(table, key, value) { const result = []; const isValid = e => typeof e[key] !== typeof undefined && e[key].toString().toLowerCase() === value.toString().toLowerCase(); for(let i=0; i<table.length; i++) { let item = table[i]; if(isValid(item)) result.push(item); } result.sort((a, b) => a.rawCoords - b.rawCoords) return result; } find(table, key, value, multipleResult) { const result = []; const tmp = []; const lowerValue = value.toString().toLowerCase(); const typeUndefined = typeof undefined; let isValid; if(key == 'coords' || key == 'rawCoords') isValid = e => e[key] === value; else isValid = e => typeof e[key] !== typeUndefined && e[key].toString().toLowerCase() === lowerValue; if(multipleResult) { for(let i=0, len=table.length; i<len; i++) { let item = table[i]; if(isValid(item)) { tmp.push(item); } } tmp.sort((a, b) => a.rawCoords - b.rawCoords).forEach(entry => { let index = table.indexOf(entry).toString(); result.push(index); }); } else { let index = table.findIndex(isValid); if(!isNaN(index) && index > -1) result.push(index); } return result; } getPositionsByCoords(sliced) { let table = this.db.positions; let result = {}; const isValid = e => e.color && e.color != 'none' && this.db.options.excludedColors.indexOf(e.color) == -1; for(let i=0, len=table.length; i<len; i++) { let item = table[i]; let id = sliced ? item.rawCoords.slice(0, -3) : item.rawCoords; if(isValid(item)) { if(!result[id]) result[id] = []; result[id].push(item); } } return result; } getPositionsByPlayerId(id) { let table = this.db.positions; let result = {}; const isValid = e => typeof e.playerID !== typeof undefined && e.playerID == id; for(let i=0, len=table.length; i<len; i++) { let item = table[i]; let id = item.playerID; if(isValid(item)) { if(!result[id]) result[id] = []; result[id].push(item); } } return result; } getPlayersById() { let table = this.db.players; let result = {}; for(let i=0, len=table.length; i<len; i++) { result[table[i].id] = table[i]; } return result; } findTargets(table, key, min, max) { const result = []; const tmp = []; let isValid; isValid = e => e.color && e.color != 'none' && parseInt(e[key]) >= parseInt(min) && parseInt(e[key]) <= parseInt(max) && this.db.options.excludedColors.indexOf(e.color) == -1; for(let i=0, len=table.length; i<len; i++) { let item = table[i]; if(isValid(item)) { tmp.push(item); } } tmp.sort((a, b) => a.rawCoords - b.rawCoords).forEach(entry => { let index = table.indexOf(entry).toString(); result.push(index); }); return result; } saveObj(table, entry, newEntry) { let index = table.indexOf(entry).toString() ?? table.length; table[index] = {...table[index], ...newEntry}; } observeMutation(callback, id) { this.observerQueue[id] = callback; } addToUpdateQueue(callback) { this.updateQueue.push(callback); } async loop() { setInterval(() => this.updateQueue.forEach(callback => callback()), 400); } betterInputs() { setInterval(() => { document.querySelectorAll('.ogl_input:not(.ogl_inputReady)').forEach(input => { input.classList.add('ogl_inputReady'); input.addEventListener('input', () => { setTimeout(() => input.dispatchEvent(new Event('change')), 10); }); input.addEventListener('change', () => { if(input.value) { let newValue = parseInt(input.value.toLowerCase().replace(/[\,\. ]/g, '').replace('g', '000000000').replace('m', '000000').replace('k', '000')); input.value = isNaN(newValue) || newValue <= 0 ? 0 : newValue.toLocaleString('de-DE'); } }); setTimeout(() => input.dispatchEvent(new Event('change')), 10); }); }, 300); } save(data) { if(data && typeof data === 'object') this.db = data; GM_saveTab([this.cache]); GM_setValue(this.DBName, JSON.stringify(this.db)); unsafeWindow.ogl = null; } saveAsync(data) { setTimeout(() => this.save(data)); } checkVersion() { let leftMenu = document.querySelector('#menuTable').appendChild(Util.createDom('li', {}, ` <span class="menu_icon ogl_leftMenuIcon"> <a class="tooltipRight" data-title="Buy me a coffee <3" href="https://ko-fi.com/oglight" target="_blank"><i class="material-icons">local_cafe</i></a> </span> <a class="menubutton tooltipRight" href="https://board.fr.ogame.gameforge.com/index.php?thread/722955-oglight/" target="_blank"> <span class="textlabel">OGLight ${this.version}</span> </a> `)); if(this.ptre) { let link = this.universe.lang == 'fr' ? `https://board.fr.ogame.gameforge.com/index.php?thread/740025-paye-ton-re-ptre-int%C3%A9gration-oglight/` : `https://forum.origin.ogame.gameforge.com/forum/thread/37-ptre-spy-report-sharing-tool-over-discord-and-ingame-oglight/`; document.querySelector('#menuTable').appendChild(Util.createDom('li', {}, ` <span class="menu_icon ogl_leftMenuIcon"> <a class="tooltipRight" href="${link}" target="_blank">${this.ptreIcon}</a> </span> <a class="menubutton tooltipRight" href="https://ptre.chez.gg/" target="_blank"> <span class="textlabel">PTRE</span> </a> `)); } let updateButton = () => { leftMenu.querySelector('.menubutton').classList.add('ogl_active'); leftMenu.querySelector('.menubutton').setAttribute('data-title', 'A new version is available !'); leftMenu.querySelector('.menubutton').setAttribute('href', 'https://openuserjs.org/scripts/nullNaN/OGLight'); } let isOldVersion = this.version.replace(/\D/g, "") != this.db.newVersion && this.version.indexOf('b') == -1; let target = document.querySelector('#siteFooter .fright'); target.appendChild(Util.createDom('span', {}, '| ')); target.appendChild(Util.createDom('a', {'target':'_blank', 'href':'https://board.fr.ogame.gameforge.com/index.php?thread/740025-paye-ton-re-ptre-intégration-oglight/'}, this.ptre ? 'PTRE <span class="ogl_ok material-icons">done</span>' : 'PTRE <span class="ogl_danger material-icons">clear</span>')); if(typeof GM_xmlhttpRequest !== 'undefined' && serverTime.getTime() > this.db.lastVersionCheck + 3600000 && !isOldVersion) { this.db.lastVersionCheck = serverTime.getTime(); GM_xmlhttpRequest( { method:'GET', url:'https://openuserjs.org/meta/nullNaN/OGLight.meta.js/', onload:result => { let updateAvailable = (result.responseText.replace(/\D/g, "") != this.version.replace(/\D/g, "") && this.version.indexOf('b') == -1) ? true : false; if(updateAvailable) { this.db.newVersion = result.responseText.replace(/\D/g, ""); updateButton(); } } }); } else if(isOldVersion && this.db.newVersion != 0) updateButton(); this.checkOGLID(); } checkTopScore() { if(!this.db.researchSpeed || this.db.topScore[1] < serverTime.getTime() - 3600000) // check every 1h max { fetch('https://' + window.location.host + '/api/serverData.xml') .then(result => result.text()) .then(txt => { let parser = new DOMParser(); let xmlResult = parser.parseFromString(txt, 'text/xml'); this.db.topScore = [parseInt(Number(xmlResult.querySelector('topScore').innerHTML)), serverTime.getTime()]; this.db.researchSpeed = parseInt(xmlResult.querySelector('researchDurationDivisor').innerHTML); }); } } displayPerformances() { if(this.version.indexOf('b') !== -1) { let initialTime = 0; let previousTime = 0; setTimeout(() => { console.groupCollapsed(`[OGL loading performances]`); this.performances.forEach((entry, index) => { if(entry[0] != 'Initial') console.log(`${entry[0].padEnd(16, '_')} ${(entry[1] - previousTime).toFixed(2)} ms`); else initialTime = entry[1]; previousTime = entry[1]; if(index == this.performances.length - 1) { console.log(''.padEnd(24, '-')); console.log('Total'.padEnd(16, '_') + ` ${(entry[1] - initialTime).toFixed(2)} ms`); } }); console.groupEnd(); }, 500); } } checkOGLID() { if(serverTime.getTime() > this.id[1] + 86400000) { let version = this.version == 'beta' ? `${this.version}-${hash}` : this.version; let json = { ogl_id:this.id[0] || '-', version:version || '-', script_name:GM_info.script.name || '-', script_namespace:GM_info.script.downloadURL || '-', } fetch('https://ptre.chez.gg/scripts/oglight_update_version.php?tool=oglight', { method:'POST', body:JSON.stringify(json) }) .then(response => response.json()) .then(data => { if(data.code == 1) { this.id[1] = serverTime.getTime(); GM_setValue('ogl_id', this.id); } }); } } } class CrawlerManager { constructor(ogl) { this.ogl = ogl; this.ogl.db.stats.total = this.ogl.db.stats.total || {}; if(this.ogl.page == 'highscore' || this.ogl.page == 'supplies') this.init(); this.ogl.observeMutation(() => { this.init(); }, 'crawler'); /*Util.getJSON(`https://${window.location.host}/game/index.php?page=fetchTechs`, result => { this.ogl.current.techs = result; let coords = this.ogl.current.coords.join(':'); if(this.ogl.current.type == 'moon') coords += ':M'; this.ogl.db.me.planets[coords] = this.ogl.db.me.planets[coords] || {}; this.ogl.db.me.planets[coords].techs = this.ogl.current.techs; // this.ogl.saveAsync(); });*/ // if(this.ogl.current.type == 'planet') this.getPlanetProduction(); } init() { if(this.ogl.page == 'supplies') { let coords = this.ogl.current.coords.join(':'); let upgrade = document.querySelector('.targetlevel')?.getAttribute('data-value'); if(upgrade && this.ogl.current.type == 'planet') { let techID = document.querySelector('.targetlevel').closest('.technology').getAttribute('data-technology'); this.ogl.db.me.planets[coords] = this.ogl.db.me.planets[coords] || {}; this.ogl.db.me.planets[coords].upgrade = [techID, parseInt(upgrade)]; } else { this.ogl.db.me.planets[coords] = this.ogl.db.me.planets[coords] || {}; this.ogl.db.me.planets[coords].upgrade = []; } // this.ogl.saveAsync(); } else if(this.ogl.page == 'highscore') { if(document.querySelector('#stat_list_content .ajaxLoad') || !document.querySelector('#row #player').classList.contains('active')) return; this.ogl.db.lastRankUpdate = !this.ogl.db.lastRankUpdate || typeof this.ogl.db.lastRankUpdate !== 'object' ? {} : this.ogl.db.lastRankUpdate; this.ogl.db.lastStatusUpdate = !this.ogl.db.lastStatusUpdate || typeof this.ogl.db.lastStatusUpdate !== 'object' ? {} : this.ogl.db.lastStatusUpdate; let rankPoint = document.querySelector('a#points').classList.contains('active'); let rankFleet = document.querySelector('a#fleet').classList.contains('active'); let rankPage = document.querySelector('.pagebar .activePager')?.textContent || 1; let updateRank = serverTime.getTime() - (this.ogl.db.lastRankUpdate?.[rankPage] || 0) > 12 * 60 * 60 * 1000; let updateStatus = serverTime.getTime() - (this.ogl.db.lastStatusUpdate?.[rankPage] || 0) > 12 * 60 * 60 * 1000; if(updateStatus) { Util.getXML(`https://${window.location.host}/api/players.xml`, result => { let xmlTimestamp = parseInt(result.querySelector('players').getAttribute('timestamp')) * 1000; document.querySelectorAll('#ranks tbody > tr').forEach((line, index) => { setTimeout(() => { let id = line.getAttribute('id').replace('position', ''); let playerStatus = result.querySelector(`player[id="${id}"]`)?.getAttribute('status') || 'status_abbr_active'; if(playerStatus.indexOf('v') > -1 && playerStatus != 'status_abbr_active') playerStatus = 'status_abbr_vacation'; else if(playerStatus === "I") playerStatus = 'status_abbr_longinactive'; else if(playerStatus === "i") playerStatus = 'status_abbr_inactive'; let entryID = this.ogl.find(this.ogl.db.players, 'id', id)[0] ?? this.ogl.db.players.length; let player = this.ogl.db.players[entryID]; if(player && (player.lastStatusUpdate ?? 0) < xmlTimestamp) { line.querySelector('.playername').classList.remove(Array.from(line.querySelector('.playername').classList).filter(e => e.startsWith('status_'))[0]); this.ogl.db.players[entryID].status = playerStatus; line.querySelector('.playername').classList.add(playerStatus); } }, index); }); this.ogl.db.lastStatusUpdate[rankPage] = xmlTimestamp; // this.ogl.saveAsync(); }); } // add status / names document.querySelectorAll('#ranks tbody > tr').forEach((line, index) => { let id = line.getAttribute('id').replace('position', ''); let playerIndex = this.ogl.find(this.ogl.db.players, 'id', id)[0] ?? this.ogl.db.players.length; let player = {}; player.id = id; player.name = line.querySelector('.playername').textContent.trim(); player.ally = line.querySelector('.ally-tag')?.textContent.trim().slice(1, -1); if(player.name.indexOf('...') > -1 && this.ogl.db.players[playerIndex]?.name && this.ogl.db.players[playerIndex].name.indexOf(player.name.replace(/\./g, '')) > -1) { player.name = this.ogl.db.players[playerIndex].name; line.querySelector('.playername').textContent = player.name; } if(rankPoint) { player.rank = line.querySelector('.position').textContent.trim(); player.total = parseInt(line.querySelector('.score').textContent.replace(/\D/g,'')); } else if(rankFleet) { player.power = parseInt(line.querySelector('.score').textContent.replace(/\D/g,'')); } if(!player.id) return; this.ogl.db.players[playerIndex] = {...this.ogl.db.players[playerIndex], ...player}; if(this.ogl.db.players?.[playerIndex]?.status) { let status = Array.from(this.ogl.db.players[playerIndex].status.split(' ')).filter(e => e.startsWith('status_'))[0]; line.querySelector('.playername').classList.add(status); } line.querySelector('.playername').classList.remove('status_abbr_honorableTarget'); // check rank et score if(rankPoint && updateRank) { this.ogl.db.players[playerIndex].veryOldRank = this.ogl.db.players[playerIndex].oldRank || this.ogl.db.players[playerIndex].rank; this.ogl.db.players[playerIndex].oldRank = this.ogl.db.players[playerIndex].rank || player.rank; this.ogl.db.players[playerIndex].veryOldTotal = this.ogl.db.players[playerIndex].oldTotal || this.ogl.db.players[playerIndex].total || player.total; this.ogl.db.players[playerIndex].oldTotal = this.ogl.db.players[playerIndex].total || player.total; } player = this.ogl.db.players[playerIndex]; // display rank & score movements if(rankPoint) { let rankMovement = (player.veryOldRank || 0) - player.rank; if(!player.veryOldRank) { line.querySelector('.movement').textContent = 'NEW'; line.querySelector('.movement').classList.add('ogl_warning'); } else { if(player.veryOldRank != player.rank) { let sign = rankMovement > 0 ? '+' : ''; line.querySelector('.movement').textContent = `(${sign + parseInt(rankMovement)})`; if(rankMovement > 0) line.querySelector('.movement').classList.add('ogl_ok'); else if(rankMovement < 0) line.querySelector('.movement').classList.add('ogl_danger'); } else line.querySelector('.movement').textContent = '-'; } let diff = (player.total - player.veryOldTotal) || 0; let diffSign = diff > 0 ? '+' : ''; line.querySelector('.ogl_scoreDiff') && line.querySelector('.ogl_scoreDiff').remove(); let scoreDiff = line.querySelector('.score').appendChild(Util.createDom('div', {'class':'ogl_scoreDiff'}, diffSign + Util.formatNumber(diff))); if(diff > 0) scoreDiff.classList.add('ogl_ok'); else if(diff < 0) scoreDiff.classList.add('ogl_danger'); else scoreDiff.classList.add('ogl_none'); } }); if(rankPoint && updateRank) this.ogl.db.lastRankUpdate[rankPage] = serverTime.getTime(); // this.ogl.saveAsync(); } else if(this.ogl.page == 'galaxy') { // store spy probes to send if(!this.spyProbeCountDone && document.querySelector('a[onclick*="sendShips"]')) { let ships = document.querySelector('a[onclick*="sendShips"]').getAttribute('onclick').match(/\d+/g).map(Number); if(ships[0] == 6 && ships[5] != this.ogl.db.spyProbesCount) { this.ogl.db.spyProbesCount = ships[5]; this.spyProbeCountDone = true; // this.ogl.saveAsync(); } } // antispam galaxy security if(this.ogl.galaxyCoords[0] != document.querySelector('#galaxy_input').value || this.ogl.galaxyCoords[1] != document.querySelector('#system_input').value) return; this.ogl.component.tooltip.close(true); let ptrePosition = {}; let ptreActivities = {}; let selector = document.querySelectorAll('.galaxyTable .ctContentRow'); let refreshPinnedTarget = false; let currentSystemRaw = parseInt(galaxy)*1000+parseInt(system); selector.forEach(line => { if(!line.querySelector('.position') && !line.querySelector('.cellPosition')) return; // ignore p16 & 17 if(line.querySelector('.playername.admin') || line.querySelector('.cellPlayerName.admin')) return; // ignore admins let isOld = false; // old OGL data format let info = this.getCurrentInfo(line); let player = info[0]; let planet = info[1]; let planetIndex = this.ogl.find(this.ogl.db.positions, 'coords', planet.coords)[0]; if(this.ogl.ptre) { let oldPositionEntry = this.ogl.db.positions[planetIndex]; if(oldPositionEntry || this.ogl.db.checkedSystems.indexOf(currentSystemRaw) > -1) { let oldPlayerEntry; oldPositionEntry = oldPositionEntry || { id:-1, playerID:-1 }; if(oldPositionEntry && oldPositionEntry.playerID && oldPositionEntry.playerID > -1) { let oldPlayerIndex = this.ogl.find(this.ogl.db.players, 'id', oldPositionEntry.playerID)[0]; oldPlayerEntry = this.ogl.db.players[oldPlayerIndex]; if(oldPlayerEntry && document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'pinned' && this.ogl.db.pinnedList[0] == oldPlayerEntry) { refreshPinnedTarget = true; } } else if(this.ogl.db.checkedSystems.indexOf(currentSystemRaw) > -1) oldPlayerEntry = {}; // prepare PTRE positions if(oldPositionEntry && (planet.id != oldPositionEntry.id || player.id != oldPositionEntry.playerID || planet.moonID != oldPositionEntry.moonID)) { if((!oldPositionEntry?.playerID || oldPositionEntry?.playerID == -1) && player.id == -1) return; ptrePosition[planet.coords] = {} ptrePosition[planet.coords].id = planet.id; ptrePosition[planet.coords].teamkey = this.ogl.ptre; ptrePosition[planet.coords].galaxy = planet.coords.split(':')[0]; ptrePosition[planet.coords].system = planet.coords.split(':')[1]; ptrePosition[planet.coords].position = planet.coords.split(':')[2]; ptrePosition[planet.coords].timestamp_ig = serverTime.getTime(); ptrePosition[planet.coords].player_id = player.id; ptrePosition[planet.coords].name = player.name || false; ptrePosition[planet.coords].rank = player.rank || -1; ptrePosition[planet.coords].score = player.total || -1; ptrePosition[planet.coords].fleet = player.fleet || -1; ptrePosition[planet.coords].status = player.statusTags; ptrePosition[planet.coords].old_player_id = oldPositionEntry?.playerID || -1; ptrePosition[planet.coords].timestamp_api = oldPlayerEntry?.lastAPIUpdate || -1; ptrePosition[planet.coords].old_name = oldPlayerEntry?.name || false; ptrePosition[planet.coords].old_rank = oldPlayerEntry?.rank || -1; ptrePosition[planet.coords].old_score = oldPlayerEntry?.total || -1; ptrePosition[planet.coords].old_fleet = oldPlayerEntry?.fleet || -1; if(planet.moonID > -1) { ptrePosition[planet.coords].moon = {}; ptrePosition[planet.coords].moon.id = planet.moonID; } } } } // save new player data if(player.id) { let playerEntryID = this.ogl.find(this.ogl.db.players, 'id', player.id)[0] ?? this.ogl.db.players.length; if(this.ogl.db.players[playerEntryID]?.id == -2) isOld = true; this.ogl.db.players[playerEntryID] = {...this.ogl.db.players[playerEntryID], ...player}; } planetIndex = planetIndex ?? this.ogl.db.positions.length; // unmark empty positions if needed if(this.ogl.db.positions[planetIndex]?.color) { if((this.ogl.db.positions[planetIndex]?.id != planet.id && !isOld) || planet.id == -1) { planet.color = false; } } // save (or remove) new position data this.ogl.db.positions[planetIndex] = {...this.ogl.db.positions[planetIndex], ...planet} if(planet.id == -1 || player.id == -1) { delete this.ogl.db.positions[planetIndex]; this.ogl.db.positions.splice(planetIndex, 1); } // update targets list if needed if(document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'targetList') { document.querySelectorAll(`.ogl_sideView [data-playerID="${planet.playerID}"]`).forEach(e => { if(player.id != -1) { e.querySelectorAll('div')[1].textContent = player.name; e.querySelectorAll('div')[1].className = ''; e.querySelectorAll('div')[1].classList.add(player.status); } else e.remove(); }); } // prepare PTRE activities if(this.ogl.ptre && planet.id > -1 && player.id > -1 && this.ogl.db.pinnedList.indexOf(player.id) > -1) { ptreActivities[planet.coords] = {}; ptreActivities[planet.coords].id = planet.id; ptreActivities[planet.coords].player_id = player.id; ptreActivities[planet.coords].teamkey = this.ogl.ptre; ptreActivities[planet.coords].mv = line.querySelector('span[class*="vacation"]') ? true : false; ptreActivities[planet.coords].activity = planet.activity; ptreActivities[planet.coords].galaxy = planet.coords.split(':')[0]; ptreActivities[planet.coords].system = planet.coords.split(':')[1]; ptreActivities[planet.coords].position = planet.coords.split(':')[2]; ptreActivities[planet.coords].main = this.ogl.db.positions[planetIndex].main || false; if(planet.moonID > -1) { ptreActivities[planet.coords].moon = {}; ptreActivities[planet.coords].moon.id = planet.moonID; ptreActivities[planet.coords].moon.activity = planet.moonActivity; } } }); this.ogl.db.checkedSystems.push(currentSystemRaw); // this.ogl.saveAsync(); // refresh pinned menu if(document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'pinned') refreshPinnedTarget = true; // send activities to PTRE if(Object.keys(ptreActivities).length > 0) { let tmpCoords = [galaxy, system]; fetch('https://ptre.chez.gg/scripts/oglight_import_player_activity.php?tool=oglight', { method:'POST', body:JSON.stringify(ptreActivities) }) .then(response => response.json()) .then(data => { Util.logPtre(data, {galaxy:galaxy, system:system}); if(data.code == 1) { if(refreshPinnedTarget && this.ogl.component.sidebar) { new Promise(resolve => { resolve(this.ogl.component.sidebar.displayPinnedTarget()); }) .then(() => { document.querySelectorAll(`.ogl_pinnedContent [data-coords^="${tmpCoords[0]}:${tmpCoords[1]}:"]`).forEach(e => { if(!e.querySelector('.ogl_checked')) e.appendChild(Util.createDom('div', {'class':'material-icons ogl_checked tooltipLeft', 'title':data.message}, 'check_circle')); }); }); } } }); } else if(refreshPinnedTarget) this.ogl.component.sidebar?.displayPinnedTarget(); // update position // send positions to PTRE if(Object.keys(ptrePosition).length > 0) { fetch('https://ptre.chez.gg/scripts/api_galaxy_import_infos.php?tool=oglight', { method:'POST', body:JSON.stringify(ptrePosition) }) .then(response => response.json()) .then(data => { Util.logPtre(data, {galaxy:galaxy, system:system}); if(data.code != 1) console.log("Can't send data to PTRE"); else { console.log('PTRE : ', currentSystemRaw, ptrePosition) if(document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'pinned' && this.ogl.db.pinnedList[0] == player.id) this.ogl.component.sidebar?.displayPinnedTarget(); } }); } } this.ogl.performances.push(['Crawler',performance.now()]); } /** * Permet de trouvé le timer d'activité d'une planète ou d'une lune. */ getTimerActivity(planetMoonRel) { if (planetMoonRel === undefined) return undefined console.log(planetMoonRel) // Le texte du timer se trouve dans une div que l'on peut retrouver // grâce à son "id" qui est stocker dans le "rel" de la div de la planète. const timerText = document.querySelector(`#${planetMoonRel}`)?.querySelector(".ListLinks li:first-child")?.innerText // Le texte du timer ressemble à "Activité: 55m" // On applique donc une regex pour trouver "55" const regex = /([0-9]{2})/g; const matches = timerText?.match(regex); console.log(timerText, matches) if (matches) { return matches[0] } else { return undefined } } getCurrentInfo(line) { let player = {}; let planet = {}; // update player data player.id = line.querySelector('.cellPlayerName').textContent.trim().length == 0 ? - 1 : line.querySelector('.cellPlayerName [rel^="player"]')?.getAttribute('rel').replace('player', '') || this.ogl.account.id; player.name = line.querySelector('.cellPlayerName [rel^="player"]')?.childNodes[0].textContent.trim() || line.querySelector('.cellPlayerName .ownPlayerRow')?.textContent.trim(); player.status = Array.from(line.querySelector('.cellPlayerName span[class*="status_"]')?.classList || []).filter(e => e.startsWith('status_'))[0]; player.lastUpdate = serverTime.getTime(); player.lastStatusUpdate = serverTime.getTime(); if(player.status == 'status_abbr_honorableTarget') player.status = 'status_abbr_active'; let status = line.querySelector('.cellPlayerName pre')?.textContent.trim().replace('(', '').replace(')', '').replace(/ /g, '').replace('ph', '').replace('A', '').replace('o', '').replace('f', '').replace('d', '').replace(',', '') || ''; if(player.id == -1) status = -1; player.statusTags = status; let tooltip = document.querySelector('#player'+player.id); if(tooltip) { player.name = tooltip.querySelector('h1 span').textContent; player.rank = tooltip.querySelector('.rank a')?.textContent || -1; } else if(player.id > -1) { player.rank = this.ogl.account.rank; } let position = parseInt(line.querySelector('.cellPosition').textContent); let coords = `${document.querySelector('#galaxy_input').value}:${document.querySelector('#system_input').value}:${position}`; // update position planet.id = line.querySelector('[data-planet-id]')?.getAttribute('data-planet-id') || -1; planet.playerID = line.querySelector('.cellPlayerName').textContent.trim().length == 0 ? -1 : line.querySelector(`.cellPlayerName [rel^="player"]`)?.getAttribute('rel').replace('player', '') || this.ogl.account.id; planet.coords = coords; planet.rawCoords = coords.split(':').map(x => x.padStart(3, '0')).join(''); planet.moonID = line.querySelector('[data-moon-id]')?.getAttribute('data-moon-id') || -1; planet.lastUpdate = serverTime.getTime(); planet.activity = line.querySelector('[data-planet-id] .activity.minute15') ? '*': this.getTimerActivity(line.querySelector('[data-planet-id]')?.getAttribute("rel")) || 60; planet.moonActivity = line.querySelector('[data-moon-id] .activity.minute15') ? '*' : this.getTimerActivity(line.querySelector('[data-moon-id]')?.getAttribute("rel")) || 60; return [player, planet]; } buildStalkWindow(playerID) { let playerIndex = this.ogl.find(this.ogl.db.players, 'id', playerID)[0]; let player = this.ogl.db.players[playerIndex]; let content = Util.createDom('div', {'class':'galaxyTooltip'}); content.innerHTML = `<h1><span>${player.name}</span><a href="https://${window.location.host}/game/index.php?page=highscore&site=${Math.max(1, Math.ceil(player.rank / 100))}&category=1&searchRelId=${player.id}" data-rank="${player.rank == -1 ? '(b)' : player.rank}" class="ogl_ranking">${player.rank == -1 ? '(b)' : '#'+player.rank}</a></h1> <div class="ogl_actions"></div> <div class="ogl_stalkActions"></div> <div class="ogl_colorAll"></div> <div class="ogl_stalkInfo"> <div class="ogl_stalkPlanets"></div> <div class="ogl_stalkPoints"> <div title="${Util.formatNumber(player.total)}"><i class="material-icons">star</i>${Util.formatToUnits(player.total)}</div> <div title="${Util.formatNumber(player.eco)}"><i class="material-icons">attach_money</i>${Util.formatToUnits(player.eco)}</div> <div title="${Util.formatNumber(player.tech)}"><i class="material-icons">science</i>${Util.formatToUnits(player.tech)}</div> <div title="${Util.formatNumber(player.fleet)}"><i class="material-icons">military_tech</i>${Util.formatToUnits(player.fleet)}</div> <div title="${Util.formatNumber(player.def)}"><i class="material-icons">security</i>${Util.formatToUnits(player.def)}</div> </div> </div>`; let actions = content.querySelector('.ogl_stalkActions'); let write = actions.appendChild(Util.createDom('div', {'class':'ogl_button material-icons', 'data-playerid':player.id}, 'edit')); if(document.querySelector('#chatBar')) { write.classList.add('sendMail'); write.classList.add('js_openChat'); } else write.addEventListener('click', () => window.location.href = `https://${window.location.host}/game/index.php?page=chat&playerId=${player.id}`); let buddy = actions.appendChild(Util.createDom('adiv', {'class':'ogl_button material-icons'}, 'person_add_alt_1')); buddy.addEventListener('click', () => window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=buddies&action=7&id=${player.id}&ajax=1`); let ignore = actions.appendChild(Util.createDom('adiv', {'class':'ogl_button material-icons'}, 'block')); ignore.addEventListener('click', () => window.location.href = `https://${window.location.host}/game/index.php?page=ignorelist&action=1&id=${player.id}`); let mmorpgstats = actions.appendChild(Util.createDom('adiv', {'class':'ogl_button material-icons'}, 'leaderboard')); mmorpgstats.addEventListener('click', () => { let lang = ['fr', 'de', 'en', 'es', 'pl', 'it', 'ru', 'ar', 'mx', 'tr', 'fi', 'tw', 'gr', 'br', 'nl', 'hr', 'sk', 'cz', 'ro', 'us', 'pt', 'dk', 'no', 'se', 'si', 'hu', 'jp', 'ba'].indexOf(this.ogl.universe.lang); let link = `https://www.mmorpg-stat.eu/0_fiche_joueur.php?pays=${lang}&ftr=${player.id.replace(/\D/g,'')}.dat&univers=_${this.ogl.universe.number}`; window.open(link, '_blank'); }); let pin = actions.appendChild(Util.createDom('div', {'class':'ogl_button material-icons'}, 'push_pin')); pin.addEventListener('click', () => { this.ogl.db.pinnedList.forEach((e, index) => { if(e && e == player.id) this.ogl.db.pinnedList.splice(index, 1); }); this.ogl.db.pinnedList.unshift(player.id); if(this.ogl.db.pinnedList.length > this.ogl.maxPinnedTargets) this.ogl.db.pinnedList.length = this.ogl.maxPinnedTargets; // this.ogl.saveAsync(); this.ogl.component.sidebar?.displayPinnedTarget(); this.ogl.component.crawler.checkPlayerApi(this.ogl.db.pinnedList[0]); }); this.ogl.component.color.addColorUI(false, content.querySelector('.ogl_colorAll'), this.ogl.find(this.ogl.db.positions, 'playerID', player.id, true)); let planetCount = 0; let rawStart = '000000'; let multi = 1; let isMulti = false; this.ogl.find(this.ogl.db.positions, 'playerID', player.id, true).forEach(planetIndex => { let planet = this.ogl.db.positions[planetIndex]; let splitted = planet.coords.split(':'); let item = Util.createDom('div', {'data-coords':planet.coords}); let coordsDiv = item.appendChild(Util.createDom('span', {}, planet.coords)); coordsDiv.addEventListener('click', () => { this.ogl.component.tooltip.close(true); this.ogl.component.galaxy.goToPosition(splitted[0], splitted[1], splitted[2]); }); if(this.ogl.page == 'galaxy' && document.querySelector('#galaxy_input').value == splitted[0] && document.querySelector('#system_input').value == splitted[1]) { coordsDiv.classList.add('ogl_currentSystem'); } if(planet.main) item.appendChild(Util.createDom('div', {'class':'material-icons ogl_mainPlanet'}, 'star')); let mSpy = item.appendChild(Util.createDom('div', {'class':'ogl_moonIcon material-icons', 'data-type':3}, 'brightness_2')); mSpy.addEventListener('click', () => this.ogl.component.fleet.sendSpyProbe([splitted[0], splitted[1], splitted[2], 3], this.ogl.db.spyProbesCount, mSpy, true)); if(serverTime.getTime() - planet.lastMoonSpy < 60 * 60 * 1000) mSpy.classList.add('ogl_done'); let pSpy = item.appendChild(Util.createDom('div', {'class':'ogl_planetIcon material-icons', 'data-type':1}, 'language')); pSpy.addEventListener('click', () => this.ogl.component.fleet.sendSpyProbe([splitted[0], splitted[1], splitted[2], 1], this.ogl.db.spyProbesCount, pSpy, true)); if(serverTime.getTime() - planet.lastSpy < 60 * 60 * 1000) pSpy.classList.add('ogl_done'); if(planet.moonID > 0) mSpy.classList.add('ogl_active'); planet.color ? item.setAttribute('data-color', planet.color) : item.removeAttribute('data-color'); content.querySelector('.ogl_stalkPlanets').appendChild(item); if(rawStart == planet.rawCoords.slice(0, -3)) { item.setAttribute('data-multi', multi); isMulti = true; } else if(isMulti) { multi++; isMulti = false; } rawStart = planet.rawCoords.slice(0, -3); planetCount++; }); content.querySelector('.ogl_stalkPoints').appendChild(Util.createDom('div', {}, `<i class="material-icons">language</i>${planetCount}`)); return content; } getPlanetProduction() { return; let currentCoords = this.ogl.current.coords.join(':'); ['metal', 'crystal', 'deut'].forEach((res, index) => { let data = resourcesBar.resources[res.replace('deut', 'deuterium')].tooltip; //let currentRes = Math.floor(resourcesBar.resources[res.replace('deut', 'deuterium')].amount); let prod = data.replace(/\./g, '').match(/\d+/g)[2]; this.ogl.db.me.planets[currentCoords] = this.ogl.db.me.planets[currentCoords] || {}; this.ogl.db.me.planets[currentCoords].production = this.ogl.db.me.planets[currentCoords].production || []; this.ogl.db.me.planets[currentCoords].storage = this.ogl.db.me.planets[currentCoords].storage || []; if(data.indexOf('overmark') == -1) { this.ogl.db.me.planets[currentCoords].production[index] = (prod / 3600).toFixed(2); } this.ogl.db.me.planets[currentCoords].storage[index] = resourcesBar.resources[res.replace('deut', 'deuterium')].storage; this.ogl.db.me.planets[currentCoords].production[3] = serverTime.getTime(); }); // this.ogl.saveAsync(); } checkPlayerPtre(playerID, callback) { if(this.ogl.ptre) { Util.getJSON(`https://ptre.chez.gg/scripts/api_galaxy_get_infos.php?tool=oglight&team_key=${this.ogl.ptre}&player_id=${playerID}`, ptreData => { Util.logPtre(ptreData, {playerID:playerID}); if(ptreData.code == 1) { let playerEntryID = this.ogl.find(this.ogl.db.players, 'id', playerID)[0] ?? this.ogl.db.players.length; this.ogl.db.players[playerEntryID] = this.ogl.db.players[playerEntryID] || {}; this.ogl.db.players[playerEntryID].lastPTRECheck = serverTime.getTime(); ptreData.galaxy_array.forEach(entry => { let planet = {}; planet.id = entry.id; planet.playerID = entry.player_id; planet.coords = entry.coords; planet.rawCoords = entry.coords.split(':').map(x => x.padStart(3, '0')).join(''); planet.moonID = entry.moon?.id ?? -1; planet.lastUpdate = entry.timestamp_ig; planet.activity = false; planet.moonActivity = false; let planetEntryID = this.ogl.find(this.ogl.db.positions, 'coords', planet.coords)[0] ?? this.ogl.db.positions.length; this.ogl.db.positions[planetEntryID] = this.ogl.db.positions[planetEntryID] || {}; if(!this.ogl.db.positions[planetEntryID].lastUpdate || this.ogl.db.positions[planetEntryID].lastUpdate < planet.lastUpdate) { this.ogl.db.positions[planetEntryID] = {...this.ogl.db.positions[planetEntryID], ...planet}; } }); // this.ogl.saveAsync(); } if(callback) callback(playerID); if(document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'pinned' && this.ogl.db.pinnedList[0] == playerID) this.ogl.component.sidebar?.displayPinnedTarget(); }); } } checkPlayerApi(playerID, callback, forced) { if(!playerID || playerID <= 0) return; let lastAPICheck = this.ogl.db.players[this.ogl.find(this.ogl.db.players, 'id', playerID)[0]]?.lastAPICheck || 0; let lastPTRECheck = this.ogl.db.players[this.ogl.find(this.ogl.db.players, 'id', playerID)[0]]?.lastPTRECheck || 0; if(serverTime.getTime() - lastAPICheck > 3 * 60 * 60 * 1000) { Util.getXML(`https://${window.location.host}/api/playerData.xml?id=${playerID}`, result => { let playerEntryID = this.ogl.find(this.ogl.db.players, 'id', playerID)[0] ?? this.ogl.db.players.length; let player = {}; player.id = playerID; player.total = parseInt(result.querySelector('position[type="0"]').getAttribute('score')); player.eco = parseInt(result.querySelector('position[type="1"]').getAttribute('score')); player.tech = parseInt(result.querySelector('position[type="2"]').getAttribute('score')); player.power = parseInt(result.querySelector('position[type="3"]').getAttribute('score')); player.def = Math.max(player.power - (player.total - player.eco - player.tech), 0); player.fleet = player.power - player.def; player.ally = result.querySelector('alliance tag')?.textContent || false; player.lastAPICheck = serverTime.getTime(); player.lastPTRECheck = serverTime.getTime(); player.lastAPIUpdate = parseInt(result.querySelector('playerData').getAttribute('timestamp')) * 1000; player.name = result.querySelector('playerData').getAttribute('name'); if(this.ogl.page == 'highscore') player.rank = document.querySelector(`#position${playerID} .position`)?.textContent.trim(); if(this.ogl.db.players[playerEntryID]?.name && this.ogl.db.players[playerEntryID].name.indexOf('...') == -1) { player.name = this.ogl.db.players[playerEntryID].name; } this.ogl.db.players[playerEntryID] = {...this.ogl.db.players[playerEntryID], ...player}; // update player positions result.querySelectorAll('planet').forEach((apiPlanet, index) => { let planet = {}; planet.id = apiPlanet.getAttribute('id'); planet.playerID = playerID; planet.coords = apiPlanet.getAttribute('coords'); planet.rawCoords = apiPlanet.getAttribute('coords').split(':').map(x => x.padStart(3, '0')).join(''); planet.moonID = apiPlanet.querySelector('moon')?.getAttribute('id') ?? -1; planet.main = !index; planet.lastUpdate = parseInt(result.querySelector('playerData').getAttribute('timestamp')) * 1000; planet.lastAPIUpdate = parseInt(result.querySelector('playerData').getAttribute('timestamp')) * 1000; planet.activity = false; planet.moonActivity = false; let planetEntryID = this.ogl.find(this.ogl.db.positions, 'coords', planet.coords)[0] ?? this.ogl.db.positions.length; this.ogl.db.positions[planetEntryID] = this.ogl.db.positions[planetEntryID] || {}; if(!this.ogl.db.positions[planetEntryID].lastUpdate || this.ogl.db.positions[planetEntryID].lastUpdate < planet.lastUpdate) { this.ogl.db.positions[planetEntryID] = {...this.ogl.db.positions[planetEntryID], ...planet}; } if(planet.main) this.ogl.db.positions[planetEntryID].main = true; else this.ogl.db.positions[planetEntryID].main = false; }); // this.ogl.saveAsync(); if(this.ogl.ptre) this.checkPlayerPtre(playerID, callback); else if(callback) callback(playerID, callback); }); } else if(this.ogl.ptre && (forced || serverTime.getTime() - lastPTRECheck > 10 * 60 * 1000)) { this.checkPlayerPtre(playerID, callback); } else { if(callback) callback(playerID, callback); } } } class HighscoreManager { constructor(ogl) { this.ogl = ogl; if(this.ogl.page == 'highscore') this.init(); this.ogl.observeMutation(() => this.init(), 'highscore'); } init() { if(!document.querySelector('.playername')) return; document.querySelectorAll('#ranks tbody tr').forEach(line => { line.querySelector('.playername').classList.add('tooltipRight'); line.querySelector('.playername').classList.add('tooltipClose'); line.querySelector('.playername').setAttribute('data-title', 'loading...'); line.querySelector('.playername').addEventListener('mouseenter', e => { let id = line.getAttribute('id').replace('position', ''); if(e.target?.classList.contains('ogl_highlight')) return; this.ogl.component.crawler.checkPlayerApi(id, () => { this.ogl.component.tooltip.update(e.target, this.ogl.component.crawler.buildStalkWindow(id)); }); }); }); this.ogl.performances.push(['Highscore',performance.now()]); } } class GalaxyManager { constructor(ogl) { this.ogl = ogl; //if(this.ogl.page == 'galaxy') this.init(); this.ogl.observeMutation(() => this.init(), 'galaxy'); if(this.ogl.page == 'galaxy') { document.querySelector('#galaxyLoading').setAttribute('data-currentPosition', `${galaxy}:${system}`); let updateTargets = (g, s) => { document.querySelectorAll('.ogl_stalkPlanets.ogl_scrollable > div.ogl_currentSystem').forEach(item => item.classList.remove('ogl_currentSystem')); document.querySelectorAll(`.ogl_stalkPlanets.ogl_scrollable > div[data-minicoords="${g}:${s}"]`).forEach(item => item.classList.add('ogl_currentSystem')); } // old galaxy perf fix /*loadContent = (g, s) => { mobile = true; isMobile = true; if(this.xhr) this.xhr.abort(); $("#galaxyLoading").show(); document.querySelector('#galaxyLoading').setAttribute('data-currentPosition', `${g}:${s}`); if(0 === galaxy.length || !$.isNumeric(+galaxy)) g = 1; if(0 === system.length || !$.isNumeric(+system)) s = 1; $("#galaxy_input").val(g); $("#system_input").val(s); let phalanxSystemLink = $('#galaxyHeader .phalanxlink.btn_system_action'); if(phalanxSystemLink.length) phalanxSystemLink.attr('href', phalanxSystemLink.attr('href').replace(/(galaxy=)\d+/, "$1" + galaxy).replace(/(system=)\d+/, "$1" + system)); this.xhr = $.post(contentLink, { galaxy:g, system:s }, displayContentGalaxy) .always(function() { mobile = false; isMobile = false; }); updateTargets(g, s); }*/ loadContentNew = (g, s) => { this.ogl.galaxyLoaded = false; if(!canSwitchGalaxy && notEnoughDeuteriumMessage) { fadeBox(notEnoughDeuteriumMessage, true); return; } if(this.xhr) this.xhr.abort(); $("#galaxyLoading").show(); document.querySelector('#galaxyLoading').setAttribute('data-currentPosition', `${g}:${s}`); if(0 === galaxy.length || !$.isNumeric(+galaxy)) g = 1; if(0 === system.length || !$.isNumeric(+system)) s = 1; $("#galaxy_input").val(g); $("#system_input").val(s); let phalanxSystemLink = $('#galaxyHeader .phalanxlink.btn_system_action'); if(phalanxSystemLink.length) phalanxSystemLink.attr('href', phalanxSystemLink.attr('href').replace(/(galaxy=)\d+/, "$1" + galaxy).replace(/(system=)\d+/, "$1" + system)); this.xhr = $.post(galaxyContentLink, { galaxy:g, system:s }, renderContentGalaxy); updateTargets(g, s); } } this.goToPosition = (g, s, p) => { if(this.ogl.page == 'galaxy') { this.ogl.component.tooltip.container.textContent = ''; this.ogl.component.tooltip.close(true); galaxy = g; system = s; loadContentNew(g, s); } else { Util.redirect(`https://${window.location.host}/game/index.php?page=ingame&component=galaxy&galaxy=${g}&system=${s}&position=${p}`, this.ogl); } } this.ogl.performances.push(['Galaxy',performance.now()]); } init() { document.querySelectorAll('.galaxyTable .ctContentRow').forEach(line => { line.removeAttribute('data-color'); line.querySelector('.cellPlayerName').classList.remove('tooltipRel'); line.querySelector('.cellDebris').classList.remove('ogl_active'); if(!line.querySelector('.cellPosition')) return; // ignore p16 & 17 if(line.querySelector('.cellPlayerName.admin')) return; // ignore admins let id; if(line.querySelector('.ownPlayerRow')) id = this.ogl.account.id; else id = line.querySelector('.cellPlayerName [rel^="player"]')?.getAttribute('rel').replace('player', ''); if(id) { let position = line.querySelector('.cellPosition').textContent; if(position >= 10) line.querySelector('.cellPlayerName > span[class*="status_"]').classList.add('tooltipRightTop'); else line.querySelector('.cellPlayerName > span[class*="status_"]').classList.add('tooltipRight'); line.querySelector('.cellPlayerName > span[class*="status_"]').classList.add('ogl_noPointer'); line.querySelector('.cellPlayerName > span[class*="status_"]').classList.add('tooltipClose'); line.querySelector('.cellPlayerName > span[class*="status_"]').classList.remove('tooltipRel'); line.querySelector('.cellPlayerName > span[class*="status_"]').setAttribute('data-title', 'loading...'); line.querySelector('.cellPlayerName > span[class*="status_"]').classList.remove('ogl_noPointer'); let player = this.ogl.db.players[this.ogl.find(this.ogl.db.players, 'id', id)[0]]; if(!player) return; let a = Util.createDom('a', {'class':'float_right', 'href':`https://${window.location.host}/game/index.php?page=highscore&site=${Math.max(1, Math.ceil(player.rank / 100))}&category=1&searchRelId=${player.id}`}, `${player.rank == -1 ? '(b)' : '#'+player.rank}`); line.querySelector('.cellPlayerName').appendChild(a); line.querySelector('.cellPlayerName > span[class*="status_"]').addEventListener('mouseenter', e => { if(e.target.classList.contains('ogl_highlight')) return; this.ogl.component.crawler.checkPlayerApi(id, () => { this.ogl.component.tooltip.update(e.target, this.ogl.component.crawler.buildStalkWindow(id)); }); }); // pin target line.querySelector('.cellPlayerName > span[class*="status_"]').addEventListener('click', () => { this.ogl.db.pinnedList.forEach((e, index) => { if(e && e == player.id) this.ogl.db.pinnedList.splice(index, 1); }); this.ogl.db.pinnedList.unshift(player.id); if(this.ogl.db.pinnedList.length > this.ogl.maxPinnedTargets) this.ogl.db.pinnedList.length = this.ogl.maxPinnedTargets; // this.ogl.saveAsync(); new Promise(resolve => { resolve(this.ogl.component.crawler.checkPlayerApi(this.ogl.db.pinnedList[0])); }) .then(() => { this.ogl.component.sidebar.displayPinnedTarget(); }) .then(() => { document.querySelectorAll(`.ogl_pinnedContent [data-coords^="${galaxy}:${system}:"]`).forEach(e => { if(!e.querySelector('.ogl_checked')) e.appendChild(Util.createDom('div', {'class':'material-icons ogl_checked'}, 'check_circle')); }); }); }); let planetID = line.querySelector('[data-planet-id]').getAttribute('data-planet-id'); let index = this.ogl.find(this.ogl.db.positions, 'id', planetID, true); line.setAttribute('data-color', this.ogl.db.positions[index[0]]?.color); let button = line.querySelector('.cellPlanetName').appendChild(Util.createDom('div', {'class':'ogl_colorButton tooltipClose', 'data-color':this.ogl.db.positions[index[0]]?.color})); button.addEventListener('click', event => { let content = Util.createDom('div', {'class':'ogl_colorAll ogl_tooltipColor'}); this.ogl.component.color.addColorUI(button, content, index, event); this.ogl.component.tooltip.open(button, false, content); }); } if(line.querySelector('.microdebris')) { let element = line.querySelector('.microdebris'); let id = '#' + element.getAttribute('rel'); let total = 0; document.querySelector(id).querySelectorAll('.debris-content').forEach(resources => { let value = Util.formatFromUnits(resources.innerText.replace(/(\D*)/, '')); element.innerHTML += Util.formatToUnits(parseInt(value), 1) + '<br>'; total += parseInt(value); }); if(total >= this.ogl.db.options.rval) element.closest('.cellDebris').classList.add('ogl_active'); } document.querySelectorAll('.expeditionDebrisSlotBox:not(.ogl_debrisReady)').forEach(element => { element.classList.add('ogl_debrisReady'); let content = element.querySelectorAll('.ListLinks li'); if(!content[0]) content = document.querySelectorAll('#debris16 .ListLinks li'); let scouts = content[3]; let action = content[4]; let res = [ content[0].textContent.replace(/(\D*)/, ''), content[1].textContent.replace(/(\D*)/, ''), content[2].textContent.replace(/(\D*)/, '') ]; element.innerHTML = ` <img src="https://gf1.geo.gfsrv.net/cdnc5/fa3e396b8af2ae31e28ef3b44eca91.gif"> <div> <div class="ogl_metal">${res[0]}</div> <div class="ogl_crystal">${res[1]}</div> <div class="ogl_deut">${res[2]}</div> </div> <div> <div>${scouts.textContent}</div> <div>${action.outerHTML}</div> </div> `; }); }); if(system != 499) this.ogl.component.keyboard.sent = false; } } class MenuManager { constructor(ogl) { this.ogl = ogl; this.init(); } init() { document.querySelector('#countColonies .ogl_menuOptions')?.remove(); document.querySelector('#countColonies .ogl_panel')?.remove(); this.mainDom = document.querySelector('#countColonies').appendChild(Util.createDom('div', {'class':'ogl_menuOptions'})); this.subDom = document.querySelector('#countColonies').appendChild(Util.createDom('div', {'class':'ogl_panel'})); // main buttons this.addOptions(); this.addShips(); this.addMissions(); this.addHarvest(); // sub buttons this.addSubEco(); this.addSubProd(); this.addSubPins(); this.addSubTargets(); this.checkImportExport(); this.ogl.performances.push(['Menu',performance.now()]); } addOptions() { let button = this.mainDom.appendChild(Util.createDom('div', {'class':'material-icons ogl_manageData ogl_button'}, 'settings')); button.addEventListener('click', () => { this.ogl.component.popup.load(); let globalContainer = Util.createDom('div', {'class':'ogl_globalConfig'}); let sideContainer = globalContainer.appendChild(Util.createDom('div')); let container = globalContainer.appendChild(Util.createDom('div', {'class':'ogl_config'})); sideContainer.appendChild(Util.createDom('h1', {'class':'ogl_scriptTitle'}, `OGLight <span>(${this.ogl.version == 'beta' ? `${this.ogl.version}-${hash}` : this.ogl.version})</span>`)); sideContainer.appendChild(Util.createDom('hr')); sideContainer.appendChild(Util.createDom('p', {}, this.ogl.component.lang.getText('kofi'))); sideContainer.appendChild(Util.createDom('div', {}, "<a class='ogl_kofi' href='https://ko-fi.com/O4O22XV69' target='_blank'>Buy me a coffee</a>")); let rval = container.appendChild(Util.createDom('div', {}, '<span>Resources Value (RVal)</span>')); let rvalInput = rval.appendChild(Util.createDom('input', {'type':'text', 'class':'ogl_input'})); rvalInput.value = this.ogl.db.options.rval; let ptre = container.appendChild(Util.createDom('div', {}, '<span><a href="https://ptre.chez.gg/" target="_blank">PTRE</a> Teamkey</span>')); let ptreInput = ptre.appendChild(Util.createDom('input', {'type':'password', 'placeholder':'TM-XXXX-XXXX-XXXX-XXXX'})); if(this.ogl.ptre) ptreInput.value = this.ogl.ptre; ptreInput.addEventListener('focus', () => ptreInput.setAttribute('type', 'text')); ptreInput.addEventListener('blur', () => ptreInput.setAttribute('type', 'password')); this.ogl.component.popup.open(globalContainer); setTimeout(() => rvalInput.dispatchEvent(new Event('change')), 500); container.appendChild(Util.createDom('h2', {}, 'Interface')); let minifyPictures = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('minifyPictures')}</span>`)); let minifyToggle = minifyPictures.appendChild(Util.createDom('div', {'class':'ogl_confToggle'})); if(localStorage.getItem('ogl-minipics')) minifyToggle.classList.add('ogl_active'); minifyToggle.addEventListener('click', () => { if(localStorage.getItem('ogl-minipics')) { localStorage.removeItem('ogl-minipics'); minifyToggle.classList.remove('ogl_active'); } else { localStorage.setItem('ogl-minipics', true); minifyToggle.classList.add('ogl_active'); } }); let timezoneMode = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('timezoneMode')}</span>`)); timezoneMode.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'timezoneMode'})); let timers = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('displayTimers')}</span>`)); timers.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'timers'})); let fleetDetailsName = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('fleetDetailsName')}</span>`)); fleetDetailsName.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'fleetDetailsName'})); let rightMenuTooltips = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('rightMenuTooltips')}</span>`)); rightMenuTooltips.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'rightMenuTooltips'})); let tooltipDelay = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('tooltipDelay')}</span>`)); let tooltipDelayInput = tooltipDelay.appendChild(Util.createDom('input', {'type':'number', 'min':'0', 'max':'2000'})); tooltipDelayInput.value = this.ogl.db.options.tooltipDelay; container.appendChild(Util.createDom('h2', {}, 'Attacks & stats')); let stats = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('rentaStats')}</span>`)); stats.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'renta'})); let ignoreConsumption = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('excludeConso')}</span>`)); ignoreConsumption.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'ignoreConsumption'})); let spytable = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('spiesTable')}</span>`)); spytable.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'spytable'})); let autoclean = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('autoClean')}</span>`)); autoclean.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'autoclean'})); let ignoreExpeShips = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('ignoreExpeShips')}</span>`)); ignoreExpeShips.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'ignoreExpeShips'})); let bigShip = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('bigShip')}</span>`)); bigShip.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'bigShip'})); let ignoreVacation = container.appendChild(Util.createDom('div', {}, `<span>${this.ogl.component.lang.getText('ignoreVacation')}</span>`)); ignoreVacation.appendChild(Util.createDom('div', {'class':'ogl_confToggle ogl_active', 'data-conf':'ignoreVacation'})); container.appendChild(Util.createDom('h2', {}, 'Data')); let data; let dataDiv = container.appendChild(Util.createDom('div', {'class':'ogl_manageData'})); let resetButton = dataDiv.appendChild(Util.createDom('a', {'class':'ogl_button tooltip', 'title':'Reset all your data'}, 'RESET ALL')); resetButton.addEventListener('click', () => { if(confirm('Do you really want to reset your data ?')) { this.ogl.save({}); document.location.reload(); } }); dataDiv.appendChild(Util.createDom('a', {'class':'ogl_button tooltip', 'data-title':'Reset only your stats'}, 'RESET STATS')) .addEventListener('click', () => { if(confirm('Do you really want to reset your stats ?')) { this.ogl.db.stats = {}; this.ogl.save(); document.location.reload(); } }); dataDiv.appendChild(Util.createDom('a', {'class':'ogl_button tooltip', 'title':'Reset only your targets'}, 'RESET TARGETS')) .addEventListener('click', () => { if(confirm('Do you really want to reset your targets list ?')) { this.ogl.db.players = []; this.ogl.db.positions = []; this.ogl.db.pinnedList = []; this.ogl.db.dataFormat = 0; this.ogl.save(); document.location.reload(); } }); dataDiv.appendChild(Util.createDom('label', {'class':'ogl_button tooltip', 'for':'ogl_import', 'title':'Import data'}, 'IMPORT')); let importButton = dataDiv.appendChild(Util.createDom('input', {'id':'ogl_import', 'class':'ogl_hidden', 'type':'file'})); importButton.addEventListener('change', () => { let file = importButton.files[0]; let reader = new FileReader(); reader.onload = () => { try { JSON.parse(reader.result); } catch (e) { return false; } data = reader.result; let parsed = JSON.parse(reader.result); if(parsed.dataFormat >= 4) { this.ogl.save(parsed); document.location.reload(); } else alert(`Wrong data format`); }; reader.readAsText(file); }); let exportButton = dataDiv.appendChild(Util.createDom('a', {'class':'ogl_button', 'download':`ogl_${this.ogl.universe.name}_${this.ogl.universe.lang}_${serverTime.getTime()}`}, 'EXPORT')); exportButton.href = URL.createObjectURL(new Blob([JSON.stringify(this.ogl.db)], {type: 'application/json'})); let saveButton = dataDiv.appendChild(Util.createDom('a', {'class':'ogl_button'}, 'SAVE')); saveButton.addEventListener('click', () => { this.ogl.db.options.rval = Util.formatFromUnits(rvalInput.value || '0'); this.ogl.db.options.tooltipDelay = parseInt(tooltipDelayInput.value || '0'); this.ogl.save(); if(ptreInput.value && ptreInput.value.replace(/-/g, '').length == 18 && ptreInput.value.indexOf('TM') == 0) { localStorage.setItem('ogl-ptreTK', ptreInput.value); document.location.reload(); } else { localStorage.removeItem('ogl-ptreTK'); if(ptreInput.value) fadeBox('Error, wrong PTRE teamkey format', true); else document.location.reload(); } }); container.querySelectorAll('.ogl_confToggle[data-conf]').forEach(button => { let id = button.getAttribute('data-conf'); if(this.ogl.db.options.togglesOff.indexOf(id) > -1) button.classList.remove('ogl_active'); button.addEventListener('click', () => { let index = this.ogl.db.options.togglesOff.indexOf(id); index > -1 ? this.ogl.db.options.togglesOff.splice(index, 1) : this.ogl.db.options.togglesOff.push(id); button.classList.toggle('ogl_active'); }); }); }); } addShips() { let button = this.mainDom.appendChild(Util.createDom('div', {'class':'ogl_shipPicker ogl_button tooltipLeft tooltipClick tooltipClose', 'data-title':'loading...'}, this.ogl.component.lang.getText('abbr'+this.ogl.db.options.defaultShip))); button.addEventListener('click', () => { let cargoChoice = Util.createDom('div', {'id':'ogl_defaultShipPicker', 'class':'ogl_shipList'}); this.ogl.component.fleet.defaultShipsList.forEach(shipID => { let cargoType = cargoChoice.appendChild(Util.createDom('div', {'class':'ogl_shipIcon ogl_'+shipID})); cargoType.addEventListener('click', () => { this.ogl.db.options.defaultShip = shipID; this.ogl.save(); document.location.reload(); }); }); this.ogl.component.tooltip.update(button, cargoChoice); }); } addMissions() { let mission = this.ogl.db.options.defaultMission; this.mainDom.appendChild(Util.createDom('div', {'class':`material-icons ogl_missionPicker${this.ogl.db.options.defaultMission} ogl_button`}, this.ogl.db.options.defaultMission == 4 ? 'keyboard_tab' : 'swap_horiz')) .addEventListener('click', () => { this.ogl.db.options.defaultMission = this.ogl.db.options.defaultMission == 4 ? 3 : 4; this.ogl.save(); Util.redirect(window.location.href.replace(`&mission=${mission}`, `&mission=${this.ogl.db.options.defaultMission}`), this.ogl); }); } addHarvest() { let button = this.mainDom.appendChild(Util.createDom('div', {'class':'material-icons ogl_harvest ogl_button'}, 'all_inclusive')); let linkedButton = Util.createDom('div', {'class':'ogl_linkedHarvest ogl_button'}, this.ogl.current.type == 'moon' ? this.ogl.component.lang.getText('linkedPlanets') : this.ogl.component.lang.getText('linkedMoons')); button.addEventListener('click', () => { if(this.ogl.page == 'fleetdispatch' && (this.ogl.mode == 1 || this.ogl.mode == 4)) { Util.redirect(redirectOverviewLink, this.ogl); } else { (document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).classList.toggle('ogl_shortcuts'); button.classList.toggle('ogl_active'); document.querySelectorAll('.smallplanet > a').forEach(planet => { if(planet.closest('.ogl_shortcuts')) { planet.addEventListener('click', event => { event.preventDefault(); this.ogl.db.collectSource = [...this.ogl.current.coords, ...[this.ogl.current.type == 'planet' ? '1' : '3']]; this.ogl.db.collectDestination = planet.closest('.smallplanet').querySelector('.planet-koords').textContent.slice(1, -1).split(':'); planet.classList.contains('moonlink') ? this.ogl.db.collectDestination.push('3') : this.ogl.db.collectDestination.push('1'); this.ogl.save(); Util.redirect(`https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=1&galaxy=${this.ogl.db.collectDestination[0]}&system=${this.ogl.db.collectDestination[1]}&position=${this.ogl.db.collectDestination[2]}&type=${this.ogl.db.collectDestination[3]}&mission=${this.ogl.db.options.defaultMission}`, this.ogl); }); } }); linkedButton.classList.toggle('ogl_active'); } }); if(this.ogl.page == 'fleetdispatch' && (this.ogl.mode == 1 || this.ogl.mode == 4)) { button.classList.add('ogl_active'); } document.querySelector('#countColonies').parentNode.insertBefore(linkedButton, document.querySelector('#planetList')); linkedButton.addEventListener('click', () => { if(this.ogl.current.smallplanet.querySelector('.moonlink')) { this.ogl.db.collectSource = [...this.ogl.current.coords, ...[this.ogl.current.type == 'planet' ? '1' : '3']]; this.ogl.save(); Util.redirect(`https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=4&type=${this.ogl.current.type == 'planet' ? '3' : '1'}&mission=${this.ogl.db.options.defaultMission}`, this.ogl); } else { this.ogl.db.collectSource = [...this.ogl.next.smallplanetWithMoon.querySelector('.planet-koords').textContent.slice(1, -1).split(':'), ...[this.ogl.current.type == 'planet' ? '3' : '1']]; this.ogl.save(); let cp = this.ogl.current.type == 'planet' ? new URL(this.ogl.next.smallplanetWithMoon.querySelector('a.planetlink').href).searchParams.get('cp') : new URL(this.ogl.next.smallplanetWithMoon.querySelector('a.moonlink').href).searchParams.get('cp'); Util.redirect(`https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=4&cp=${cp}&type=${this.ogl.current.type == 'planet' ? '1' : '3'}&mission=${this.ogl.db.options.defaultMission}`, this.ogl); } }); } addSubEco() { let button = this.subDom.appendChild(Util.createDom('div', {'class':'material-icons tooltip ogl_button', 'title':this.ogl.component.lang.getText('economyView')}, 'account_balance')); document.querySelectorAll('.planetlink, .moonlink').forEach(element => { let coords = element.parentNode.querySelector('.planet-koords').textContent.slice(1, -1); if(element.classList.contains('moonlink')) coords += ':M'; let container = element.appendChild(Util.createDom('div', {'class':'ogl_stock'})); let deltaTime = Math.floor((serverTime.getTime() - this.ogl.db.me.planets[coords]?.production?.[3] || 0) / 1000); deltaTime = 0; ['metal', 'crystal', 'deut'].forEach((res, index) => { let oldValue = this.ogl.db.me.planets[coords]?.resources?.[res] || 0; let storage = this.ogl.db.me.planets?.[coords]?.storage?.[res]; let prodSinceLastUpdate = (this.ogl.db.me.planets[coords]?.production?.[index] || 0) * deltaTime; let newValue = Math.floor(oldValue + prodSinceLastUpdate); let item = container.appendChild(Util.createDom('div', {'class':`ogl_${res}`})); if(!element.classList.contains('moonlink') && storage) { if(oldValue < storage && newValue >= storage) newValue = storage; if(newValue >= storage) item.classList.add('ogl_full'); } item.textContent = Util.formatToUnits(newValue); item.setAttribute('data-value', newValue); }); }); button.addEventListener('click', () => { if((document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).getAttribute('data-panel')) { (document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).removeAttribute('data-panel'); this.ogl.db.menuView = false; // this.ogl.saveAsync(); } else { (document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).setAttribute('data-panel', 'resources'); this.ogl.db.menuView = 'resources'; // this.ogl.saveAsync(); } }); if(this.ogl.db.menuView == 'resources') (document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).setAttribute('data-panel', 'resources'); } addSubProd() { let button = this.subDom.appendChild(Util.createDom('div', {'class':'tooltip ogl_button', 'title':this.ogl.component.lang.getText('productionView')}, 'ø')); button.addEventListener('click', () => { this.ogl.component.popup.load(); let container = Util.createDom('div', {'class':'ogl_mineContainer'}); let sum = [0,0,0]; let sumProd = [0,0,0]; let count = 0; container.appendChild(Util.createDom('span', {'class':'ogl_header'}, ' ')); container.appendChild(Util.createDom('span', {'class':'ogl_header'}, ' ')); container.appendChild(Util.createDom('span', {'class':'ogl_header'}, ' ')); container.appendChild(Util.createDom('span', {'class':'ogl_header'}, ' ')); let headerMetal = container.appendChild(Util.createDom('b', {'class':'ogl_metal ogl_header'})); let headerCrystal = container.appendChild(Util.createDom('b', {'class':'ogl_crystal ogl_header'})); let headerDeut = container.appendChild(Util.createDom('b', {'class':'ogl_deut ogl_header'})); document.querySelectorAll('.smallplanet').forEach(planet => { let name = planet.querySelector('.planet-name').textContent; let coords = planet.querySelector('.planet-koords').textContent.slice(1, -1); let upgrading = planet.querySelector('.constructionIcon'); if(this.ogl.db.me.planets[coords]) { let fieldUsed = this.ogl.db.me.planets[coords].fieldUsed || 0; let fieldMax = this.ogl.db.me.planets[coords].fieldMax || 0; let newLine = container.appendChild(Util.createDom('span', {}, `[${coords}]`)); if(planet.getAttribute('data-multi')) newLine.setAttribute('data-multi', planet.getAttribute('data-multi')); container.appendChild(Util.createDom('i', {}, name)); container.appendChild(Util.createDom('i', {}, `${fieldUsed || '?'}/${fieldMax || '?'} (<strong>${fieldMax-fieldUsed}</strong>)`)); let temperature = container.appendChild(Util.createDom('i', {}, (this.ogl.db.me.planets[coords].temperature || '?') + '°C')); if(this.ogl.db.me.planets[coords].temperature >= 150) temperature.style.color = "#af644d"; // too hot else if(this.ogl.db.me.planets[coords].temperature >= 50) temperature.style.color = "#af9e4d"; // hot else if(this.ogl.db.me.planets[coords].temperature >= 0) temperature.style.color = "#4daf67"; // normal else if(this.ogl.db.me.planets[coords].temperature >= -100) temperature.style.color = "#4dafa6"; // cold else temperature.style.color = "#4d79af"; // too cold let metalLevel = (upgrading && this.ogl.db.me.planets[coords].upgrade?.[0] == 1) ? `(${this.ogl.db.me.planets[coords].upgrade?.[1]})` : (this.ogl.db.me.planets[coords]?.techs?.[1] || '?'); let crystalLevel = (upgrading && this.ogl.db.me.planets[coords].upgrade?.[0] == 2) ? `(${this.ogl.db.me.planets[coords].upgrade?.[1]})` : (this.ogl.db.me.planets[coords]?.techs?.[2] || '?'); let deutLevel = (upgrading && this.ogl.db.me.planets[coords].upgrade?.[0] == 3) ? `(${this.ogl.db.me.planets[coords].upgrade?.[1]})` : (this.ogl.db.me.planets[coords]?.techs?.[3] || '?'); container.appendChild(Util.createDom('b', {'class':'ogl_metal'}, metalLevel + `<div>+${Util.formatToUnits(Math.round((this.ogl.db.me.planets[coords]?.production[0] || 0) * 60 * 60 * 24))}</div>`)); container.appendChild(Util.createDom('b', {'class':'ogl_crystal'}, crystalLevel + `<div>+${Util.formatToUnits(Math.round((this.ogl.db.me.planets[coords]?.production[1] || 0) * 60 * 60 * 24))}</div>`)); container.appendChild(Util.createDom('b', {'class':'ogl_deut'}, deutLevel + `<div>+${Util.formatToUnits(Math.round((this.ogl.db.me.planets[coords]?.production[2] || 0) * 60 * 60 * 24))}</div>`)); sum = [sum[0] + parseInt(this.ogl.db.me.planets[coords]?.techs?.[1] || 0), sum[1] + parseInt(this.ogl.db.me.planets[coords]?.techs?.[2] || 0), sum[2] + parseInt(this.ogl.db.me.planets[coords]?.techs?.[3] || 0)]; sumProd = [sumProd[0] + (this.ogl.db.me.planets[coords]?.production?.[0] || 0) * 60 * 60 * 24, sumProd[1] + (this.ogl.db.me.planets[coords]?.production?.[1] || 0) * 60 * 60 * 24, sumProd[2] + (this.ogl.db.me.planets[coords]?.production?.[2] || 0) * 60 * 60 * 24]; count++; } }); headerMetal.innerHTML = 'ø ' + (sum[0] / count).toFixed(1) + `<div>+${Util.formatToUnits(Math.round(sumProd[0]))}</div>`; headerCrystal.innerHTML = 'ø ' + (sum[1] / count).toFixed(1) + `<div>+${Util.formatToUnits(Math.round(sumProd[1]))}</div>`; headerDeut.innerHTML = 'ø ' + (sum[2] / count).toFixed(1) + `<div>+${Util.formatToUnits(Math.round(sumProd[2]))}</div>`; let shareButton = Util.createDom('div', {'class':'ogl_button'}, '<i class="material-icons">file_download</i>Download (.jpg)'); shareButton.addEventListener('click', () => { shareButton.textContent = 'loading...'; shareButton.classList.add('ogl_disabled'); Util.takeScreenshot(container, shareButton, `ogl_${this.ogl.universe.name}_${this.ogl.universe.lang}_empire_${serverTime.getTime()}`); }); this.ogl.component.popup.open(container, () => { this.ogl.component.popup.content.appendChild(shareButton); }); }); } addSubPins() { let button = this.subDom.appendChild(Util.createDom('div', {'class':'material-icons tooltip ogl_button', 'title':this.ogl.component.lang.getText('pinnedView')}, 'push_pin')); button.addEventListener('click', () => this.ogl.component.sidebar?.displayPinnedList()); } addSubTargets() { let button = this.subDom.appendChild(Util.createDom('div', {'class':'material-icons tooltip ogl_button', 'title':this.ogl.component.lang.getText('targetView')}, 'gps_fixed')); button.addEventListener('click', () => this.ogl.component.sidebar?.displayTargetList()); } checkImportExport() { if(this.ogl.db.nextImportExport < Date.now()) { document.querySelector('.menubutton[href*=traderOverview]').classList.add('ogl_active'); } window.addEventListener('beforeunload', () => { let textTarget = document.querySelector('.bargain_text'); let button = document.querySelector('.import_bargain.hidden'); if(textTarget && button) { let today = new Date(serverTime.getTime()); let tomorow = new Date(serverTime.getTime() + 86400000); if(textTarget.textContent.match(/\d+/g)) { this.ogl.db.nextImportExport = new Date(today.getFullYear(), today.getMonth(), today.getDate(), textTarget.textContent.match(/\d+/g)[0], 0, 0).getTime(); } else { this.ogl.db.nextImportExport = new Date(tomorow.getFullYear(), tomorow.getMonth(), tomorow.getDate(), 8, 0, 0).getTime(); } this.ogl.save(); } else if(textTarget && textTarget.textContent == '') { this.ogl.db.nextImportExport = serverTime.getTime(); this.ogl.save(); } }); } }class ColorManager { constructor(ogl) { this.ogl = ogl; this.colors = ['red', 'halfred', 'yellow', 'halfyellow', 'green', 'halfgreen', 'blue', 'halfblue', 'violet', 'halfviolet', 'gray', 'none']; } addColorUI(sender, parent, planetIDs, clickEvent, callback) { let container = parent.appendChild(Util.createDom('div', {'class':'ogl_colors'})); this.colors.forEach(color => { let button = container.appendChild(Util.createDom('div', {'data-color':color})); button.addEventListener('click', () => { planetIDs.forEach(planetID => { this.ogl.db.positions[planetID].colorID = this.ogl.db.positions[planetID].playerID; if(planetIDs.length == 1 && this.ogl.db.positions[planetID].color == color) color = false; this.ogl.db.positions[planetID].color = color; this.ogl.db.lastColorUsed = color; if(document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'targetList') { let target = document.querySelector(`.ogl_sideView [data-planetID="${this.ogl.db.positions[planetID].id}"]`); if(target) { target.setAttribute('data-color', color); if(color == 'none' || color == false) target.remove(); } else if(!target && color != 'none' && color != false) { this.ogl.component.sidebar?.displayTargetList(); } } }); if(sender) { sender.setAttribute('data-color', color); if(sender.closest('.row')) sender.closest('.row').setAttribute('data-color', color); if(sender.closest('.galaxyRow')) sender.closest('.galaxyRow').setAttribute('data-color', color); if(sender.closest('.ogl_spyTable')) sender.closest('[data-coords]').setAttribute('data-color', color); } if(callback) callback(color); setTimeout(() => this.ogl.component.tooltip.close(true), 100); // this.ogl.saveAsync(); if(document.querySelector('.ogl_sideView.ogl_active') && this.ogl.db.sidebarView == 'pinned') this.ogl.component.sidebar?.displayPinnedTarget(); if(planetIDs.length > 1) submitForm(); }); if(color == 'none') color = false; if(clickEvent && clickEvent.shiftKey && color == this.ogl.db.lastColorUsed) { button.click(); } }); } } class TooltipManager { constructor(ogl) { this.ogl = ogl; this.ogl.tooltipList = this.ogl.tooltipList || {}; this.ogl.tmpTooltip = this.ogl.tmpTooltip || {}; this.dom = document.body.appendChild(Util.createDom('div', {'class':'ogl_tooltip tpd-tooltip'})); this.cross = this.dom.appendChild(Util.createDom('div', {'class':'ogl_close material-icons ogl_hidden'}, 'clear')); this.container = this.dom.appendChild(Util.createDom('div', {})); this.openDelay = this.ogl.db.options.tooltipDelay; this.closeDelay = 1; this.updateDelay = 50; this.openTimer; this.updateTimer; document.addEventListener('click', e => { if(!this.dom.classList.contains('ogl_active') && !this.dom.classList.contains('ogl_highlight')) return; if(e.target != this.dom && !e.target.closest('.ogl_tooltip')) { this.lastSender = false; this.close(true); } }); this.dom.addEventListener('mouseout', e => { let target = e.toElement || e.relatedTarget || e.target; if(!this.dom.contains(target) && target != this.lastSender && this.cross.classList.contains('ogl_hidden') && !target.classList.contains('ogl_highlight')) { this.timer = setTimeout(e => this.close(), this.tooltipDelay); } }); this.cross.addEventListener('click', () => this.close()); this.ogl.observeMutation(() => this.initTooltip(), 'tooltip'); this.ogl.performances.push(['Tooltip',performance.now()]); } initTooltip() { let senderList = document.querySelectorAll(`[class*="tooltip"]:not(.ogl_tooltipReady)`); senderList.forEach((sender, index) => { setTimeout(() => { if(sender.classList.contains('ogl_tooltipReady') || !this.ogl.component.tooltip || sender.closest('.ogl_tooltipReady')) return; if(!sender.classList.contains('tooltipRel') && !sender.getAttribute('title') && !sender.getAttribute('data-title')); sender.classList.add('ogl_tooltipReady'); if(sender.parentNode && sender.parentNode.closest('.ogl_tooltipReady')) return; if(this.ogl.db.options.togglesOff.indexOf('rightMenuTooltips') == -1 && (sender.classList.contains('planetlink') || sender.classList.contains('moonlink'))) { sender.removeAttribute('title'); return; } if(sender.getAttribute('title') && !sender.getAttribute('data-title')) { sender.setAttribute('data-title', sender.getAttribute('title')); if(!sender.classList.contains('icon_apikey')) sender.removeAttribute('title'); } let tooltipID; if(sender.classList.contains('icon_apikey') || sender.classList.contains('show_fleet_apikey')) { sender.classList.add('tooltipClick'); } if(sender.classList.contains('tooltipRel')) { let id = '#' + sender.getAttribute('rel'); tooltipID = id; } if(sender.classList.contains('tooltipClick')) { sender.addEventListener('click', e => { if(e.target != sender) this.close(); this.lastSender = sender; this.open(sender, tooltipID); }); sender.addEventListener('mouseenter', e => { clearTimeout(this.openTimer); clearTimeout(this.updateTimer); }); } else { sender.addEventListener('mouseenter', e => { clearTimeout(this.openTimer); if(e.target != sender) this.close(); if(this.ogl.component.tooltip.dom.contains(sender)) return; if(sender == this.lastSender && (sender.getAttribute('data-title') == 'loading...' || this.dom.classList.contains('.ogl_active'))) return; this.lastSender = sender; if(sender.getAttribute('data-title') == 'loading...') { this.open(sender, tooltipID); } else { this.openTimer = setTimeout(() => this.open(sender, tooltipID), this.openDelay); } }); sender.addEventListener('mouseout', e => { if(sender.contains(e.toElement) || (sender.classList.contains('tooltipClose') && this.dom.classList.contains('.ogl_active'))) return; clearTimeout(this.openTimer); clearTimeout(this.updateTimer); if(!this.cross.classList.contains('ogl_hidden')) return; this.closeTimer = setTimeout(e => this.close(), this.closeDelay); }); } //if(index == senderList.length-1) document.body.classList.remove('ogl_noPointer'); }, index); }); } rebuildTooltip(sender) { let rect = sender.getBoundingClientRect(); let win = sender.ownerDocument.defaultView; this.position = { x:rect.left + win.pageXOffset, y:rect.top + win.pageYOffset }; this.dom.style.top = 0 + 'px'; this.dom.style.left = 0 + 'px'; this.dom.style.width = 'auto'; let tooltipWidth = this.dom.offsetWidth + 3; if(sender.classList.contains('tooltipClose') || sender.classList.contains('tooltipCustom') || sender.classList.contains('tooltipRel')) { this.cross.classList.remove('ogl_hidden'); this.dom.classList.remove('ogl_noPointer'); } else { this.cross.classList.add('ogl_hidden'); this.dom.classList.add('ogl_noPointer'); } if(sender.classList.contains('tooltipLeft')) { this.dom.classList.add('ogl_left'); this.position.x -= this.dom.offsetWidth + 5; this.position.y -= this.dom.offsetHeight / 2; this.position.y += rect.height / 2; } else if(sender.classList.contains('tooltipRight')) { this.dom.classList.add('ogl_right'); this.position.x += rect.width + 5; this.position.y -= this.dom.offsetHeight / 2; this.position.y += rect.height / 2; } else if(sender.classList.contains('tooltipRightTop')) { this.dom.classList.add('ogl_rightTop'); this.position.x += rect.width; this.position.y -= this.dom.offsetHeight - 20; this.position.y += rect.height / 2; } else if(sender.classList.contains('tooltipBottom')) { this.dom.classList.add('ogl_bottom'); this.position.x -= this.dom.offsetWidth / 2; this.position.x += rect.width / 2; this.position.y += rect.height; } else { this.position.x -= this.dom.offsetWidth / 2; this.position.x += rect.width / 2; this.position.y -= this.dom.offsetHeight; this.position.y -= 4; } this.position.x = Math.round(this.position.x); this.position.y = Math.round(this.position.y); this.position.x = this.position.x - (this.position.x % 2); this.position.y = this.position.y - (this.position.y % 2); this.dom.style.top = this.position.y + 'px'; this.dom.style.left = this.position.x + 'px'; this.dom.style.width = tooltipWidth + 'px'; setTimeout(() => { if(this.container.textContent.trim() != '' || this.container.innerHTML != '') this.dom.classList.add('ogl_active'); }, 10); } open(sender, tooltipID, data) { clearTimeout(this.closeTimer); if(sender != this.lastSender) this.close(); else if(sender.classList.contains('ogl_highlight')) return; let content; this.container.textContent = ''; //if(tooltipID) content = this.ogl.tooltipList[tooltipID] || this.ogl.tmpTooltip[tooltipID]; if(tooltipID) content = document.querySelector(`${tooltipID}`).outerHTML; else if(data) content = data; else { content = sender.getAttribute('title') || sender.getAttribute('data-title'); if(content) sender.setAttribute('data-title', content); } if(!content) { this.close(); return; } document.querySelectorAll('.ogl_highlight').forEach(e => e.classList.remove('ogl_highlight')); sender.classList.add('ogl_highlight'); if(typeof content == 'object' && content.style && content.style.display == 'none') content.style.display = 'block'; typeof content == 'object' ? this.container.appendChild(content) : this.container.innerHTML = content; if(this.container.textContent.indexOf('|') > -1) this.container.innerHTML = this.container.innerHTML.replace(/\|/g, '<div class="splitLine"></div>'); // remove right menu tooltip on fleet 2 if(sender.closest('.ogl_shortcuts') && (sender.classList.contains('planetlink') || sender.classList.contains('moonlink'))) return; sender.removeAttribute('title'); if(this.updateBeforeDisplay(sender)) return; this.dom.className = 'ogl_tooltip tpd-tooltip'; this.dom.style.width = 'auto'; this.rebuildTooltip(sender); } update(sender, newData) { let excludedClasses = ['ogl_capacityContainer', 'ogl_resourceSaver']; let delay = sender.getAttribute('data-title') == 'loading...' ? 0 : this.openDelay + this.updateDelay; if(sender.className.trim().split(' ').filter(e => excludedClasses.includes(e)).length > 0) delay = 0; clearTimeout(this.openTimer); clearTimeout(this.updateTimer); this.updateTimer = setTimeout(() => { if(sender != this.lastSender) return; this.container.textContent = ''; if(!newData) return; typeof newData == 'object' ? this.container.appendChild(newData) : this.container.innerHTML = newData; this.rebuildTooltip(sender); }, delay); } close(forced) { clearTimeout(this.closeTimer); let ignore = false; document.querySelectorAll(':hover').forEach(element => { if(element.classList.contains('ogl_tooltip')) ignore = true; if(element.classList.contains('ogl_highlight')) ignore = true; if(element.classList.contains('ogl_close')) ignore = false; }); if(!ignore || forced) { document.querySelectorAll('.ogl_highlight').forEach(e => e.classList.remove('ogl_highlight')); this.dom.classList.remove('ogl_active'); this.lastSender = false; } } updateBeforeDisplay(sender) { if(this.container.querySelector('.fleetinfo')) { if(sender.closest('.allianceAttack')) { this.container.querySelector('.fleetinfo').classList.add('ogl_ignored'); return; } this.container.querySelectorAll('.fleetinfo tr').forEach(line => { if(line.textContent.trim() == '') line.classList.add('ogl_hidden'); else if(!line.querySelector('td')) line.classList.add('ogl_full'); else { let name = line.querySelector('td').textContent.replace(':', ''); let id = (Object.entries(this.ogl.db.ships).find(e => e[1].name == name) || [false])[0]; if(!id) id = Util.findObjectByValue(this.ogl.db.loca, line.querySelector('td').textContent.replace(':', '')) || -1 if(id && line.querySelector('.value')) { line.classList.add('ogl_'+id); line.querySelector('td').textContent = ''; line.querySelector('td').className = 'ogl_shipIcon ogl_'+id; line.title = line.querySelector('.value').textContent; line.querySelector('.value').textContent = Util.formatToUnits(line.querySelector('.value').textContent); if(this.ogl.db.options.togglesOff.indexOf('fleetDetailsName') == -1) { line.appendChild(Util.createDom('div', {'class':'fleetDetailsName'}, name)); line.classList.add('ogl_activeNames'); } } } }); this.container.querySelector('h1').remove(); this.container.querySelector('.splitLine').remove(); this.container.querySelector('.ogl_full').remove(); } if(sender.classList.contains('moonlink')) { sender.classList.add('tooltipRight'); sender.classList.remove('tooltipLeft'); if(this.ogl.db.options.togglesOff.indexOf('rightMenuTooltips') == -1) { return true; } } else if(sender.classList.contains('planetlink')) { sender.classList.remove('tooltipRight'); sender.classList.add('tooltipLeft'); //this.position.x += sender.closest('[data-panel="stock"]') ? 80 : 45; //this.container.querySelectorAll('a').forEach(e => e.remove()); if(this.ogl.db.options.togglesOff.indexOf('rightMenuTooltips') == -1) { return true; } } if(sender.closest('#top') || sender.closest('#box')) { sender.classList.add('tooltipBottom'); sender.classList.remove('tooltip'); } } } class FleetManager { constructor(ogl) { this.ogl = ogl; this.spyReady = true; // add "shortcut" icons document.querySelectorAll('.smallplanet > a.planetlink, .smallplanet > a.moonlink').forEach(link => { if(link.classList.contains('planetlink')) link.parentNode.setAttribute('data-coords', link.querySelector('.planet-koords').textContent.slice(1, -1)); if(!link.querySelector('.ogl_shortcut')) link.appendChild(Util.createDom('div', {'class':'material-icons ogl_shortcut'}, 'flag')); }); this.shipsList = [202,203,204,205,206,207,208,209,210,211,213,214,215,217,218,219]; this.defaultShipsList = [202,203,219,210]; this.checkFleetMovement(); if(this.ogl.page == 'fleetdispatch' || this.ogl.page == 'shipyard') this.updateShipsTooltip(); if(this.ogl.page != 'fleetdispatch') return; // language names this.ogl.db.loca.metal = loca.LOCA_ALL_METAL; this.ogl.db.loca.crystal = loca.LOCA_ALL_CRYSTAL; this.ogl.db.loca.deut = loca.LOCA_ALL_DEUTERIUM; this.ogl.db.loca.food = loca.LOCA_ALL_FOOD; this.ogl.db.loca.dm = LocalizationStrings.darkMatter; this.ogl.db.loca.item = 'Item'; this.ogl.db.loca.conso = loca.LOCA_FLEET_FUEL_CONSUMPTION; this.ogl.db.loca.energy = resourcesBar.resources.energy.tooltip.split('|')[0]; this.ogl.db.servertTimezone = serverTimeZoneOffsetInMinutes * 60000; this.ogl.db.clientTimezone = localTimeZoneOffsetInMinutes * 60000; // fleetDispatcher variables name this.resourceNames = [loca.LOCA_ALL_METAL, loca.LOCA_ALL_CRYSTAL, loca.LOCA_ALL_DEUTERIUM, loca.LOCA_ALL_FOOD]; this.selectKeys = ['selectMaxMetal', 'selectMaxCrystal', 'selectMaxDeuterium', 'selectMaxFood']; this.resourceOnKeys = ['metalOnPlanet', 'crystalOnPlanet', 'deuteriumOnPlanet', 'foodOnPlanet']; this.cargoKeys = ['cargoMetal', 'cargoCrystal', 'cargoDeuterium', 'cargoFood']; this.resourceKeys = ['metal', 'crystal', 'deut', 'food']; // wait for fleetDispatcher to be ready if(fleetDispatcher && !fleetDispatcher.fetchTargetPlayerDataTimeout) { this.ogl.component.popup.load(true); // force shipsData fetch if(!unsafeWindow.shipsData || !fleetDispatcher?.fleetHelper?.shipsData) { let params = {}; fleetDispatcher.appendShipParams(params); fleetDispatcher.appendTargetParams(params); fleetDispatcher.appendTokenParams(params); params.union = fleetDispatcher.union; $.post(fleetDispatcher.checkTargetUrl, params, response => { let data = JSON.parse(response); fleetDispatcher.fleetHelper.shipsData = data.shipsData; fleetDispatcher.updateToken(data.newAjaxToken); this.init(); }); } else this.init(); } else setTimeout(() => this.ogl.component.fleet = new FleetManager(this.ogl), 30); // replace default fleet movement (page movement) } init() { this.ogl.component.popup.close(); fleetDispatcher.refreshDataAfterAjax = function (data) { this.setOrders(data.orders); if(!fleetDispatcher.isInitialized) { fleetDispatcher.isInitialized = true; return; } this.setTargetInhabited(data.targetInhabited); this.setTargetPlayerId(data.targetPlayerId); this.setTargetPlayerName(data.targetPlayerName); this.setTargetIsStrong(data.targetIsStrong); this.setTargetIsOutlaw(data.targetIsOutlaw); this.setTargetIsBuddyOrAllyMember(data.targetIsBuddyOrAllyMember); this.setTargetPlayerColorClass(data.targetPlayerColorClass); this.setTargetPlayerRankIcon(data.targetPlayerRankIcon); this.setPlayerIsOutlaw(data.playerIsOutlaw); this.setTargetPlanet(data.targetPlanet); }; fleetDispatcher.apiTechData.forEach(tech => this.ogl.db.me.techs[tech[0]] = tech[1]); this.shipsList.forEach(shipID => { if(fleetDispatcher.fleetHelper.shipsData?.[shipID]) { this.ogl.db.ships[shipID] = {}; this.ogl.db.ships[shipID].name = fleetDispatcher.fleetHelper.shipsData[shipID].name; this.ogl.db.ships[shipID].capacity = fleetDispatcher.fleetHelper.shipsData[shipID].cargoCapacity || fleetDispatcher.fleetHelper.shipsData[shipID].baseCargoCapacity; this.ogl.db.ships[shipID].speed = fleetDispatcher.fleetHelper.shipsData[shipID].speed; } }); this.initialDeutOnPlanet = fleetDispatcher.deuteriumOnPlanet; // update "[resource]OnPlanet" fleetDispatcher variables this.resourceOnKeys.forEach((resourceOnKey, index) => { fleetDispatcher[resourceOnKey] = Math.max(0, this.ogl.current[this.resourceKeys[index]] - this.ogl.db.options.resSaver[index]) || 0; }); this.totalOnPlanet = fleetDispatcher.metalOnPlanet + fleetDispatcher.crystalOnPlanet + fleetDispatcher.deuteriumOnPlanet + fleetDispatcher.foodOnPlanet || this.ogl.current.metal + this.ogl.current.crystal + this.ogl.current.deut + this.ogl.current.food || 0; this.updatePlanetList(); this.updatePrevNextLink(); if(fleetDispatcher.shipsOnPlanet.length == 0 || document.querySelector('#fleet1 #warning')) return; if(!fleetDispatcher.fleetHelper?.getShipData) { fleetDispatcher.fleetHelper.getShipData = shipID => { return shipsData[shipID]; } } // this.ogl.saveAsync(); this.addRequired(); this.addReverse(); this.addCapacity(); this.overWriteEnterKey(); this.replaceSpeedSelector(); this.planetsAreDestinations(); this.resourcesSaving(); // select max resources ignoring resource saving fleetDispatcher.selectForcedMaxAll = () => { // ignore resSaver variables this.resourceOnKeys.forEach((resourceOnKey, index) => { fleetDispatcher[resourceOnKey] = Math.max(0, this.ogl.current[this.resourceKeys[index]]); }); fleetDispatcher.selectMaxAll(); fleetDispatcher.refresh(); this.resourceOnKeys.forEach((resourceOnKey, index) => { fleetDispatcher[resourceOnKey] = Math.max(0, this.ogl.current[this.resourceKeys[index]] - this.ogl.db.options.resSaver[index]); }); } document.querySelector('#loadAllResources').addEventListener('click', event => { if(event.shiftKey) { event.preventDefault(); setTimeout(() => fleetDispatcher.selectForcedMaxAll()); } }); for(let i=0; i<3; i++) { document.querySelector('#'+this.selectKeys[i]).addEventListener('click', event => { fleetDispatcher[this.cargoKeys[i]] = 0; if(event.shiftKey) { event.preventDefault(); setTimeout(() => { fleetDispatcher[this.resourceOnKeys[i]] = Math.max(0, this.ogl.current[this.resourceOnKeys[i]]); fleetDispatcher[this.selectKeys[i]](); fleetDispatcher.refresh(); fleetDispatcher[this.resourceOnKeys[i]] = Math.max(0, this.ogl.current[this.resourceOnKeys[i]] - this.ogl.db.options.resSaver[i]); }); } }); } let unload = document.querySelector('#loadAllResources').parentNode.appendChild(Util.createDom('div', {'class':'ogl_unloadAllResources'}, '0')); unload.addEventListener('click', () => { fleetDispatcher.cargoMetal = 0; fleetDispatcher.cargoCrystal = 0; fleetDispatcher.cargoDeuterium = 0; fleetDispatcher.cargoFood = 0; fleetDispatcher.refresh(); }); this.overWriteFleetDispatcher('selectShip', (shipID, amount) => { document.querySelector(`[data-technology="${shipID}"]`).classList.remove('ogl_notEnoughShips') let available = fleetDispatcher.shipsOnPlanet.find(e => e.id == this.ogl.db.options.defaultShip)?.number || 0; if(amount > available) { document.querySelector(`[data-technology="${shipID}"]`).classList.add('ogl_notEnoughShips'); setTimeout(() => document.querySelector(`[data-technology="${shipID}"]`).classList.remove('ogl_notEnoughShips'), 3000); } amount = Math.min(available, amount); this.cargoMax = fleetDispatcher.getCargoCapacity(); this.cargoList = [fleetDispatcher.cargoMetal, fleetDispatcher.cargoCrystal, fleetDispatcher.cargoDeuterium]; }, shipID => { if(this.cargoMax <= fleetDispatcher.getCargoCapacity() && this.cargoList.reduce((a, b) => a+b) > 0) { fleetDispatcher.cargoMetal = this.cargoList[0]; fleetDispatcher.cargoCrystal = this.cargoList[1]; fleetDispatcher.cargoDeuterium = this.cargoList[2]; } setTimeout(() => document.querySelector(`[data-technology="${shipID}"] input`)?.dispatchEvent(new Event('change')), 10); }); if(this.ogl.mode == 1 || this.ogl.mode == 4) this.collectResources(); if(this.ogl.mode == 3) { let cumul = [0, 0, 0]; let destination = `${fleetDispatcher.targetPlanet.galaxy}:${fleetDispatcher.targetPlanet.system}:${fleetDispatcher.targetPlanet.position}`; this.ogl.db.lockedList.forEach(key => { if(this.ogl.db.lock[destination][key]) { cumul[0] += this.ogl.db.lock[destination][key].metal; cumul[1] += this.ogl.db.lock[destination][key].crystal; cumul[2] += this.ogl.db.lock[destination][key].deut; } }); let resToSend = [Math.min(cumul[0], fleetDispatcher.metalOnPlanet), Math.min(cumul[1], fleetDispatcher.crystalOnPlanet), Math.min(cumul[2], fleetDispatcher.deuteriumOnPlanet)]; let shipsAmount = this.calcRequiredShips(this.ogl.db.options.defaultShip, Math.min(resToSend[0] + resToSend[1] + resToSend[2])); fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, shipsAmount); fleetDispatcher.cargoDeuterium = Math.min(resToSend[2], fleetDispatcher.getDeuteriumOnPlanetWithoutConsumption(), fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoCrystal = Math.min(resToSend[1], fleetDispatcher.crystalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoMetal = Math.min(resToSend[0], fleetDispatcher.metalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.refresh(); this.overWriteFleetDispatcher('submitFleet2', () => { this.ogl.db.lockedList.forEach(key => { if(this.ogl.db.lock[destination][key]) { if(cumul[0] > 0) { let metalSent = Math.max(this.ogl.db.lock[destination][key].metal - fleetDispatcher.cargoMetal, 0); cumul[0] -= metalSent; this.ogl.db.lock[destination][key].metal = metalSent; } if(cumul[1] > 0) { let crystalSent = Math.max(this.ogl.db.lock[destination][key].crystal - fleetDispatcher.cargoCrystal, 0); cumul[1] -= crystalSent; this.ogl.db.lock[destination][key].crystal = crystalSent; } if(cumul[2] > 0) { let deutSent = Math.max(this.ogl.db.lock[destination][key].deut - fleetDispatcher.cargoDeuterium, 0); cumul[2] -= deutSent; this.ogl.db.lock[destination][key].deut = deutSent; } //if(this.ogl.db.lock[destination][key].metal == 0 && this.ogl.db.lock[destination][key].crystal == 0 && this.ogl.db.lock[destination][key].deut == 0) delete(this.ogl.db.lock[destination][key]); } }); this.ogl.save(); }); } this.overWriteFleetDispatcher('setTargetPlanet', false, () => { // preselect default mission if(fleetDispatcher.union) { fleetDispatcher.mission = 2; fleetDispatcher.refresh(); // update ACS data let acsArrivalTime = (Object.values(fleetDispatcher.unions).find(a => a.id == fleetDispatcher.union)?.time || 0) * 1000; if(acsArrivalTime) { document.querySelector('.ogl_acsInfo') && document.querySelector('.ogl_acsInfo').remove(); let li = Util.createDom('li', {'class':'ogl_acsInfo'}, 'acs:'); document.querySelector('#fleetBriefingPart1').prepend(li); let span = li.appendChild(Util.createDom('span', {'class':'value'})); let spanOffset = span.appendChild(Util.createDom('span')); let count = span.appendChild(Util.createDom('span', {'class':'ogl_warning'})); this.acsInterval = setInterval(() => { if(!fleetDispatcher.getDuration()) return; let newTime = serverTime.getTime() + fleetDispatcher.getDuration() * 1000; let acsTime = acsArrivalTime; let tl = acsTime - serverTime.getTime(); let tl3 = tl * 30 / 100; let delta = newTime - acsTime; let offset = tl3 - delta; if(delta > 0) { spanOffset.textContent = `+${new Date(delta).toISOString().slice(11,19)}`; spanOffset.classList.add('ogl_danger'); } else { spanOffset.textContent = '+00:00:00'; spanOffset.classList.remove('ogl_danger'); } if(delta < tl3) count.textContent = `${new Date(offset).toISOString().slice(11,19)}`; else count.textContent = 'too late'; if(!fleetDispatcher.union) { clearInterval(this.acsInterval); document.querySelector('.ogl_acsInfo') && document.querySelector('.ogl_acsInfo').remove(); } }, 333); } } if(!fleetDispatcher.mission) { fleetDispatcher.mission = this.ogl.db.options.defaultMission; fleetDispatcher.refresh(); } this.updatePlanetList(); }); this.overWriteFleetDispatcher('trySubmitFleet1', false, () => { this.conso = fleetDispatcher.getConsumption(); if(this.ogl.mode == 1 || this.ogl.mode == 4) { fleetDispatcher.resetCargo(); fleetDispatcher.cargoDeuterium = Math.min(fleetDispatcher.getDeuteriumOnPlanetWithoutConsumption(), fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoCrystal = Math.min(fleetDispatcher.crystalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoMetal = Math.min(fleetDispatcher.metalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoFood = Math.min(fleetDispatcher.foodOnPlanet || 0, fleetDispatcher.getFreeCargoSpace()); } }); this.overWriteFleetDispatcher('switchToPage', () => { if(this.ogl.mode == 3) this.tmpCargo = [fleetDispatcher.metal, fleetDispatcher.crystal, fleetDispatcher.deut]; }, () => { // change right menu planets actions (links -> destinations shortcuts) if(fleetDispatcher.currentPage == 'fleet2') { (document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).classList.add('ogl_shortcuts'); if(this.ogl.mode == 3) { fleetDispatcher.metal = [this.tmpCargo[0], this.tmpCargo[1], this.tmpCargo[2]]; } } else { (document.querySelector('#myPlanets') || document.querySelector('#myWorlds')).classList.remove('ogl_shortcuts'); } }); this.overWriteFleetDispatcher('trySubmitFleet2', () => { this.tmpDeutOnPlanet = fleetDispatcher.deuteriumOnPlanet; fleetDispatcher.deuteriumOnPlanet = this.initialDeutOnPlanet; }, () => { fleetDispatcher.deuteriumOnPlanet = this.tmpDeutOnPlanet; }); this.overWriteFleetDispatcher('submitFleet2', () => { this.fleetSent = true; let coords = this.ogl.current.coords.join(':'); if(this.ogl.current.type == 'moon') coords += ':M'; // update blind target if(this.targetSelected) { if(this.ogl.db.options.nextTargets[0] && !this.ogl.db.options.nextTargets[1]) { this.ogl.db.options.nextTargets[0] = 0; } else { this.ogl.db.options.nextTargets[0] = this.ogl.db.options.nextTargets[1]; } this.ogl.db.options.nextTargets[1] = 0; } let now = new Date(Date.now()); let midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0).getTime(); // update resources on planet this.ogl.db.me.planets[coords].resources.metal = Math.max(0, this.ogl.db.me.planets[coords].resources.metal - fleetDispatcher.cargoMetal); this.ogl.db.me.planets[coords].resources.crystal = Math.max(0, this.ogl.db.me.planets[coords].resources.crystal - fleetDispatcher.cargoCrystal); this.ogl.db.me.planets[coords].resources.deut = Math.max(0, this.ogl.db.me.planets[coords].resources.deut - fleetDispatcher.cargoDeuterium - fleetDispatcher.getConsumption()); // save sent fleet data this.ogl.db.lastFleet = {}; this.ogl.db.lastFleet.shipsToSend = fleetDispatcher.shipsToSend; this.ogl.db.lastFleet.targetPlanet = fleetDispatcher.targetPlanet; this.ogl.db.lastFleet.speedPercent = fleetDispatcher.speedPercent; this.ogl.db.lastFleet.cargoMetal = fleetDispatcher.cargoMetal; this.ogl.db.lastFleet.cargoCrystal = fleetDispatcher.cargoCrystal; this.ogl.db.lastFleet.cargoDeuterium = fleetDispatcher.cargoDeuterium; this.ogl.db.lastFleet.mission = fleetDispatcher.mission; this.ogl.db.lastFleet.expeditionTime = fleetDispatcher.expeditionTime; // add consumption to stats this.ogl.db.stats[midnight] = this.ogl.db.stats[midnight] || { idList:[], expe:{}, raid:{}, expeOccurences:{}, raidOccurences:0, consumption:0 }; this.ogl.db.stats[midnight].consumption = (this.ogl.db.stats?.[midnight]?.consumption || 0) - fleetDispatcher.getConsumption(); this.ogl.db.stats.total = this.ogl.db.stats.total || {}; this.ogl.db.stats.total.consumption = (this.ogl.db.stats?.total?.consumption || 0) - fleetDispatcher.getConsumption(); // redirect to messages page when using the spies table if(this.ogl.mode == 2) { localStorage.setItem('ogl-redirect', `https://${window.location.host}/game/index.php?page=messages`); } this.ogl.save(); }); // add mission's name as tooltip document.querySelectorAll('#fleet2 ul#missions a').forEach(e => { e.classList.add('tooltip'); e.setAttribute('title', e.querySelector('span').textContent); }); } // add a callback before and/or after a fleetdispatcher function overWriteFleetDispatcher(functionName, beforeCallback, afterCallback) { let old = fleetDispatcher[functionName]; fleetDispatcher[functionName] = function(param, param2) { beforeCallback && beforeCallback(param, param2); old.call(fleetDispatcher, param, param2); afterCallback && afterCallback(param, param2); } } // replace the default "enter" key action on fleetdispatch overWriteEnterKey() { let btn = document.querySelector('#continueToFleet2'); let newBtn = Util.createDom('div', {'class':'ogl_fleetBtn'}, btn.innerHTML); btn.parentNode.replaceChild(newBtn, btn); newBtn.addEventListener('click', event => { this.nextPageAction(event, true); }); this.fleet1Pressed = false; this.fleet2Pressed = false; document.querySelector('#fleetdispatchcomponent').addEventListener('keypress', event => { if((event.keyCode || event.which) == 13) event.preventDefault();return false; }); window.addEventListener('keyup', () => { this.fleet1Pressed = false; this.fleet2Pressed = false; }); window.addEventListener('keydown', event => { let keycode = event.keyCode ? event.keyCode : event.which; if(keycode == 13) { event.preventDefault(); if(((!document.querySelector('.ui-dialog') || document.querySelector('.ui-dialog').style.display == 'none') && !document.querySelector('.chat_box_textarea:focus') && (!document.querySelector('.ogl_overlay.ogl_active')))) { this.nextPageAction(event); } else if(document.querySelector('.ui-dialog').style.display != 'none' && document.querySelector('.ui-dialog a.ok')) { document.querySelector('.ui-dialog a.ok').click(); } } }); } async nextPageAction(event, noKeyCheck) { if(navigator.userAgentData && navigator.userAgentData.mobile) noKeyCheck = true; //if(!noKeyCheck && document.querySelector('.ogl_capacityContainer.ogl_highlight')) return; if(document.querySelector('.ajax_loading').style.display != 'none') return; if(this.fleetSent && fleetDispatcher.targetPlanet.position != 16) return; //if(fleetDispatcher.currentPage == 'fleet1' && !this.fleet1Pressed && !fleetDispatcher.fetchTargetPlayerDataTimeout) if(fleetDispatcher.currentPage == 'fleet1' && !this.fleet1Pressed) { if(!noKeyCheck && !event.shiftKey) this.fleet1Pressed = true; if(!this.ogl.db.options.nextTargets?.[0] && !this.ogl.db.options.nextTargets?.[1] && this.targetSelected) return; let differentPosition = false; ['galaxy', 'system', 'position', 'type'].forEach(key => { if(fleetDispatcher.currentPlanet[key] != fleetDispatcher.targetPlanet[key]) differentPosition = true; }); if(event.shiftKey) { if(!this.ogl.db.options.nextTargets[0] && !this.ogl.db.options.nextTargets[1]) return; document.querySelector('.ogl_keyList [data-trigger="T"]') && document.querySelector('.ogl_keyList [data-trigger="T"]').click(); this.updatePlanetList(); } else { if(!differentPosition && (fleetDispatcher.shipsToSend.length == 0 || this.ogl.mode == 4)) { fleetDispatcher.targetPlanet.type = fleetDispatcher.targetPlanet.type == 3 ? 1 : 3; this.updatePlanetList(); } } if(fleetDispatcher.shipsToSend.length == 0) { let required = this.calcRequiredShips(this.ogl.db.options.defaultShip); fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, required); if(!fleetDispatcher.mission && !differentPosition) { fleetDispatcher.mission = this.ogl.db.options.defaultMission; if(!fleetDispatcher.cargoMetal && !fleetDispatcher.cargoCrystal && !fleetDispatcher.cargoDeuterium) { fleetDispatcher.selectMaxAll(); } } fleetDispatcher.refresh(); } else { await new Promise((resolve, reject) => setTimeout(() => resolve(), 250)); fleetDispatcher.trySubmitFleet1(); } } else if(fleetDispatcher.currentPage == 'fleet2' && !this.fleet2Pressed) { if(!noKeyCheck) this.fleet2Pressed = true; let differentPosition = false; fleetDispatcher.speedPercent = this.sliderSpeed.querySelector('.ogl_active').getAttribute('data-step'); ['galaxy', 'system', 'position', 'type'].forEach(key => { if(fleetDispatcher.currentPlanet[key] != fleetDispatcher.targetPlanet[key]) differentPosition = true; }); if(!differentPosition) { fleetDispatcher.targetPlanet.type = fleetDispatcher.targetPlanet.type == 3 ? 1 : 3; this.updatePlanetList(); fleetDispatcher.updateTarget(); } else { await new Promise((resolve, reject) => setTimeout(() => { if(fleetDispatcher.targetPlanet.position == 16) { this.fleet2Pressed = false; this.fleetSent = false; } if(!this.fleetSent) { resolve(); fleetDispatcher.trySubmitFleet2(); } }, 250)); } } } updateShipsTooltip() { document.querySelectorAll('.technology').forEach(ship => { let shipID = ship.getAttribute('data-technology'); let shipData = this.ogl.db.ships[shipID]; if(shipData) { let amount = parseInt(ship.querySelector('.amount').getAttribute('data-value')); ship.title = ` <div class="ogl_shipData"> <h3>${shipData.name}</h3> <div class="splitLine"></div> <div>Speed: <span>${Util.formatNumber(shipData.speed)}</span></div> <div>Capacity: <span>${Util.formatNumber(shipData.capacity)}</span></div> <div class="splitLine"></div> <div>Quantity: <span>x${Util.formatNumber(amount)}</span></div> <div>Total capacity: <span>${Util.formatNumber(amount * shipData.capacity)}</span></div> </div> `; } }); } updatePrevNextLink() { if(this.ogl.mode != 1 && this.ogl.mode != 4) return; let onMoon = this.ogl.db.collectSource[3] == 3 ? true : false; if(this.ogl.mode == 1) { let next = !onMoon ? this.ogl.next.smallplanet : this.ogl.next.smallplanetWithMoon; let nextCoords = `${next.querySelector('.planet-koords').textContent.slice(1, -1)}:${this.ogl.current.type == 'moon' ? 3 : 1}`; let prev = !onMoon ? this.ogl.prev.smallplanet : this.ogl.prev.smallplanetWithMoon; let prevCoords = `${prev.querySelector('.planet-koords').textContent.slice(1, -1)}:${this.ogl.current.type == 'moon' ? 3 : 1}`; let destinationCoords = this.ogl.db.collectDestination.join(':'); if(nextCoords == destinationCoords) // next { if(!onMoon) { this.ogl.next.smallplanet = this.ogl.next.smallplanet.nextElementSibling || document.querySelectorAll('.smallplanet')[0]; } else { if(document.querySelector('.moonlink') && document.querySelectorAll('.moonlink').length > 1) { do this.ogl.next.smallplanetWithMoon = this.ogl.next.smallplanetWithMoon.nextElementSibling || document.querySelectorAll('.moonlink')[0].parentNode; while(!this.ogl.next.smallplanetWithMoon.querySelector('.moonlink')); } } } else if(prevCoords == destinationCoords) // prev { if(!onMoon) { this.ogl.prev.smallplanet = this.ogl.prev.smallplanet.previousElementSibling || document.querySelectorAll('.smallplanet')[document.querySelectorAll('.smallplanet').length - 1]; } else { if(document.querySelector('.moonlink') && document.querySelectorAll('.moonlink').length > 1) { do this.ogl.prev.smallplanetWithMoon = this.ogl.prev.smallplanetWithMoon.previousElementSibling || document.querySelectorAll('.moonlink')[document.querySelectorAll('.moonlink').length - 1].parentNode; while(!this.ogl.prev.smallplanetWithMoon.querySelector('.moonlink')); } } } } if(this.ogl.mode == 1) // chosen destination { let next = !onMoon ? this.ogl.next.smallplanet : this.ogl.next.smallplanetWithMoon; if(next) { let nextCoords = next.querySelector('.planet-koords').textContent.slice(1, -1).split(':'); let id = !onMoon ? new URL(next.querySelector('a.planetlink').href).searchParams.get('cp') : new URL(next.querySelector('a.moonlink').href).searchParams.get('cp'); this.ogl.nextLink = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=1&cp=${id}&galaxy=${this.ogl.db.collectDestination[0]}&system=${this.ogl.db.collectDestination[1]}&position=${this.ogl.db.collectDestination[2]}&type=${this.ogl.db.collectDestination[3]}&mission=${this.ogl.db.options.defaultMission}`; if(this.ogl.db.collectSource[0] == nextCoords[0] && this.ogl.db.collectSource[1] == nextCoords[1] && this.ogl.db.collectSource[2] == nextCoords[2]) { this.ogl.nextLink = `https://${window.location.host}/game/index.php?page=ingame&component=overview`; } } let prev = !onMoon ? this.ogl.prev.smallplanet : this.ogl.prev.smallplanetWithMoon; if(prev) { let id = !onMoon ? new URL(prev.querySelector('a.planetlink').href).searchParams.get('cp') : new URL(prev.querySelector('a.moonlink').href).searchParams.get('cp'); this.ogl.prevLink = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=1&cp=${id}&galaxy=${this.ogl.db.collectDestination[0]}&system=${this.ogl.db.collectDestination[1]}&position=${this.ogl.db.collectDestination[2]}&type=${this.ogl.db.collectDestination[3]}&mission=${this.ogl.db.options.defaultMission}`; } } else if(this.ogl.mode == 4) // linked planet/moon { let nextCoords = this.ogl.next.smallplanetWithMoon.querySelector('.planet-koords').textContent.slice(1, -1).split(':'); let nextCp = this.ogl.current.type == 'planet' ? new URL(this.ogl.next.smallplanetWithMoon.querySelector('a.planetlink').href).searchParams.get('cp') : new URL(this.ogl.next.smallplanetWithMoon.querySelector('a.moonlink').href).searchParams.get('cp'); this.ogl.nextLink = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=4&cp=${nextCp}&type=${this.ogl.current.type == 'planet' ? '3' : '1'}&mission=${this.ogl.db.options.defaultMission}`; if(this.ogl.db.collectSource[0] == nextCoords[0] && this.ogl.db.collectSource[1] == nextCoords[1] && this.ogl.db.collectSource[2] == nextCoords[2]) { this.ogl.nextLink = `https://${window.location.host}/game/index.php?page=ingame&component=overview`; } let prevCp = this.ogl.current.type == 'planet' ? new URL(this.ogl.prev.smallplanetWithMoon.querySelector('a.planetlink').href).searchParams.get('cp') : new URL(this.ogl.prev.smallplanetWithMoon.querySelector('a.moonlink').href).searchParams.get('cp'); this.ogl.prevLink = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=4&cp=${prevCp}&type=${this.ogl.current.type == 'planet' ? '3' : '1'}&mission=${this.ogl.db.options.defaultMission}`; } this.linksUpdated = true; } // update rightmenu to display fleet's target updatePlanetList() { let targetCoords = `${fleetDispatcher.targetPlanet.galaxy}:${fleetDispatcher.targetPlanet.system}:${fleetDispatcher.targetPlanet.position}`; let type = fleetDispatcher.targetPlanet.type; document.querySelectorAll('.smallplanet a.ogl_active').forEach(e => e.classList.remove('ogl_active')); let target = document.querySelector(`.smallplanet[data-coords="${targetCoords}"]`); if(target && type == 1) { document.querySelector(`.smallplanet[data-coords="${targetCoords}"] .planetlink`)?.classList.add('ogl_active'); } else if(target && type == 3) { document.querySelector(`.smallplanet[data-coords="${targetCoords}"] .moonlink`)?.classList.add('ogl_active'); } } // resources to keep on planet resourcesSaving() { document.querySelectorAll('#fleet2 #resources .res_wrap .resourceIcon').forEach(resource => { // set index according to this.resourceKeys order (metal, crystal, deut, food) let index = 0; this.resourceKeys.forEach((res, ind) => { if(resource.classList.contains(res.replace('deut', 'deuterium'))) index = ind; }); resource = resource.parentNode; let deltaResources = resource.querySelector('.res').appendChild(Util.createDom('div', {'class':'ogl_delta material-icons'}, 'fiber_smart_record')); deltaResources.addEventListener('click', () => { let resourceValue = Util.formatFromUnits(resource.querySelector('input').value) || 0; let currentMax = fleetDispatcher[this.resourceOnKeys[index]]; if(index == 2) currentMax -= fleetDispatcher.getConsumption(); fleetDispatcher[this.cargoKeys[index]] = Math.min(currentMax, Math.max(0, currentMax - resourceValue)); resource.querySelector('input').value = fleetDispatcher[this.cargoKeys[index]]; setTimeout(() => document.querySelector('#sendFleet').focus(), 100); }); let edit = resource.querySelector('.res').appendChild(Util.createDom('div', {'class':'ogl_resourceSaver material-icons tooltip ogl_input', 'title':`${this.resourceNames[index]} ${this.ogl.component.lang.getText('keepOnPlanet')}`}, 'play_for_work')); edit.addEventListener('click', () => { this.ogl.component.tooltip.close(true); edit.classList.add('tooltipClose'); this.ogl.component.tooltip.lastSender = edit; let content = Util.createDom('div', {'class':'ogl_preloadResources'}, `<h2>${this.resourceNames[index]} ${this.ogl.component.lang.getText('keepOnPlanet')}</h2>`); content.appendChild(Util.createDom('div', {'class':`ogl_shipIcon ogl_${this.resourceKeys[index]}`})); let input = content.appendChild(Util.createDom('input', {'type':'text', 'class':'ogl_input'}, '0')); input.addEventListener('keydown', e => { if(e.keyCode === 13) { this.fleet2Pressed = true; content.querySelector('button').click(); } }); setTimeout(() => input.focus(), 100); content.appendChild(Util.createDom('button', {'class':'ogl_button ogl_fullGrid'}, 'OK')) .addEventListener('click', () => { this.ogl.db.options.resSaver[index] = parseInt(input.value?.replace(/\D/g,'') || 0); fleetDispatcher[this.resourceOnKeys[index]] = Math.max(0, this.ogl.current[this.resourceKeys[index]] - this.ogl.db.options.resSaver[index]); this.totalOnPlanet = fleetDispatcher.metalOnPlanet + fleetDispatcher.crystalOnPlanet + fleetDispatcher.deuteriumOnPlanet + fleetDispatcher.foodOnPlanet || this.ogl.current.metal + this.ogl.current.crystal + this.ogl.current.deut + this.ogl.current.food || 0; fleetDispatcher.refresh(); this.ogl.component.tooltip.close(true); if(this.ogl.db.options.resSaver[index]) { edit.classList.remove('material-icons'); edit.classList.add('ogl_active'); edit.textContent = '-' + Util.formatToUnits(this.ogl.db.options.resSaver[index], 0); } else { edit.classList.add('material-icons'); edit.classList.remove('ogl_active'); edit.textContent = 'play_for_work'; } edit.classList.remove('tooltipClose'); // this.ogl.saveAsync(); }); this.ogl.component.tooltip.update(edit, content); }); edit.addEventListener('mouseover', () => edit.classList.remove('tooltipClose')); if(this.ogl.db.options.resSaver[index]) { edit.classList.remove('material-icons'); edit.classList.add('ogl_active'); edit.textContent = '-' + Util.formatToUnits(this.ogl.db.options.resSaver[index], 0); } resource.querySelector('input').classList.add('ogl_input'); }); } // right menu planets are destination shortcut on fleet2 planetsAreDestinations() { document.querySelectorAll('.smallplanet > a.planetlink, .smallplanet > a.moonlink').forEach(link => { link.addEventListener('click', event => { if(fleetDispatcher.currentPage == 'fleet2') { event.preventDefault(); document.querySelector('.smallplanet a.ogl_active') && document.querySelector('.smallplanet a.ogl_active').classList.remove('ogl_active'); let destination = link.closest('.smallplanet').querySelector('.planet-koords').textContent.slice(1, -1).split(':'); let type = link.classList.contains('planetlink') ? 1 : 3; fleetDispatcher.targetPlanet.galaxy = destination[0]; fleetDispatcher.targetPlanet.system = destination[1]; fleetDispatcher.targetPlanet.position = destination[2]; fleetDispatcher.targetPlanet.type = type; fleetDispatcher.refresh(); fleetDispatcher.updateTarget(); link.classList.add('ogl_active'); } }); }); } // replace the default speed selector replaceSpeedSelector() { this.sliderSpeed = Util.createDom('div', {'class':'ogl_fleetSpeed'}); if(this.ogl.account.class == 2) this.sliderSpeed.classList.add('ogl_big'); document.querySelector('#fleetboxbriefingandresources form').insertBefore(this.sliderSpeed, document.querySelector('#fleet2 div#mission')); let steps = this.ogl.account.class == 2 ? .5 : 1; for(let i=steps; i<=10; i+=steps) { let step = this.sliderSpeed.appendChild(Util.createDom('div', {'data-step':i}, i*10)); if(fleetDispatcher.speedPercent == i) step.classList.add('ogl_active'); } this.sliderSpeed.addEventListener('click', event => { if(!event.target.getAttribute('data-step')) return; if(fleetDispatcher.cargoDeuterium + this.conso >= fleetDispatcher.deuteriumOnPlanet) { fleetDispatcher.speedPercent = event.target.getAttribute('data-step'); fleetDispatcher.cargoDeuterium = 0; fleetDispatcher.selectMaxDeuterium(); } this.sliderSpeed.querySelectorAll('div').forEach(e => e.classList.remove('ogl_active')); event.target.classList.add('ogl_active'); fleetDispatcher.speedPercent = event.target.getAttribute('data-step'); fleetDispatcher.refresh(); this.conso = fleetDispatcher.getConsumption(); setTimeout(() => document.querySelector('#sendFleet').focus(), 100); }); this.sliderSpeed.addEventListener('mouseover', event => { if(!event.target.getAttribute('data-step')) return; fleetDispatcher.speedPercent = event.target.getAttribute('data-step'); fleetDispatcher.refresh(); }); this.sliderSpeed.addEventListener('mouseout', event => { fleetDispatcher.speedPercent = this.sliderSpeed.querySelector('.ogl_active').getAttribute('data-step'); fleetDispatcher.refresh(); }); } updateSpeedPercent() { this.sliderSpeed.querySelectorAll('div').forEach(e => e.classList.remove('ogl_active')); this.sliderSpeed.querySelector(`[data-step="${fleetDispatcher.speedPercent}"]`).classList.add('ogl_active'); } // add required ship indicator to move all the resources addRequired() { this.defaultShipsList.forEach(shipID => { let tech = document.querySelector(`#fleet1 .technology[data-technology="${shipID}"]`); let required = this.calcRequiredShips(shipID); tech?.querySelector('.icon')?.appendChild(Util.createDom('div', {'class':'ogl_required'}, Util.formatNumber(required))) .addEventListener('click', e => { e.stopPropagation(); fleetDispatcher.selectShip(shipID, required); fleetDispatcher.refresh(); }); }); } // reverse the ship selection addReverse() { fleetDispatcher.totalFret = 0; fleetDispatcher.shipsOnPlanet.forEach(ship => { fleetDispatcher.totalFret += this.ogl.db.ships[ship.id].capacity * ship.number; let tech = document.querySelector(`#fleet1 .technology[data-technology="${ship.id}"`); tech.querySelector('input').classList.add('ogl_input'); tech.querySelector('.icon').appendChild(Util.createDom('div', {'class':'ogl_delta material-icons'}, 'fiber_smart_record')) .addEventListener('click', e => { e.stopPropagation(); let delta = fleetDispatcher.shipsOnPlanet.find(e => e.id == ship.id)?.number - (fleetDispatcher.findShip(ship.id)?.number || 0); fleetDispatcher.selectShip(ship.id, delta); fleetDispatcher.refresh(); }); }); } // cargo capacity indicator & preload resources addCapacity() { let container = document.querySelector('#fleet1 .allornonewrap').appendChild(Util.createDom('div', {'class':'ogl_capacityContainer tooltip', 'title':this.ogl.component.lang.getText('capacityPicker')})); let dom = container.appendChild(Util.createDom('div', {'class':'ogl_capacityInfo'})); let required = dom.appendChild(Util.createDom('div', {'class':'ogl_capacityRequired'}, this.ogl.component.lang.getText('required') + ' ' + Util.formatNumber(this.totalOnPlanet))); let capacityValues = dom.appendChild(Util.createDom('p')); let current = dom.appendChild(Util.createDom('div', {'class':'ogl_capacityCurrent'})); container.appendChild(Util.createDom('i', {'class':'material-icons'}, 'launch')); required.appendChild(Util.createDom('div')); required.style.width = Math.min(this.totalOnPlanet / fleetDispatcher.totalFret * 100, 100) + '%'; if(this.totalOnPlanet > fleetDispatcher.totalFret) bar.classList.add('ogl_active'); this.overWriteFleetDispatcher('resetCargo', false, () => { let domWidth = fleetDispatcher.getCargoCapacity() / fleetDispatcher.totalFret * 100; current.style.width = domWidth + '%'; capacityValues.innerHTML = `<span class="float_right"><b>${Util.formatNumber(fleetDispatcher.getCargoCapacity())}</b> / <b>${Util.formatNumber(fleetDispatcher.totalFret)}</b></span>`; }); container.addEventListener('mouseout', () => { container.classList.remove('tooltipClose'); }); container.addEventListener('click', () => { this.ogl.component.tooltip.close(true); container.classList.add('tooltipClose'); this.ogl.component.tooltip.lastSender = container; let content = Util.createDom('div', {'class':'ogl_preloadResources'}, `<h2>${this.ogl.component.lang.getText('capacityPicker')}</h2>`); let inputList = {}; ['metal', 'crystal', 'deut'].forEach(res => { let icon = content.appendChild(Util.createDom('div', {'class':`ogl_shipIcon ogl_${res} material-icons`}, 'double_arrow')); icon.addEventListener('click', () => { let attr = res == 'metal' ? 'metalOnPlanet' : res == 'crystal' ? 'crystalOnPlanet' : 'deuteriumOnPlanet'; inputList[res].value = fleetDispatcher[attr]; }); inputList[res] = content.appendChild(Util.createDom('input', {'type':'text', 'class':'ogl_input'}, '0')); inputList[res].addEventListener('keydown', e => { if(e.keyCode === 13) { this.fleet1Pressed = true; content.querySelectorAll('button')[1].click(); } }); }); setTimeout(() => inputList.metal.focus(), 100); let actions = content.appendChild(Util.createDom('div')); actions.appendChild(Util.createDom('button', {'class':'ogl_button'}, 'Max.')) .addEventListener('click', () => { inputList.metal.value = fleetDispatcher.metalOnPlanet; inputList.crystal.value = fleetDispatcher.crystalOnPlanet; inputList.deut.value = fleetDispatcher.deuteriumOnPlanet; fleetDispatcher.refresh(); }); actions.appendChild(Util.createDom('button', {'class':'ogl_button'}, 'OK')) .addEventListener('click', () => { fleetDispatcher.cargoMetal = 0; fleetDispatcher.cargoCrystal = 0; fleetDispatcher.cargoDeuterium = 0; fleetDispatcher.refresh(); let total = parseInt(inputList.metal.value?.replace(/\D/g,'') || 0) + parseInt(inputList.crystal.value?.replace(/\D/g,'') || 0) + parseInt(inputList.deut.value?.replace(/\D/g,'') || 0); let required = this.calcRequiredShips(this.ogl.db.options.defaultShip, total); (async() => { await fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, required); fleetDispatcher.cargoMetal = Math.min(parseInt(inputList.metal.value?.replace(/\D/g,'') || 0), fleetDispatcher.metalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoCrystal = Math.min(parseInt(inputList.crystal.value?.replace(/\D/g,'') || 0), fleetDispatcher.crystalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoDeuterium = Math.min(parseInt(inputList.deut.value?.replace(/\D/g,'') || 0), fleetDispatcher.deuteriumOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.refresh(); this.ogl.component.tooltip.close(true); container.classList.remove('tooltipClose'); })(); }); this.ogl.component.tooltip.update(container, content); }); } // collect resources when the harvest button has been clicked collectResources() { let required = this.calcRequiredShips(this.ogl.db.options.defaultShip); fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, required); if(this.ogl.mode == 4) { fleetDispatcher.targetPlanet.type = fleetDispatcher.targetPlanet.type == 3 ? 1 : 3; } fleetDispatcher.refresh(); this.overWriteFleetDispatcher('submitFleet2', () => localStorage.setItem('ogl-redirect', this.ogl.nextLink)); } checkFleetMovement() { if(this.ogl.page == 'movement') { document.querySelectorAll('.fleetDetails').forEach(line => { let onBack = line.getAttribute('data-return-flight'); let missionType = line.getAttribute('data-mission-type'); // header let header = Util.createDom('div', {'class':'ogl_topLine'}); let smallMission = header.appendChild(Util.createDom('div')); smallMission.appendChild(Util.createDom('div', {'class':'ogl_shipIcon ogl_mission'+missionType})); let leftTime = header.appendChild(Util.createDom('div')); leftTime.appendChild(line.querySelector('.timer') || Util.createDom('div')); let leftAbsTime = header.appendChild(Util.createDom('div')); leftAbsTime.appendChild(line.querySelector('.absTime') || Util.createDom('div')); let originCoords = header.appendChild(Util.createDom('div')); originCoords.appendChild(line.querySelector('.originCoords') || Util.createDom('div')); if(onBack) originCoords.classList.add('ogl_active'); let originPlanet = header.appendChild(Util.createDom('div')); originPlanet.appendChild(line.querySelector('.originPlanet') || Util.createDom('div')); if(onBack) originPlanet.classList.add('ogl_active'); let iconFleet = header.appendChild(Util.createDom('div', {'class':'ogl_active'})); iconFleet.appendChild(line.querySelector('.starStreak .route a') || Util.createDom('div')); iconFleet.querySelector('a').style.transform = 'scale(.75)'; let destinationPlanet = header.appendChild(Util.createDom('div')); destinationPlanet.appendChild(line.querySelector('.destinationPlanet') || Util.createDom('div')); if(!onBack) destinationPlanet.classList.add('ogl_active'); let destinationCoords = header.appendChild(Util.createDom('div')); destinationCoords.appendChild(line.querySelector('.destinationCoords') || Util.createDom('div')); if(!onBack) destinationCoords.classList.add('ogl_active'); let rightAbsTime = header.appendChild(Util.createDom('div')); rightAbsTime.appendChild(line.querySelector('.nextabsTime') || Util.createDom('div')); let rightTime = header.appendChild(Util.createDom('div')); rightTime.appendChild(line.querySelector('.nextTimer') || Util.createDom('div')); // grid let id = '#'+iconFleet.querySelector('a').getAttribute('rel'); let div = document.querySelector(id); let container = Util.createDom('div', {'class':'ogl_shipDetail'}); div.querySelectorAll('.fleetinfo tr').forEach((line, index) => { if(line.querySelector('td')) { let shipLine = Util.createDom('div', {'class':'ogl_movementItem'}); let shipID = Util.findObjectByValue(this.ogl.db.loca, line.querySelector('td').textContent.replace(':', '')) || (Object.entries(this.ogl.db.ships).find(e => e[1].name == line.querySelector('td').textContent.replace(':', '')) || [false])[0] || -1; if(shipID == 'metal') container.prepend(shipLine); else if(shipID == 'crystal') container.insertBefore(shipLine, container.querySelectorAll('.ogl_movementItem')[1]); else if(shipID == 'deut') container.insertBefore(shipLine, container.querySelectorAll('.ogl_movementItem')[2]); else if(shipID == 'food') container.insertBefore(shipLine, container.querySelectorAll('.ogl_movementItem')[3]); //else if(shipID == -1) container.prepend(shipLine); else if(shipID && shipID != -1) container.appendChild(shipLine); let shipNumber = line.querySelector('td.value') ? line.querySelector('td.value').textContent : '0'; if(shipID && shipID != -1) { shipLine.appendChild(Util.createDom('div', {'class':'ogl_shipIcon ogl_'+shipID})); shipLine.appendChild(Util.createDom('span', {'class':'ogl_'+shipID}, Util.formatToUnits(Util.formatNumber(shipNumber), 0).replace(' ',''))); } } }); let missionIcon = Util.createDom('div', {'class':'ogl_shipIcon ogl_mission'+missionType}); container.prepend(Util.createDom('div', {'class':'ogl_movementItem'}, missionIcon.outerHTML)); // actions let actions = Util.createDom('div', {'class':'ogl_actions'}); let reduceButton = actions.appendChild(Util.createDom('div')); let reduceContent = reduceButton.appendChild(line.querySelector('.openDetails') || Util.createDom('div')); if(reduceContent.innerHTML === '') reduceButton.classList.add('ogl_hidden'); let backButton = actions.appendChild(Util.createDom('div')); let backContent = backButton.appendChild(line.querySelector('.reversal') || Util.createDom('div')); if(!onBack) destinationCoords.classList.add('ogl_active'); if(backContent.innerHTML === '') backButton.classList.add('ogl_hidden'); if(backButton.querySelector('a')) { let time = backButton.querySelector('a').getAttribute('data-title') || backButton.querySelector('a').getAttribute('title'); time = time.replace('<br>',' '); time = time.replace(/ \.$/, ''); time = time.trim().replace(/[ \.]/g, ':'); time = time.split(':'); let initialTime = Date.now(); time = new Date(`${time[4]}-${time[3]}-${time[2]}T${time[5]}:${time[6]}:${time[7]}`).getTime(); let domParent = actions.appendChild(Util.createDom('div', {'class':'ogl_backTime'})); let domElement = domParent.appendChild(Util.createDom('div', {'class':'ogl_fulldate ogl_hiddenContent ogl_timeZone ogl_backTimer'})); setInterval(() => { const deltaTime = Date.now() - initialTime; const newTime = new Date((time + timeDelta - Math.round(timeDiff / 100000) * 100000) + deltaTime * 2); domElement.setAttribute('data-servertime', newTime.getTime()); domElement.setAttribute('data-datezone', `${newTime.toLocaleDateString('fr-FR').replace(/\//g, '.')} `); domElement.setAttribute('data-timezone', ` ${newTime.toLocaleTimeString('fr-FR')}`); }, 500); } else actions.appendChild(Util.createDom('div')); let mailButton = actions.appendChild(Util.createDom('div')); let mailContent = mailButton.appendChild(line.querySelector('.sendMail') || Util.createDom('div')); if(mailContent.innerHTML === '') mailButton.classList.add('ogl_hidden'); let agsButton = actions.appendChild(Util.createDom('div')); let agsContent = agsButton.appendChild(line.querySelector('.fedAttack a') || Util.createDom('div')); if(!onBack) destinationCoords.classList.add('ogl_active'); if(agsContent.innerHTML === '') agsButton.classList.add('ogl_hidden'); let agsName = actions.appendChild(Util.createDom('div', {'class':'ogl_agsName'})); let agsNameContent = agsName.appendChild(line.querySelector('.allianceName') || Util.createDom('div')); if(agsNameContent.innerHTML === '') agsName.classList.add('ogl_hidden'); actions.appendChild(Util.createDom('div')); /*let misisonText = actions.appendChild(Util.createDom('div')); misisonText.appendChild(line.querySelector('.mission') || Util.createDom('div'));*/ line.appendChild(actions); line.appendChild(container); line.appendChild(header); }); return; // update back timer /*let updateBackTimer = (parent, time, offset) => { let newTime = new Date(`${time[4]}-${time[3]}-${time[2]}T${time[5]}:${time[6]}:${time[7]}`).getTime(); newTime = new Date((newTime - Math.round(timeDiff / 100000) * 100000) + offset * 2); parent.setAttribute('data-servertime', newTime.getTime()); parent.setAttribute('data-datezone', `${newTime.toLocaleDateString('fr-FR').replace(/\//g, '.')} `); parent.setAttribute('data-timezone', ` ${newTime.toLocaleTimeString('fr-FR')}`); }*/ // add back timer document.querySelectorAll('.reversal a').forEach((button, index) => { setTimeout(() => { let time = button.getAttribute('data-tooltip') || button.getAttribute('title'); time = time.replace('<br>',' '); time = time.replace(/ \.$/, ''); time = time.trim().replace(/[ \.]/g, ':'); time = time.split(':'); let initialTime = Date.now(); time = new Date(`${time[4]}-${time[3]}-${time[2]}T${time[5]}:${time[6]}:${time[7]}`).getTime(); let domElement = button.closest('.fleetDetails').appendChild(Util.createDom('div', {'class':'ogl_fulldate ogl_hiddenContent ogl_timeZone ogl_backTimer'})); setInterval(() => { const deltaTime = Date.now() - initialTime; const newTime = new Date((time + timeDelta - Math.round(timeDiff / 100000) * 100000) + deltaTime * 2); domElement.setAttribute('data-servertime', newTime.getTime()); domElement.setAttribute('data-datezone', `${newTime.toLocaleDateString('fr-FR').replace(/\//g, '.')} `); domElement.setAttribute('data-timezone', ` ${newTime.toLocaleTimeString('fr-FR')}`); }, 500); }, index * 5); }); // replace default mouvement menu document.querySelectorAll('.starStreak .route').forEach(movement => { let id = '#'+movement.querySelector('a').getAttribute('rel'); let div = document.querySelector(id); let container = movement.closest('.fleetDetails').appendChild(Util.createDom('div',{'class':'ogl_shipDetail'})); movement.querySelector('a').classList.add('ogl_inFlight'); div.querySelectorAll('.fleetinfo tr').forEach((line, index) => { if(line.querySelector('td')) { let shipLine = Util.createDom('div', {'class':'ogl_movementItem'}); let shipID = Util.findObjectByValue(this.ogl.db.loca, line.querySelector('td').textContent.replace(':', '')) || (Object.entries(this.ogl.db.ships).find(e => e[1].name == line.querySelector('td').textContent.replace(':', '')) || [false])[0] || -1; if(shipID == 'metal') container.prepend(shipLine); else if(shipID == 'crystal') container.insertBefore(shipLine, container.querySelectorAll('.ogl_movementItem')[1]); else if(shipID == 'deut') container.insertBefore(shipLine, container.querySelectorAll('.ogl_movementItem')[2]); else if(shipID == 'food') container.insertBefore(shipLine, container.querySelectorAll('.ogl_movementItem')[3]); else if(shipID == -1) container.prepend(shipLine); else container.appendChild(shipLine); let shipNumber = line.querySelector('td.value') ? line.querySelector('td.value').textContent : '0'; if(shipID && shipID != -1) { shipLine.appendChild(Util.createDom('div', {'class':'ogl_shipIcon ogl_'+shipID})); shipLine.appendChild(Util.createDom('span', {'class':'ogl_'+shipID}, Util.formatToUnits(Util.formatNumber(shipNumber), 0).replace(' ',''))); } } }); }); } } calcRequiredShips(shipID, resources) { resources = resources ?? this.totalOnPlanet; return Math.ceil(resources / this.ogl.db.ships[shipID].capacity); } sendSpyProbe(coords, count, sender, noPopup, callback) { this.spyQueue = this.spyQueue || []; this.spyQueue.push({coords:coords, count:count, sender:sender, noPopup:noPopup, callback:callback}); sender && sender.classList.add('ogl_loading'); if(this.spyReady) this.trySendProbes(); } trySendProbes() { if(this.spyQueue?.length) { let coords = this.spyQueue[0].coords; let count = this.spyQueue[0].count; let sender = this.spyQueue[0].sender; let noPopup = this.spyQueue[0].noPopup; let callback = this.spyQueue[0].callback; let params = { mission:6, galaxy:coords[0], system:coords[1], position:coords[2], type:coords[3], shipCount:count, token:token, } let self = this; this.spyReady = false; $.ajax(miniFleetLink, { data:params, dataType:"json", type:"POST", success:function(data) { if(typeof data.newAjaxToken != "undefined") { token = data.newAjaxToken; } if(sender) { sender.classList.remove('ogl_disabled'); sender.classList.remove('ogl_danger'); } if(!data.response.success && data.response.coordinates) fadeBox(data.response.message + ' ' + coords[0] + ":" + coords[1] + ":" + coords[2], !data.response.success); if(data.response.coordinates && !noPopup) fadeBox(data.response.message + ' ' + data.response.coordinates.galaxy + ":" + data.response.coordinates.system + ":" + data.response.coordinates.position, !data.response.success); if(sender && data.response.success) { sender.classList.remove('ogl_loading'); sender.classList.add('ogl_disabled'); let index = self.ogl.find(self.ogl.db.positions, 'coords', `${coords[0]}:${coords[1]}:${coords[2]}`)[0]; if(index) { coords[3] == 3 ? self.ogl.db.positions[index].lastMoonSpy = serverTime.getTime() : self.ogl.db.positions[index].lastSpy = serverTime.getTime(); self.ogl.save(); } } else if(sender && !data.response.success && data.response.coordinates) { sender.classList.remove('ogl_loading'); sender.classList.add('ogl_danger'); } if(callback) callback(data); self.spyReady = true; if(data.response.coordinates) { self.spyQueue.shift(); } self.trySendProbes(); }, error:function(error) { fadeBox('Error'); sender.classList.remove('ogl_loading'); if(sender) sender.classList.add('ogl_danger'); self.spyReady = true; self.trySendProbes(); } }); } } expedition(mainShipID) { fleetDispatcher.resetShips(); fleetDispatcher.resetCargo(); let coords = [fleetDispatcher.currentPlanet.galaxy, fleetDispatcher.currentPlanet.system, fleetDispatcher.currentPlanet.position]; let fillerID = 0; let maxTotal = 0; let minShip = 0; let currentStep = 0; let minFactor202to203 = 3; let minFactor202to219 = 5.75; let steps = { 10000 : { 202:10, 'max':40000 }, 100000 : { 202:125, 'max':500000 }, 1000000 : { 202:300, 'max':1200000 }, 5000000 : { 202:450, 'max':1800000 }, 25000000 : { 202:600, 'max':2400000 }, 50000000 : { 202:750, 'max':3000000 }, 75000000 : { 202:900, 'max':3600000 }, 100000000 : { 202:1050, 'max':4200000 }, Infinity : { 202:1250, 'max':5000000 }, } for(const [key, value] of Object.entries(steps)) { steps[key][203] = Math.ceil(steps[key][202] / minFactor202to203); steps[key][219] = Math.ceil(steps[key][202] / minFactor202to219); if(this.ogl.db.topScore[0] < key && !currentStep) currentStep = key; } maxTotal = steps[currentStep]['max']; minShip = steps[currentStep][mainShipID]; maxTotal = this.ogl.account.class == 3 ? maxTotal * 3 * this.ogl.universe.ecoSpeed : maxTotal * 2; let mainAmount = Math.max(minShip, this.calcRequiredShips(mainShipID, maxTotal)); [218, 213, 211, 215, 207].forEach(shipID => { let count = document.querySelector(`.technology[data-technology="${shipID}"] .amount`).getAttribute('data-value'); if(fillerID == 0 && count > 0) fillerID = shipID; }); if(this.ogl.db.options.togglesOff.indexOf('bigShip') > -1) fillerID = 0; shipsOnPlanet.forEach(ship => { if(ship.id == mainShipID) fleetDispatcher.selectShip(ship.id, mainAmount); else if(ship.id == fillerID && mainShipID != fillerID) fleetDispatcher.selectShip(ship.id, 1); else if(ship.id == 210) fleetDispatcher.selectShip(ship.id, 1); else if(ship.id == 219 && mainShipID != 219) fleetDispatcher.selectShip(ship.id, 1); }); fleetDispatcher.targetPlanet.galaxy = coords[0]; fleetDispatcher.targetPlanet.system = coords[1]; fleetDispatcher.targetPlanet.position = 16; fleetDispatcher.targetPlanet.type = 1; fleetDispatcher.targetPlanet.name = 'Expedition'; fleetDispatcher.mission = 15; fleetDispatcher.expeditionTime = 1; fleetDispatcher.refresh(); //setTimeout(() => document.querySelector('#continueToFleet2').focus(), 100); } } class EmpireManager { constructor(ogl) { this.ogl = ogl; this.addTimers(); this.resourceSum = Util.createDom('div', {'class':'ogl_resourcesSum'}); let i = this.resourceSum.appendChild(Util.createDom('i')); i.appendChild(Util.createDom('div', {'class':'ogl_loader'})); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_metal'}, '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_metal'}, '+0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_crystal'}, '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_crystal'}, '+0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_deut'}, '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_deut'}, '+0')); (document.querySelector('#cutty') || document.querySelector('#norm')).querySelector('#myPlanets, #myWorlds').after(this.resourceSum); if(!this.ogl.prevLink) this.ogl.prevLink = this.ogl.current.type == 'moon' ? this.ogl.prev.smallplanetWithMoon.querySelector('.moonlink')?.getAttribute('href') || this.ogl.prev.smallplanet.querySelector('.planetlink')?.getAttribute('href') : this.ogl.prev.smallplanet.querySelector('.planetlink')?.getAttribute('href'); if(!this.ogl.nextLink) this.ogl.nextLink = this.ogl.current.type == 'moon' ? this.ogl.next.smallplanetWithMoon.querySelector('.moonlink')?.getAttribute('href') || this.ogl.next.smallplanet.querySelector('.planetlink')?.getAttribute('href') : this.ogl.next.smallplanet.querySelector('.planetlink')?.getAttribute('href'); this.mainResources = ['metal', 'crystal', 'deut', 'dm']; this.myPlanets = {}; this.total = [0,0,0,0]; this.onPlanet = [0,0,0,0]; this.prod = [0,0,0,0]; this.locked = [0,0,0,0]; this.flightResources = [0,0,0,0]; let isGroup = false; let lastCoords, countGroup = 0; document.querySelectorAll('.smallplanet').forEach(p => { let coords = p.querySelector('.planetlink .planet-koords').textContent.slice(1,-1).split(':'); if(lastCoords == coords[0] + ':' + coords[1]) { p.setAttribute('data-multi', countGroup); isGroup = true; } else { if(isGroup) countGroup++; isGroup = false; } lastCoords = coords[0] + ':' + coords[1]; }); this.ogl.observeMutation(() => this.reloadEventbox(), 'eventbox'); new Promise(resolve => { resolve(this.checkPlanetResources()); }) .then(() => { this.checkLockedTechs(); this.checkStorage(); this.getEmpireData(); this.checkMovement(); this.addStats(); this.checkCrawlers(); this.ogl.performances.push(['Empire',performance.now()]); }); //this.checkPlanetResources(); //this.checkLockedTechs(); //this.checkStorage(); //this.checkMovement(); //this.addStats(); //this.checkCrawlers(); //setTimeout(() => this.getEmpireData(), 10); } // add planet "last refresh" timer addTimers() { if(this.ogl.db.options.togglesOff.indexOf('timers') > -1) return; let now = serverTime.getTime(); let currentCoords = this.ogl.current.coords.join(':'); if(!this.ogl.db.myActivities[currentCoords]) this.ogl.db.myActivities[currentCoords] = [0, 0]; let planetActivity = this.ogl.db.myActivities[currentCoords][0]; let moonActivity = this.ogl.db.myActivities[currentCoords][1]; if(this.ogl.current.type == 'moon') moonActivity = now; else planetActivity = now; this.ogl.db.myActivities[currentCoords] = [planetActivity, moonActivity]; document.querySelectorAll('.smallplanet').forEach(planet => { let coords = planet.querySelector('.planet-koords').textContent.slice(1, -1); let timers = this.ogl.db.myActivities[coords] || [0,0]; let pt = Math.min(Math.round((now - timers[0]) / 60000), 60); let pTimer = planet.querySelector('.planetlink').appendChild(Util.createDom('div', {'class':'ogl_timer ogl_medium ogl_short', 'data-timer':pt})); this.updateTimer(pTimer, timers[0]); setInterval(() => this.updateTimer(pTimer, timers[0]), 20000); if(planet.querySelector('.moonlink')) { let mt = Math.min(Math.round((now - timers[1]) / 60000), 60); let mTimer = planet.querySelector('.moonlink').appendChild(Util.createDom('div', {'class':'ogl_timer ogl_medium ogl_short', 'data-timer':mt})); this.updateTimer(mTimer, timers[1]); setInterval(() => this.updateTimer(mTimer, timers[1]), 20000); } }); } updateTimer(element, timer) { let time = Math.min(Math.round((serverTime.getTime() - timer) / 60000), 60); if(time >= 15) element.classList.remove('ogl_short'); if(time >= 30) element.classList.remove('ogl_medium'); if(time >= 60) return; element.setAttribute('data-timer', time); } checkPlanetResources() { let coords = this.ogl.current.coords.join(':'); if(this.ogl.current.type == 'moon') coords += ':M'; this.ogl.db.me.planets[coords] = this.ogl.db.me.planets[coords] || {}; this.ogl.db.me.planets[coords].resources = this.ogl.db.me.planets[coords].resources || {}; this.ogl.db.me.planets[coords].resources.metal = this.ogl.current.metal; this.ogl.db.me.planets[coords].resources.crystal = this.ogl.current.crystal; this.ogl.db.me.planets[coords].resources.deut = this.ogl.current.deut; this.ogl.db.me.planets[coords].resources.food = this.ogl.current.food; this.ogl.db.me.planets[coords].resources.population = this.ogl.current.population; // this.ogl.saveAsync(); } checkMovement() { // remove deleted / relocated planets Object.keys(this.ogl.db.me.planets).forEach(k => { if(!document.querySelector(`.smallplanet[data-coords="${k.replace(':M', '')}"]`)) { delete this.ogl.db.me.planets[k]; } }); Object.entries(this.ogl.db.me.planets).forEach(planet => { let coords = planet[0]; this.myPlanets[coords] = this.myPlanets[coords] || {}; this.myPlanets[coords].resources = this.ogl.db.me.planets[coords].resources || { metal:0, crystal:0, deut:0 }; this.myPlanets[coords].resourcesFlight = this.myPlanets[coords].resourcesFlight || { metal:0, crystal:0, deut:0 }; this.myPlanets[coords].ships = {}; this.myPlanets[coords].shipsFlight = this.myPlanets[coords].shipsFlight || {}; this.myPlanets[coords].opponentShips = this.myPlanets[coords].opponentShips || {}; this.myPlanets[coords].missions = this.myPlanets[coords].missions || []; this.ogl.db.me.planets[coords] = this.ogl.db.me.planets[coords] || { techs:{} }; Object.keys(this.ogl.db.ships).forEach(ship => this.myPlanets[coords].ships[ship] = this.ogl.db.me.planets[coords].techs?.[ship] || 0); }); Util.getXML(`https://${window.location.host}/game/index.php?page=componentOnly&component=eventList&ajax=1`, result => { let idList = []; let resourceKeys = ['metal', 'crystal', 'deut', 'food']; result.querySelectorAll('.eventFleet').forEach(line => { let coords; let coordsNode, isMoon; let id = line.getAttribute('id').replace('eventRow-', ''); let mission = line.getAttribute('data-mission-type'); let back = line.getAttribute('data-return-flight') == 'false' ? false : true; let fromAnotherPlayer = document.querySelector(`.smallplanet[data-coords="${line.querySelector('.coordsOrigin').textContent.trim().slice(1,-1)}"]`) ? false : true; let toAnotherPlayer = document.querySelector(`.smallplanet[data-coords="${line.querySelector('.destCoords').textContent.trim().slice(1,-1)}"]`) ? false : true; if((mission == '1' || mission == '6') && fromAnotherPlayer) // ennemy attacks and spies { coordsNode = line.querySelector('.destCoords'); isMoon = line.querySelector('.destFleet figure.moon'); } else if((mission == '1' && back) // attack || mission == '3' // transpo || mission == '4' // deploy || (mission == '7' && back) // colo || (mission == '8' && back) // harvest || (mission == '15' && back)) // expedition { if(idList.indexOf(parseInt(id)) > -1) return; if(mission == '3' && !back) idList.push(parseInt(id) + 1); if(toAnotherPlayer || back) { coordsNode = line.querySelector('.coordsOrigin'); isMoon = line.querySelector('.originFleet figure.moon'); } else { coordsNode = line.querySelector('.destCoords'); isMoon = line.querySelector('.destFleet figure.moon'); } } else return; coords = coordsNode.textContent.trim().slice(1,-1); if(isMoon) coords += ':M'; this.myPlanets[coords] = this.myPlanets[coords] || {}; this.myPlanets[coords].missions.push(mission); let tooltip = Util.createDom('div', {}, (line.querySelector('.icon_movement .tooltip') || line.querySelector('.icon_movement_reserve .tooltip')).getAttribute('title')); tooltip.querySelectorAll('.fleetinfo tr').forEach(subline => { if(subline.textContent.trim() == '') subline.classList.add('ogl_hidden'); else if(!subline.querySelector('td')) subline.classList.add('ogl_full'); else { let name = subline.querySelector('td').textContent.replace(':', ''); let shipID = (Object.entries(this.ogl.db.ships).find(e => e[1].name == name) || [false])[0]; let resourceName = resourceKeys.find(e => this.ogl.component.lang.getText(e) == name); const sublineValue = Util.formatFromUnits(subline.querySelector('.value')?.textContent || 0); if(shipID && shipID > -1 && sublineValue) { if((mission == '1' || mission == '6') && fromAnotherPlayer) this.myPlanets[coords].opponentShips[shipID] = (this.myPlanets[coords].opponentShips[shipID] || 0) + sublineValue; else if(!toAnotherPlayer || back) this.myPlanets[coords].shipsFlight[shipID] = (this.myPlanets[coords].shipsFlight[shipID] || 0) + sublineValue; } else if(resourceName && (!toAnotherPlayer || back)) { this.myPlanets[coords].resourcesFlight[resourceName] = (this.myPlanets[coords].resourcesFlight[resourceName] || 0) + sublineValue; } } }); }); // fleet movements Object.entries(this.myPlanets).forEach(entry => { let content = Util.createDom('table', {'class':'ogl_inFlightTable'}); Object.entries(entry[1].shipsFlight).forEach(ship => { let tr = content.appendChild(Util.createDom('tr')); tr.appendChild(Util.createDom('td', {'class':`ogl_shipIcon ogl_${ship[0]}`})); tr.appendChild(Util.createDom('td', {'class':'value'}, Util.formatToUnits(ship[1]))); }); content.appendChild(Util.createDom('tr', {'class':'ogl_full'})); Object.entries(entry[1].resourcesFlight).forEach(res => { let tr = content.appendChild(Util.createDom('tr', {'class':`ogl_${res[0]}`})); tr.appendChild(Util.createDom('td', {'class':`ogl_shipIcon ogl_${res[0]}`})); tr.appendChild(Util.createDom('td', {'class':`value`}, Util.formatToUnits(res[1] || '0'))); }); content.appendChild(Util.createDom('hr')); let missionsDiv = content.appendChild(Util.createDom('div', {'class':`ogl_missionList`})); [...new Set(entry[1].missions)].forEach(missionID => { let occurences = entry[1].missions.filter(x => x === missionID).length; missionsDiv.appendChild(Util.createDom('div', {'data-mission-type':missionID, 'data-mission-occurence':`${occurences}`})); }); let icon = document.querySelector(`.smallplanet[data-coords="${entry[0].replace(':M', '')}"]`).appendChild(Util.createDom('div', {'class':`ogl_missionType tooltipLeft ogl_inFlight ${entry[0].indexOf(':M') > 1 ? 'ogl_moonFleet' : 'ogl_planetFleet'}`, 'title':'loading'})); //if(Object.values(entry[1].resourcesFlight).reduce((previousValue, currentValue) => previousValue + currentValue) > 0) icon.classList.add('ogl_active'); icon.setAttribute('data-mission-type', (entry[1].missions || [0])[0] || 0); if(document.querySelector(`.smallplanet[data-coords="${entry[0].replace(':M', '')}"] .alert`) && (entry[1].isAttacked || entry[1].isSpied)) { document.querySelector(`.smallplanet[data-coords="${entry[0].replace(':M', '')}"] .alert`).remove(); } icon.addEventListener('mouseenter', () => { this.ogl.component.tooltip.update(icon, content) }); }); // resources summary document.querySelectorAll('.smallplanet').forEach(planet => { let coords = planet.querySelector('.planet-koords').textContent.slice(1, -1); resourceKeys.forEach((resourceKey, index) => { this.total[index] += this.ogl.db.me.planets[coords]?.resources[resourceKey] || 0; this.total[index] += this.ogl.db.me.planets[coords+':M']?.resources[resourceKey] || 0; this.total[index] += this.myPlanets[coords]?.resourcesFlight[resourceKey] || 0; this.total[index] += this.myPlanets[coords+':M']?.resourcesFlight[resourceKey] || 0; this.onPlanet[index] += this.ogl.db.me.planets[coords]?.resources[resourceKey] || 0; this.onPlanet[index] += this.ogl.db.me.planets[coords+':M']?.resources[resourceKey] || 0; this.prod[index] += parseFloat(this.ogl.db.me.planets[coords]?.production?.[index]) || 0; this.flightResources[index] += this.myPlanets[coords]?.resourcesFlight[resourceKey] || 0; this.flightResources[index] += this.myPlanets[coords+':M']?.resourcesFlight[resourceKey] || 0; Object.values(this.ogl.db.lock?.[coords] || {}).forEach(lock => { this.locked[index] += parseFloat(lock?.[resourceKey]) || 0; }); }); }); this.ogl.account.totalProd = this.prod; let displayIndex = 0; this.resourceSum.addEventListener('click', () => { displayIndex = displayIndex == 3 ? 0 : displayIndex + 1; this.resourceSum.classList.add('ogl_active'); selectDisplay(); }); let selectDisplay = () => { let target, icon; if(displayIndex == 0) { icon = 'functions'; target = this.total; } else if(displayIndex == 1) { icon = 'send'; target = this.flightResources; } else if(displayIndex == 2) { icon = 'public'; target = this.onPlanet; } else if(displayIndex == 3) { icon = 'lock'; target = this.locked; } this.resourceSum.textContent = ''; this.resourceSum.appendChild(Util.createDom('i', {'class':'material-icons'}, icon)); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_metal'}, Util.formatToUnits(target[0]) || '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_metal'}, '+'+Util.formatToUnits(Math.round(this.prod[0]*24*3600), 0) || '+0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_crystal'}, Util.formatToUnits(target[1]) || '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_crystal'}, '+'+Util.formatToUnits(Math.round(this.prod[1]*24*3600), 0) || '+0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_deut'}, Util.formatToUnits(target[2]) || '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_deut'}, '+'+Util.formatToUnits(Math.round(this.prod[2]*24*3600), 0) || '+0')); setTimeout(() => this.resourceSum.classList.remove('ogl_active'), 50); } selectDisplay(); }); /* Util.getXML(`https://${window.location.host}/game/index.php?page=componentOnly&component=eventList&ajax=1`, result => { let idList = []; let resName = ['metal', 'crystal', 'deut']; result.querySelectorAll('.eventFleet').forEach((line, index) => { let id = line.getAttribute('id').replace('eventRow-', ''); let mission = line.getAttribute('data-mission-type'); let back = line.getAttribute('data-return-flight') == 'false' ? false : true; if((mission == '1' || mission == '6') && !back) // ennemy attacks and spies { let target = line.querySelector('.destCoords').textContent.trim().slice(1,-1); if(document.querySelector(`.smallplanet[data-coords="${target}"]`)) { if(line.querySelector('.destFleet figure.moon')) target += ':M'; this.myPlanets[target] = this.myPlanets[target] || {}; this.myPlanets[target].resFlight = this.myPlanets[target].resFlight || [0,0,0]; this.myPlanets[target].ships = this.myPlanets[target].ships || {}; console.log(this.myPlanets[target].nextFleetEventType) if(!this.myPlanets[target].nextFleetEventType) this.myPlanets[target].nextFleetEventType = mission; if(mission == '1') this.myPlanets[target].isAttacked = true; else if(mission == '6') this.myPlanets[target].isSpied = true; let tempElem = Util.createDom('div', {}, (line.querySelector('.icon_movement .tooltip') || line.querySelector('.icon_movement_reserve .tooltip')).getAttribute('title')); tempElem.querySelectorAll('.fleetinfo tr').forEach(subline => { if(subline.textContent.trim() == '') subline.classList.add('ogl_hidden'); else if(!subline.querySelector('td')) subline.classList.add('ogl_full'); else { let name = subline.querySelector('td').textContent.replace(':', ''); let id = (Object.entries(this.ogl.db.ships).find(e => e[1].name == name) || [false])[0]; if(id && id > -1 && subline.querySelector('.value')) { this.myPlanets[target].ships[id] = (this.myPlanets[target].ships[id] || 0) + Util.formatFromUnits(subline.querySelector('.value').textContent); } } }); } } if((mission == '1' && back) // attack || mission == '3' // transpo || mission == '4' // deploy || (mission == '7' && back) // colo || (mission == '8' && back) // harvest || (mission == '15' && back)) // expedition { let target; if(idList.indexOf(parseInt(id)) > -1) return; if(mission == '3' && !back) idList.push(parseInt(id) + 1); if(!back) target = line.querySelector('.destCoords').textContent.trim().slice(1,-1); else target = line.querySelector('.coordsOrigin').textContent.trim().slice(1,-1); if(document.querySelector(`.smallplanet[data-coords="${target}"]`)) { if((!back && line.querySelector('.destFleet figure.moon')) || (back && line.querySelector('.originFleet figure.moon'))) { target += ':M'; } this.myPlanets[target] = this.myPlanets[target] || {}; this.myPlanets[target].resFlight = this.myPlanets[target].resFlight || [0,0,0]; this.myPlanets[target].ships = this.myPlanets[target].ships || {}; this.myPlanets[target].missionList = this.myPlanets[target].missionList || []; if(!this.myPlanets[target].nextFleetEventType) this.myPlanets[target].nextFleetEventType = mission; this.myPlanets[target].missionList.push(mission); let tempElem = Util.createDom('div', {}, (line.querySelector('.icon_movement .tooltip') || line.querySelector('.icon_movement_reserve .tooltip')).getAttribute('title')); if(tempElem.querySelectorAll('th').length > 1) { let trLen = tempElem.querySelectorAll('tr').length; for(let i=0; i<3; i++) { let res = parseInt(tempElem.querySelectorAll('tr')[trLen-3+i].querySelector('.value').textContent.replace(/\./g,'')); this.myPlanets[target].resFlight[i] += res; this.ogl.account.totalResources[i] += parseInt(res); this.total[i] += res; } } tempElem.querySelectorAll('.fleetinfo tr').forEach(subline => { if(subline.textContent.trim() == '') subline.classList.add('ogl_hidden'); else if(!subline.querySelector('td')) subline.classList.add('ogl_full'); else { let name = subline.querySelector('td').textContent.replace(':', ''); let id = (Object.entries(this.ogl.db.ships).find(e => e[1].name == name) || [false])[0]; if(id && id > -1 && subline.querySelector('.value')) { this.myPlanets[target].ships[id] = (this.myPlanets[target].ships[id] || 0) + Util.formatFromUnits(subline.querySelector('.value').textContent); } } }); } } }); Object.entries(this.myPlanets).forEach(entry => { let content = Util.createDom('table', {'class':'ogl_inFlightTable'}); Object.entries(entry[1].ships).forEach(ship => { let tr = content.appendChild(Util.createDom('tr')); tr.appendChild(Util.createDom('td', {'class':`ogl_shipIcon ogl_${ship[0]}`})); tr.appendChild(Util.createDom('td', {'class':'value'}, Util.formatToUnits(ship[1]))); }); content.appendChild(Util.createDom('tr', {'class':'ogl_full'})); Object.entries(entry[1].resFlight).forEach(res => { let tr = content.appendChild(Util.createDom('tr', {'class':`ogl_${resName[res[0]]}`})); tr.appendChild(Util.createDom('td', {'class':`ogl_shipIcon ogl_${resName[res[0]]}`})); tr.appendChild(Util.createDom('td', {'class':`value`}, Util.formatToUnits(res[1] || '0'))); }); content.appendChild(Util.createDom('hr')); let missionsDiv = content.appendChild(Util.createDom('div', {'class':`ogl_missionList`})); //entry[1].missionList.forEach(missionID => [...new Set(entry[1].missionList)].forEach(missionID => { let occurences = entry[1].missionList.filter(x => x === missionID).length; missionsDiv.appendChild(Util.createDom('div', {'data-mission-type':missionID, 'data-mission-occurence':`${occurences}`}, )); }); // let link = entry[0].indexOf(':M') > -1 ? 'moonlink' : 'planetlink'; let icon = document.querySelector(`.smallplanet[data-coords="${entry[0].replace(':M', '')}"]`).appendChild(Util.createDom('div', {'class':`ogl_missionType tooltipLeft ogl_inFlight ${entry[0].indexOf(':M') > 1 ? 'ogl_moonFleet' : 'ogl_planetFleet'}`, 'title':'loading...'})); if(entry[1].resFlight.reduce((previousValue, currentValue) => previousValue + currentValue) > 0) icon.classList.add('ogl_active'); if(entry[1].isAttacked) icon.classList.add('ogl_danger'); else if(entry[1].isSpied) icon.classList.add('ogl_warning'); icon.setAttribute('data-mission-type', entry[1].nextFleetEventType); if(document.querySelector(`.smallplanet[data-coords="${entry[0].replace(':M', '')}"] .alert`) && (entry[1].isAttacked || entry[1].isSpied)) { document.querySelector(`.smallplanet[data-coords="${entry[0].replace(':M', '')}"] .alert`).remove(); } icon.addEventListener('mouseenter', () => { this.ogl.component.tooltip.update(icon, content) }); }); document.querySelectorAll('.smallplanet').forEach(planet => { let resName = ['metal', 'crystal', 'deut']; let coords = planet.querySelector('.planet-koords').textContent.slice(1, -1); for(let i=0; i<3; i++) { this.total[i] += parseInt(planet.querySelector(`.ogl_stock .ogl_${resName[i]}`).getAttribute('data-value')) || 0; this.total[i] += this.ogl.db.me.planets[coords+':M']?.resources[resName[i]] || 0; this.onPlanet[i] += parseInt(planet.querySelector(`.ogl_stock .ogl_${resName[i]}`).getAttribute('data-value')) || 0; this.onPlanet[i] += this.ogl.db.me.planets[coords+':M']?.resources[resName[i]] || 0; this.prod[i] += parseFloat(this.ogl.db.me.planets[coords]?.production?.[i]) || 0; Object.values(this.ogl.db.lock?.[coords] || {}).forEach(lock => { this.locked[i] += parseFloat(lock?.[resName?.[i]]) || 0; }); } }); this.ogl.account.totalProd = this.prod; let displayIndex = 0; this.resourceSum.addEventListener('click', () => { displayIndex = displayIndex == 3 ? 0 : displayIndex + 1; this.resourceSum.classList.add('ogl_active'); selectDisplay(); }); let selectDisplay = index => { let target, icon; if(displayIndex == 0) { icon = 'functions'; target = this.total; } else if(displayIndex == 1) { icon = 'send'; target = this.ogl.account.totalResources; } else if(displayIndex == 2) { icon = 'public'; target = this.onPlanet; } else if(displayIndex == 3) { icon = 'lock'; target = this.locked; } this.resourceSum.textContent = ''; this.resourceSum.appendChild(Util.createDom('i', {'class':'material-icons'}, icon)); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_metal'}, Util.formatToUnits(target[0]) || '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_metal'}, '+'+Util.formatToUnits(Math.round(this.prod[0]*24*3600), 0) || '+0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_crystal'}, Util.formatToUnits(target[1]) || '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_crystal'}, '+'+Util.formatToUnits(Math.round(this.prod[1]*24*3600), 0) || '+0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_deut'}, Util.formatToUnits(target[2]) || '0')); this.resourceSum.appendChild(Util.createDom('div', {'class':'ogl_sub ogl_deut'}, '+'+Util.formatToUnits(Math.round(this.prod[2]*24*3600), 0) || '+0')); setTimeout(() => this.resourceSum.classList.remove('ogl_active'), 50); } selectDisplay(); // todo //console.log(this.ogl.db.me.planets) // res on planet //console.log(this.flightResources) // res in flight //console.log(this.total) // res total });*/ } addStats(startDate, endDate) { if(this.ogl.db.options.togglesOff.indexOf('renta') > -1) return; if(this.ogl.db.stats.NaN) delete this.ogl.db.stats.NaN; document.querySelector('.ogl_stats')?.remove(); let entry = Object.keys(this.ogl.db.stats).sort()[0]; if(!isNaN(entry)) this.ogl.db.stats.firstEntry = entry; for (const [key, value] of Object.entries(this.ogl.db.stats)) { if(Date.now() - key > 31 * 24 * 60 * 60 * 1000) { delete this.ogl.db.stats[key]; } } // this.ogl.saveAsync(); startDate = startDate || Date.now() - this.ogl.db.options.dateFilter * 24 * 60 * 60 * 1000; endDate = endDate || Date.now(); let days = Math.round((endDate - startDate) / 24 / 60 / 60 / 1000); let rangeDate = days; this.dailiesStats = []; let raidOccurences = 0; let expeOccurences = 0; if(startDate >= 0) { for(let i=0; i<days; i++) { let date = new Date(endDate - i * 24 * 60 * 60 * 1000); let midnight = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0).getTime(); this.dailiesStats.push(this.ogl.db.stats[midnight] || false); // fix if(this.ogl.db.stats?.[midnight]?.raidOccuences) { this.ogl.db.stats[midnight].raidOccurences = (this.ogl.db.stats[midnight].raidOccurences || 0) + this.ogl.db.stats.total.raidOccuences; delete this.ogl.db.stats[midnight].raidOccuences; } raidOccurences += this.ogl.db.stats?.[midnight]?.raidOccurences || 0; expeOccurences += this.ogl.db.stats?.[midnight]?.expeOccurences && Object.values(this.ogl.db.stats?.[midnight]?.expeOccurences).length ? Object.values(this.ogl.db.stats?.[midnight]?.expeOccurences).reduce((a, b) => a + b) : 0; } } else { // fix if(this.ogl.db.stats?.total?.raidOccuences) { this.ogl.db.stats.total.raidOccurences = (this.ogl.db.stats.total.raidOccurences || 0) + this.ogl.db.stats.total.raidOccuences; delete this.ogl.db.stats.total.raidOccuences; } this.dailiesStats.push(this.ogl.db.stats.total || false); raidOccurences += this.ogl.db.stats?.total?.raidOccurences || 0; expeOccurences += this.ogl.db.stats?.total?.expeOccurences && Object.values(this.ogl.db.stats?.total?.expeOccurences).length ? Object.values(this.ogl.db.stats?.total?.expeOccurences).reduce((a, b) => a + b) : 0; let now = new Date(); let midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0).getTime(); rangeDate = (midnight - this.ogl.db.stats.firstEntry) / (24 * 60 * 60 * 1000) || (Math.ceil((Date.now() - Object.keys(this.ogl.db.stats).sort()[0]) / 24 / 60 / 60 / 1000) + 1) || 1; } let cumul = { metal:0, crystal:0, deut:0, dm:0 }; let cumulExpe = { metal:0, crystal:0, deut:0, dm:0 }; let cumulRaid = { metal:0, crystal:0, deut:0, dm:0 }; let cumulConso = 0; let cumulExpeOccurences = {}; let emptyData = true; Object.values(this.dailiesStats).forEach(daily => { if(!daily || (!daily.raid && !daily.expe)) return; if(emptyData) emptyData = false; ['metal','crystal','deut','dm',202,203,204,205,206,207,208,209,210,211,213,214,215,218,219].forEach(id => { cumul[id] = parseInt(cumul[id]) || 0; if(isNaN(id)) cumulRaid[id] = parseInt(cumulRaid[id]) || 0; cumulExpe[id] = parseInt(cumulExpe[id]) || 0; let dayRaidValue = parseInt(daily?.raid?.[id]) || 0; let dayExpeValue = parseInt(daily?.expe?.[id]) || 0; // raids if(dayRaidValue && isNaN(id)) { cumul[id] = cumul[id] + dayRaidValue; cumulRaid[id] = cumulRaid[id] + dayRaidValue; } // expeditions if(dayExpeValue) { cumul[id] = cumul[id] + dayExpeValue; cumulExpe[id] = cumulExpe[id] + dayExpeValue; if(!isNaN(id) && this.ogl.db.options.togglesOff.indexOf('ignoreExpeShips') > -1) { let shipData = Datafinder.getTech(id); cumul.metal = (cumul.metal || 0) + (shipData.metal || 0) * dayExpeValue; cumul.crystal = (cumul.crystal || 0) + (shipData.crystal || 0) * dayExpeValue; cumul.deut = (cumul.deut || 0) + (shipData.deut || 0) * dayExpeValue; cumulExpe.metal = (cumulExpe.metal || 0) + (shipData.metal || 0) * dayExpeValue; cumulExpe.crystal = (cumulExpe.crystal || 0) + (shipData.crystal || 0) * dayExpeValue; cumulExpe.deut = (cumulExpe.deut || 0) + (shipData.deut || 0) * dayExpeValue; } } }); cumulConso += daily.consumption || 0; if(daily.expeOccurences) { for(let k of Object.keys(daily.expeOccurences)) { cumulExpeOccurences[k] = (cumulExpeOccurences[k] || 0) + (daily?.expeOccurences?.[k] || 0); } } }); if(this.ogl.db.options.togglesOff.indexOf('ignoreConsumption') == -1) cumulConso = 0; let dom = document.querySelector('#links').appendChild(Util.createDom('div', {'class':'ogl_stats'})); ['metal', 'crystal', 'deut', 'dm'].forEach(res => { let line = dom.appendChild(Util.createDom('div')); line.appendChild(Util.createDom('div', {'class':`ogl_shipIcon ogl_${res}`})); line.appendChild(Util.createDom('div', {'class':`number ogl_${res}`}, Util.formatToUnits((res == 'deut' ? cumul[res]+cumulConso : cumul[res]) || '0'))); }); dom.appendChild(Util.createDom('div', {'class':'ogl_labelLimit'}, Math.floor(rangeDate) + LocalizationStrings.timeunits.short.day)); let more = dom.appendChild(Util.createDom('button', {'class':'ogl_button material-icons tooltip ogl_moreStats', 'title':this.ogl.component.lang.getText('moreStats')}, 'open_in_full')); more.addEventListener('click', () => { this.ogl.component.popup.load(); let container = Util.createDom('div', {'class':'ogl_statsDetails'}); let dateArea = container.appendChild(Util.createDom('div', {'class':'ogl_dateArea'})); let mainArea = container.appendChild(Util.createDom('div', {'class':'ogl_mainArea'})); let today = new Date(); today.setHours(0,0,0,0); let currentMonth = new Date(today.getFullYear(), today.getMonth(), 1); let currentDay = today.getDate(); let prevMonthLength = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), 0).getDate(); let monthLength = new Date(currentMonth.getFullYear(), currentMonth.getMonth()+1, 0).getDate(); let filterDiv = dateArea.appendChild(Util.createDom('div')); [1, 7, 14, 30, 40000].forEach(filter => { let button = filterDiv.appendChild(Util.createDom('div', {'class':''}, filter.toString().replace(/^1$/, 'today').replace(/^7$/, '7d').replace(/^14$/, '14d').replace(/^30$/, '30d').replace('40000', 'all'))); if(this.ogl.db.options.dateFilter == filter) button.classList.add('ogl_active'); button.addEventListener('click', () => { this.ogl.db.options.dateFilter = filter; this.addStats(Date.now() - filter * 24 * 60 * 60 * 1000, Date.now()); document.querySelector('.ogl_stats .ogl_moreStats').click(); // this.ogl.saveAsync(); }); }); // 1 - 31 days grid let dayDiv = dateArea.appendChild(Util.createDom('div')); for(let i=currentDay; i>currentDay-31; i--) { let totalSum = 0; let timestamp = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), i, 0, 0, 0).getTime(); let dateDiff = today.getDate() - i; let btn = Util.createDom('div', {'class':'ogl_button'}, i > 0 ? i : prevMonthLength+i); dayDiv.prepend(btn); if(timestamp === today.getTime()) btn.classList.add('ogl_today'); if(timestamp >= startDate && timestamp < endDate) btn.classList.add('ogl_active'); if(this.ogl.db.stats[timestamp]) { let raidSum, expeSum = 0; if(this.ogl.db.stats[timestamp].raid) raidSum = Object.values(this.ogl.db.stats[timestamp].raid).reduce((sum, a) => sum + a, 0); if(this.ogl.db.stats[timestamp].expe) expeSum = Object.values(this.ogl.db.stats[timestamp].expe).reduce((sum, a) => sum + a, 0); totalSum = raidSum + expeSum; } if(totalSum == 0) btn.classList.add('ogl_disabled'); btn.addEventListener('click', () => { this.addStats(Date.now() - (dateDiff + 1) * 24 * 60 * 60 * 1000, Date.now() - (dateDiff) * 24 * 60 * 60 * 1000); document.querySelector('.ogl_stats .ogl_moreStats').click(); }); } let calendarIcon = Util.createDom('i', {'class':'material-icons ogl_calendarIcon'}, 'date_range'); dayDiv.prepend(calendarIcon); //if(this.daysOpen) dayDiv.classList.remove('ogl_hidden'); /*let plusBtn = filterDiv.appendChild(Util.createDom('div', {'class':'ogl_button'}, '+')); plusBtn.addEventListener('click', () => { dayDiv.classList.toggle('ogl_hidden'); this.daysOpen = !dayDiv.classList.contains('ogl_hidden'); });*/ let tables = mainArea.appendChild(Util.createDom('div', {'class':'ogl_statsTables'})); let recap = mainArea.appendChild(Util.createDom('div', {'class':'ogl_statsRecap tooltip', 'title':Util.formatToUnits(cumul.metal + cumul.crystal + cumul.deut)})); recap.appendChild(Util.createDom('div', {}, 'Total')); this.mainResources.forEach(res => { let div = recap.appendChild(Util.createDom('div', {'class':`ogl_${res}`}, Util.formatToUnits(cumul[res] || '0'))); if(res == 'deut' && cumulConso) div.appendChild(Util.createDom('div', {'class':`ogl_${res}`}, Util.formatToUnits(cumulConso))); }); let firstCol = tables.appendChild(Util.createDom('span', {'class':'ogl_statsColumn'})); let chartArea = firstCol.appendChild(Util.createDom('span', {'class':'ogl_chartArea', 'data-html2canvas-ignore':true})); let chart = chartArea.appendChild(Util.createDom('span', {'class':'ogl_pie'})); let labels = chartArea.appendChild(Util.createDom('span', {'class':'ogl_pieLabel'})) let dataSum = Object.values(cumulExpeOccurences).reduce((a,b) => b>0 ? a+b : a+0, 0); let pieStats = Object.entries(cumulExpeOccurences).sort((a, b) => a[0].localeCompare(b[0])).map(x => (1 / (dataSum / x[1]) * 100)); let gradient = ''; let sum = 0; let colors = ['#e64a19', '#19bd9b', '#f9a825', '#64648b', '#c52b51', '#05abc3', '#c5ced3']; pieStats.forEach((v, index) => { gradient += `${colors[index]} ${Math.max(sum, 0)||0}%, ${colors[index]} ${Math.max(sum + v, 0)||0}%, `; sum += v; if(index == pieStats.length-1 && (isNaN(sum) || sum < 0)) gradient = ''; }); chart.style.background = `conic-gradient(${gradient}#000)`; Object.entries(cumulExpeOccurences).sort((a, b) => a[0].localeCompare(b[0])).forEach((e, index) => { if(e[0] == 'none') e[0] = 'other'; let label = labels.appendChild(Util.createDom('span', {}, `<span>${this.ogl.component.lang.getText(e[0])}</span><span>${Util.formatToUnits(Math.max(0, e[1]))}</span><b>${Math.max(0, pieStats[index].toFixed(2)) || 0}%</b>`)); label.prepend(Util.createDom('span', {'style':'background:'+colors[index]})); }); let shipsArea = firstCol.appendChild(Util.createDom('span', {'class':'ogl_shipsArea', 'data-html2canvas-ignore':true})); let expeArea = firstCol.appendChild(Util.createDom('div')); for (const [key, value] of Object.entries(cumulExpe)) { if(!this.mainResources.includes(key)) { let entry = shipsArea.appendChild(Util.createDom('div', {'class':'ogl_statsItem'}, `<div class="ogl_shipIcon ogl_${key}"></div><div class="ogl_${key}">${Util.formatToUnits(value)}</div>`)); if(value < 0) entry.classList.add('ogl_danger'); } } let withWithout = this.ogl.db.options.togglesOff.indexOf('ignoreExpeShips') == -1 ? 'w/o' : 'w/'; expeArea.appendChild(Util.createDom('h3', {}, `Expe (<u class="tooltip" title="ø ${Util.formatToUnits(Math.round((cumulExpe.metal + cumulExpe.crystal + cumulExpe.deut) / expeOccurences))} | Σ ${Util.formatToUnits(Math.round(cumulExpe.metal + cumulExpe.crystal + cumulExpe.deut))}">${Util.formatNumber(expeOccurences)}</u>) ${withWithout} ships`)); for (const [key, value] of Object.entries(cumulExpe)) { if(this.mainResources.includes(key)) { let entry = expeArea.appendChild(Util.createDom('div', {'class':'ogl_statsItem'}, `<div class="ogl_shipIcon ogl_${key}"></div><div class="ogl_${key}">${Util.formatToUnits(value)}</div>`)); if(value < 0) entry.classList.add('ogl_danger'); } } let raidArea = firstCol.appendChild(Util.createDom('div')); raidArea.appendChild(Util.createDom('h3', {}, `Raid (<u class="tooltip" title="ø ${Util.formatToUnits(Math.round((cumulRaid.metal + cumulRaid.crystal + cumulRaid.deut) / raidOccurences))} | Σ ${Util.formatToUnits(Math.round(cumulRaid.metal + cumulRaid.crystal + cumulRaid.deut))}">${Util.formatNumber(raidOccurences)}</u>)`)); for (const [key, value] of Object.entries(cumulRaid)) { raidArea.appendChild(Util.createDom('div', {'class':'ogl_statsItem'}, `<div class="ogl_shipIcon ogl_${key}"></div><div class="ogl_${key}">${Util.formatToUnits(value)}</div>`)); } raidArea.appendChild(Util.createDom('h3', {}, 'ø / day')); for (const [key, value] of Object.entries(cumul)) { if(this.mainResources.includes(key)) raidArea.appendChild(Util.createDom('div', {'class':'ogl_statsItem'}, `<div class="ogl_shipIcon ogl_${key}"></div><div class="ogl_${key}">${Util.formatToUnits(Math.round(value/rangeDate))}</div>`)); } raidArea.appendChild(Util.createDom('h3', {}, 'ø + prod / day')); for (const [key, value] of Object.entries(cumul)) { if(this.mainResources.includes(key)) { let resIndex = key == 'metal' ? '0' : key == 'crystal' ? '1' : '2'; let totalRes = parseInt(this.ogl.account.totalProd[resIndex]); if(key == 'dm') raidArea.appendChild(Util.createDom('div', {'class':'ogl_statsItem'}, `<div class="ogl_shipIcon ogl_${key}"></div><div class="ogl_${key}">${Util.formatToUnits(Math.round(value/rangeDate))}</div>`)); else if(isNaN(key)) raidArea.appendChild(Util.createDom('div', {'class':'ogl_statsItem'}, `<div class="ogl_shipIcon ogl_${key}"></div><div class="ogl_${key}">${Util.formatToUnits(Math.round(parseFloat(value)/rangeDate) + totalRes*24*3600)}</div>`)); } } if(!sum || emptyData) { chartArea.classList.add('ogl_hidden'); shipsArea.classList.add('ogl_hidden'); expeArea.classList.add('ogl_hidden'); if(emptyData) raidArea.classList.add('ogl_hidden'); } let shareButton = Util.createDom('div', {'class':'ogl_button'}, '<i class="material-icons">file_download</i>Download (.jpg)'); shareButton.addEventListener('click', () => { shareButton.textContent = 'loading...'; shareButton.classList.add('ogl_disabled'); container.querySelectorAll('[data-html2canvas-ignore]').forEach(e => e.style.display = 'none'); container.querySelectorAll('.ogl_shipIcon').forEach(e => e.style.visibility = 'hidden'); Util.takeScreenshot(container, shareButton, `ogl_${this.ogl.universe.name}_${this.ogl.universe.lang}_stats_${serverTime.getTime()}`); }); this.ogl.component.popup.open(container, () => { this.ogl.component.popup.content.appendChild(shareButton); }); }); let blackholeButton = dom.appendChild(Util.createDom('button', {'class':'ogl_button material-icons tooltip', 'title':this.ogl.component.lang.getText('signalBlackhole')}, 'sentiment_very_dissatisfied')); blackholeButton.addEventListener('click', () => { this.ogl.component.popup.load(); let date = new Date(); let midnight = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0).getTime(); let container = Util.createDom('div', {'class':'ogl_blackHole'}); [202,203,204,205,206,207,208,209,210,211,213,214,215,218,219].forEach(shipID => { let content = container.appendChild(Util.createDom('div')); content.appendChild(Util.createDom('div', {'class':'ogl_shipIcon ogl_'+shipID})); content.appendChild(Util.createDom('input', {'type':'text', 'class':'ogl_checkInput', 'data-ship':shipID})); }); let confirmButton = Util.createDom('div', {'class':'ogl_button'}, 'OK'); confirmButton.addEventListener('click', () => { if(confirm('Do you really want to add this black hole ?')) { let result = {}; container.querySelectorAll('input').forEach(input => { let shipID = parseInt(input.getAttribute('data-ship')); let amount = parseInt(input.value.replace(/[\,\. ]/g, '')); if(!isNaN(shipID) && !isNaN(amount)) result[shipID] = amount; }); this.ogl.db.stats[midnight] = this.ogl.db.stats[midnight] = this.ogl.db.stats[midnight] || { idList:[], expe:{}, raid:{}, expeOccurences:{}, raidOccurences:0, consumption:0 }; this.ogl.db.stats[midnight].expe = this.ogl.db.stats[midnight].expe || {}; this.ogl.db.stats.total.expe = this.ogl.db.stats.total.expe || {}; this.ogl.db.stats[midnight].expeOccurences = this.ogl.db.stats[midnight].expeOccurences || {}; this.ogl.db.stats.total.expeOccurences = this.ogl.db.stats.total.expeOccurences || {}; for(let [k,v] of Object.entries(result)) { this.ogl.db.stats[midnight].expe[k] = (this.ogl.db.stats[midnight].expe?.[k] || 0) - v; this.ogl.db.stats.total.expe[k] = (this.ogl.db.stats.total.expe?.[k] || 0) - v; } this.ogl.db.stats[midnight].expeOccurences.blackhole = (this.ogl.db.stats[midnight].expeOccurences?.blackhole || 0) + 1; this.ogl.db.stats.total.expeOccurences.blackhole = (this.ogl.db.stats.total.expeOccurences?.blackhole || 0) + 1; this.addStats(); this.ogl.component.popup.close(); } }); this.ogl.component.popup.open(container, () => { this.ogl.component.popup.content.appendChild(confirmButton); }); }); /* let resetButton = dom.appendChild(Util.createDom('button', {'class':'ogl_button material-icons tooltip', 'title':this.ogl.component.lang.getText('eraseData')}, 'delete_forever')); resetButton.addEventListener('click', () => { if(confirm('Do you want to erase stats data ?')) { delete this.ogl.db.stats; this.ogl.save(); document.location.reload(); } }); */ } addCalendar(startDate, endDate) { let domElement = Util.createDom('div', {'class':'ogl_calendar'}); // Liste des jours de la semaine let dayList = []; for(let i=0; i<7; i++) { dayList.push(new Date(24*60*60*1000*(4+i)).toLocaleString('en-EN', {weekday:'long'})); } // Date actuelle let today = new Date(); today.setHours(0,0,0,0); // Mois actuel let currentMonth = new Date(today.getFullYear(), today.getMonth(), 1); // On créé le div qui contiendra les jours de notre calendrier let content = document.createElement('div'); domElement.appendChild(content); // Création des cellules contenant le jour de la semaine for(let i=0; i<dayList.length; i++) { content.appendChild(Util.createDom('span', {'class':'cell day'}, dayList[i].substring(0, 3).toUpperCase())); } // Création des cellules vides si nécessaire for(let i=1; i<currentMonth.getDay(); i++) { content.appendChild(Util.createDom('div', {'class':'cell empty'})); } // Nombre de jour dans le mois affiché let monthLength = new Date(currentMonth.getFullYear(), currentMonth.getMonth()+1, 0).getDate(); // Création des cellules contenant les jours du mois affiché for(let i=1; i<=monthLength; i++) { let cell = content.appendChild(Util.createDom('span', {'class':'cell'}, i)); // Timestamp de la cellule let timestamp = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), i, 0, 0, 0).getTime(); // Ajoute une classe spéciale pour aujourd'hui if(timestamp === today.getTime()) cell.classList.add('ogl_today'); else if (timestamp > today.getTime()) cell.classList.add('ogl_disabled'); if(timestamp >= startDate && timestamp < endDate) { cell.classList.add('ogl_active'); } if(timestamp - 24 * 60 * 60 * 1000 <= startDate && timestamp >= startDate && !content.querySelector('.ogl_firstDate')) cell.classList.add('ogl_firstDate'); if(timestamp + 24 * 60 * 60 * 1000 >= endDate && !content.querySelector('.ogl_lastDate')) cell.classList.add('ogl_lastDate'); let dateDiff = today.getDate() - i; let total = 0; if(this.ogl.db.stats[timestamp]) { let raids = Object.keys(this.ogl.db.stats?.[timestamp]?.raid || {}).length ? Object.values(this.ogl.db.stats?.[timestamp]?.raid || {a:0}).reduce((a, b) => a + b) : 0; let expes = Object.keys(this.ogl.db.stats?.[timestamp]?.expe || {}).length ? Object.values(this.ogl.db.stats?.[timestamp]?.expe || {a:0}).reduce((a, b) => a + b) : 0; total = raids + expes; } if(total == 0) cell.classList.add('ogl_disabled'); cell.addEventListener('click', () => { this.addStats(Date.now() - (dateDiff + 1) * 24 * 60 * 60 * 1000, Date.now() - (dateDiff) * 24 * 60 * 60 * 1000); document.querySelector('.ogl_stats .ogl_moreStats').click(); }); } if(!content.querySelector('.ogl_firstDate') && content.querySelector('.cell.empty')) { content.querySelector('.cell.empty:last-of-type').classList.add('ogl_disabled'); content.querySelector('.cell.empty:last-of-type').classList.add('ogl_beforeDate'); } return domElement; } lockTech(tech) { let coords = this.ogl.current.coords.join(':'); tech.onMoon = this.ogl.current.type == 'moon'; this.ogl.db.lock = this.ogl.db.lock || {}; this.ogl.db.lock[coords] = this.ogl.db.lock[coords] || {}; this.ogl.db.lock[coords][`${tech.id}_${tech.level}_${this.ogl.current.type}`] = tech; // this.ogl.saveAsync(); this.checkLockedTechs(); } checkLockedTechs(refresh, noSub) { let coords = this.ogl.current.coords.join(':'); let pageList = ['supplies', 'facilities', 'research', 'shipyard', 'defenses', 'lfbuildings', 'lfresearch']; if(pageList.indexOf(this.ogl.page) > -1 && this.ogl.db.lock?.[coords]) { Object.keys(this.ogl.db.lock[coords]).forEach(key => { if(this.ogl.db.lock[coords][key] && key.indexOf(this.ogl.current.type) > -1) { if(this.ogl.db.lock[coords][key].level <= parseInt(document.querySelector(`[data-technology="${this.ogl.db.lock[coords][key].id}"] .targetlevel`)?.getAttribute('data-value') || document.querySelector(`[data-technology="${this.ogl.db.lock[coords][key].id}"] .level`)?.getAttribute('data-value') || 0)) { delete(this.ogl.db.lock[coords][key]); } } }); } document.querySelectorAll('.smallplanet').forEach(planet => { planet.querySelector('.ogl_lockedIcon') && planet.querySelector('.ogl_lockedIcon').remove(); let coords = planet.querySelector('.planet-koords').textContent.slice(1, -1); if(this.ogl.db.lock?.[coords] && Object.entries(this.ogl.db.lock[coords]).length > 0) { let button = planet.appendChild(Util.createDom('div', {'class':'ogl_lockedIcon material-icons tooltipLeft'}, 'lock')); let tooltipCumul = [0,0,0]; let isReady = false; for(let tech of Object.values(this.ogl.db.lock[coords])) { tooltipCumul[0] += tech.metal; tooltipCumul[1] += tech.crystal; tooltipCumul[2] += tech.deut; if(tech.metal == 0 && tech.crystal == 0 && tech.deut == 0) isReady = true; } if(isReady) button.classList.add('ogl_ok'); button.title = 'Locked' + '<div class="splitLine"></div>'; ['metal','crystal','deut'].forEach((res, index) => { let resName = this.ogl.component.lang.getText(res); button.title += `<div>${resName}: <span class="ogl_${res} float_right">${Util.formatToUnits(tooltipCumul[index])}</span></div>`; }); button.addEventListener('click', () => { this.ogl.component.popup.load(); if(!noSub) { this.availableResources = [(this.ogl.db.me?.planets?.[coords]?.resources?.metal || 0), (this.ogl.db.me?.planets?.[coords]?.resources?.crystal || 0), (this.ogl.db.me?.planets?.[coords]?.resources?.deut || 0)]; } let container = Util.createDom('div', {'class':'ogl_lockPopup'}); let planetContainer = container.appendChild(Util.createDom('div', {'class':'ogl_lockedContainer'})); let moonContainer = container.appendChild(Util.createDom('div', {'class':'ogl_lockedContainer'})); let cumul = [0, 0, 0, 0, 0, 0]; for(let tech of Object.values(this.ogl.db.lock[coords])) { let targetContainer = tech.onMoon ? moonContainer : planetContainer; targetContainer.appendChild(Util.createDom('span', {}, tech.name)); targetContainer.appendChild(Util.createDom('i', {}, tech.amount > 1 ? tech.amount : tech.level)); targetContainer.appendChild(Util.createDom('b', {'class':'ogl_metal'}, Util.formatToUnits(tech.metal))); targetContainer.appendChild(Util.createDom('b', {'class':'ogl_crystal'}, Util.formatToUnits(tech.crystal))); targetContainer.appendChild(Util.createDom('b', {'class':'ogl_deut'}, Util.formatToUnits(tech.deut))); let substract = targetContainer.appendChild(Util.createDom('b', {'class':'material-icons'}, 'remove')); if(this.availableResources[0] <= 0 && this.availableResources[1] <= 0 && this.availableResources[2] <= 0) { substract.classList.add('ogl_disabled'); } substract.addEventListener('click', () => { let key = `${tech.id}_${tech.level}_${tech.onMoon ? 'moon' : 'planet'}`; if(this.availableResources[0] > 0) this.ogl.db.lock[coords][key].metal = Math.max(tech.metal - (this.ogl.db.me?.planets?.[coords]?.resources?.metal || 0), 0); if(this.availableResources[1] > 0) this.ogl.db.lock[coords][key].crystal = Math.max(tech.crystal - (this.ogl.db.me?.planets?.[coords]?.resources?.crystal || 0), 0); if(this.availableResources[2] > 0) this.ogl.db.lock[coords][key].deut = Math.max(tech.deut - (this.ogl.db.me?.planets?.[coords]?.resources?.deut || 0), 0); this.availableResources[0] -= tech.metal; this.availableResources[1] -= tech.crystal; this.availableResources[2] -= tech.deut; // this.ogl.saveAsync(); this.ogl.component.popup.close(); this.checkLockedTechs(coords, true); }); let send = targetContainer.appendChild(Util.createDom('b', {'class':'material-icons'}, 'local_shipping')); send.addEventListener('click', () => { this.ogl.db.lockedList = []; this.ogl.db.lockedList.push(`${tech.id}_${tech.level}_${tech.onMoon ? 'moon' : 'planet'}`); this.ogl.save(); let splitted = coords.split(':'); Util.redirect(`https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=3&galaxy=${splitted[0]}&system=${splitted[1]}&position=${splitted[2]}&mission=${this.ogl.db.options.defaultMission}&type=${tech.onMoon ? 3 : 1}`, this.ogl); }); let remove = targetContainer.appendChild(Util.createDom('b', {'class':'material-icons'}, 'close')); remove.addEventListener('click', () => { delete this.ogl.db.lock[coords][`${tech.id}_${tech.level}_${!tech.onMoon ? 'planet' : 'moon'}`]; // this.ogl.saveAsync(); this.ogl.component.popup.close(); this.checkLockedTechs(coords, noSub); }); let offset = tech.onMoon ? 3 : 0; cumul[0 + offset] += tech.metal; cumul[1 + offset] += tech.crystal; cumul[2 + offset] += tech.deut; } ['planet', 'moon'].forEach(e => { let headerContainer = e == 'planet' ? planetContainer : moonContainer; let offset = e == 'planet' ? 0 : 3; headerContainer.appendChild(Util.createDom('span', {'class':'ogl_header'}, 'Total ' + e)); headerContainer.appendChild(Util.createDom('i', {'class':'ogl_header'}, ' ')); headerContainer.appendChild(Util.createDom('b', {'class':'ogl_header ogl_metal'}, Util.formatToUnits(cumul[0 + offset]))); headerContainer.appendChild(Util.createDom('b', {'class':'ogl_header ogl_crystal'}, Util.formatToUnits(cumul[1 + offset]))); headerContainer.appendChild(Util.createDom('b', {'class':'ogl_header ogl_deut'}, Util.formatToUnits(cumul[2 + offset]))); headerContainer.appendChild(Util.createDom('i', {'class':'ogl_header'}, ' ')); let send = headerContainer.appendChild(Util.createDom('b', {'class':'ogl_header material-icons'}, 'local_shipping')); send.addEventListener('click', () => { this.ogl.db.lockedList = []; for(let tech of Object.values(this.ogl.db.lock[coords])) { if(this.ogl.db.lock[coords][`${tech.id}_${tech.level}_${e}`]) { this.ogl.db.lockedList.push(`${tech.id}_${tech.level}_${e}`); this.ogl.save(); let splitted = coords.split(':'); Util.redirect(`https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&ogl_mode=3&galaxy=${splitted[0]}&system=${splitted[1]}&position=${splitted[2]}&mission=${this.ogl.db.options.defaultMission}&type=${tech.onMoon ? 3 : 1}`, this.ogl); } } }); let remove = headerContainer.appendChild(Util.createDom('b', {'class':'ogl_header material-icons'}, 'close')); remove.addEventListener('click', () => { for(let tech of Object.values(this.ogl.db.lock[coords])) { if(this.ogl.db.lock[coords][`${tech.id}_${tech.level}_${e}`]) delete this.ogl.db.lock[coords][`${tech.id}_${tech.level}_${e}`]; } // this.ogl.saveAsync(); this.ogl.component.popup.close(); this.checkLockedTechs(coords); }); }); this.ogl.component.popup.open(container); }); if(refresh && refresh == coords) button.click(); } }); } checkStorage() { if(this.ogl.current.type == 'moon') return; let storage = { 'metal' : resourcesBar.resources.metal.storage, 'crystal' : resourcesBar.resources.crystal.storage, 'deut' : resourcesBar.resources.deuterium.storage, }; ['metal', 'crystal', 'deut'].forEach(res => { let prod = resourcesBar.resources[res.replace('deut', 'deuterium')].tooltip.replace(/\./g, '').match(/\d+/g)[2]; let timeLeft = prod > 0 ? Math.floor((storage[res] - this.ogl.current[res]) / prod) || 0 : 0; let day = Math.max(0, Math.floor(timeLeft / 24)); let hour = Math.max(0, Math.floor(timeLeft % 24)); let box = document.querySelector(`#${res.replace('deut', 'deuterium')}_box`); let text = day > 365 ? `> 365${LocalizationStrings.timeunits.short.day}` : `${day}${LocalizationStrings.timeunits.short.day}<br>${hour}${LocalizationStrings.timeunits.short.hour}`; box.querySelector('.resourceIcon').appendChild(Util.createDom('div', {'class':'ogl_storage'}, text)); }); } checkCrawlers() { if(this.ogl.current.type == 'planet' && (this.ogl.page == 'supplies' || this.ogl.page == 'shipyard')) { let currentCoords = this.ogl.current.coords.join(':'); let maxCrawler = ((this.ogl.db.me.planets?.[currentCoords]?.techs?.[1] || 0) + (this.ogl.db.me.planets?.[currentCoords]?.techs?.[2] || 0) + (this.ogl.db.me.planets?.[currentCoords]?.techs?.[3] || 0)) * 8; if(document.querySelector('#officers .geologist.on') && this.ogl.account.class == 1) maxCrawler += maxCrawler * .1; document.querySelector('.technology[data-technology="217"] .amount span').appendChild(Util.createDom('span', {'class':'ogl_maxCrawler'}, ` / ${Util.formatNumber(Math.floor(maxCrawler))}`)); } } getEmpireData(forced) { let now = Date.now(); if((now > this.ogl.db.lastEmpireUpdate + 300000 && document.visibilityState === 'visible') || forced) // update every 5 mn { let stacks = 0; let maxLoop = document.querySelector('.smallplanet .moonlink') ? 2 : 1; for(let i=0; i<maxLoop; i++) { $.ajax( { url:`https://${window.location.host}/game/index.php?page=ajax&component=empire&ajax=1&asJson=1&planetType=${i}`, type:'GET', dataType:'json', success:result => { let data = JSON.parse(result.mergedArray).planets; if(!data) return; Object.values(data).forEach(p => { let stockDiv = Util.createDom('div', {'class':'ogl_stock'}); let coords = p.coordinates.slice(1, -1); if(p.type != 1) coords += ':M'; let currentPlanetCoords = this.ogl.current.coords.join(':'); if(this.ogl.current.type == 'moon') currentPlanetCoords += ':M'; this.ogl.db.me.planets[coords] = this.ogl.db.me.planets[coords] || { techs:{} }; this.ogl.db.me.planets[coords].techs = this.ogl.db.me.planets[coords].techs || {}; this.ogl.db.me.planets[coords].resources = this.ogl.db.me.planets[coords].resources || {}; this.ogl.db.me.planets[coords].production = this.ogl.db.me.planets[coords].production || []; this.ogl.db.me.planets[coords].storage = (this.ogl.db.me.planets[coords].storage?.constructor?.name == 'array' ? {} : this.ogl.db.me.planets[coords].storage) || {}; Object.keys(p).forEach(k => { if(!isNaN(k)) { this.ogl.db.me.planets[coords].techs[k] = p[k]; } else { // resources if(k == 'metal' && coords != currentPlanetCoords) this.ogl.db.me.planets[coords].resources.metal = p[k]; else if(k == 'crystal' && coords != currentPlanetCoords) this.ogl.db.me.planets[coords].resources.crystal = p[k]; else if(k == 'deuterium' && coords != currentPlanetCoords) this.ogl.db.me.planets[coords].resources.deut = p[k]; else if(k == 'food' && coords != currentPlanetCoords) this.ogl.db.me.planets[coords].resources.food = p[k]; else if(k == 'population' && coords != currentPlanetCoords) this.ogl.db.me.planets[coords].resources.population = p[k]; // storage else if(k == 'metalStorage') this.ogl.db.me.planets[coords].storage.metal = p[k]; else if(k == 'crystalStorage') this.ogl.db.me.planets[coords].storage.crystal = p[k]; else if(k == 'deuteriumStorage') this.ogl.db.me.planets[coords].storage.deut = p[k]; else if(k == 'foodStorage') this.ogl.db.me.planets[coords].storage.food = p[k]; else if(k == 'populationStorage') this.ogl.db.me.planets[coords].storage.population = p[k]; // production else if(k == 'production') { this.ogl.db.me.planets[coords].production[0] = (p[k].hourly[0]/ 3600).toFixed(2); this.ogl.db.me.planets[coords].production[1] = (p[k].hourly[1]/ 3600).toFixed(2); this.ogl.db.me.planets[coords].production[2] = (p[k].hourly[2]/ 3600).toFixed(2); this.ogl.db.me.planets[coords].production[3] = serverTime.getTime(); } // other else if(k == 'fieldUsed') this.ogl.db.me.planets[coords].fieldUsed = p[k]; else if(k == 'fieldMax') this.ogl.db.me.planets[coords].fieldMax = p[k]; else if(k == 'temperature') this.ogl.db.me.planets[coords].temperature = p[k].match(/[-+]?[0-9]*\.?[0-9]+/g)[1]; } }); let targetType = i != 1 ? 'planetlink' : 'moonlink'; let targetID = i != 1 ? p.id : p.planetID; let target = document.querySelector(`.smallplanet[id="planet-${targetID}"] .${targetType}`); ['metal', 'crystal', 'deut'].forEach(res => { let storage = this.ogl.db.me.planets?.[coords]?.storage?.[res]; let amount = this.ogl.db.me.planets[coords].resources[res]; let line = stockDiv.appendChild(Util.createDom('div', {'class':`ogl_${res}`}, Util.formatToUnits(amount))); if(storage && amount >= storage && i != 1) line.classList.add('ogl_full'); }); target.querySelector('.ogl_stock').innerHTML = stockDiv.innerHTML; }); stacks++; if(stacks == maxLoop) { this.ogl.db.lastEmpireUpdate = now; this.ogl.saveAsync(); } } }); } } //else setTimeout(() => this.getEmpireData(true), 60000); } reloadEventbox() { if(document.querySelector('#eventboxContent h2 .ogl_button') || !document.querySelector('#eventboxContent h2')) return; let button = document.querySelector('#eventboxContent h2').appendChild(Util.createDom('div', {'class':'ogl_button material-icons'}, 'refresh')); button.addEventListener('click', () => { if(document.querySelector('#eventboxContent #eventContent').querySelector('.ogl_loader')) return; document.querySelector('#eventboxContent #eventContent').textContent = ''; document.querySelector('#eventboxContent #eventContent').appendChild(Util.createDom('div', {'class':'ogl_loader'})); Util.getRaw(eventlistLink, result => { $("#eventboxContent").html(result); toggleEvents.loaded = true; }); }); } } class Datafinder { static getTech(id) { let tech = { // base 1 : { priceFactor:1.5 }, 2 : { priceFactor:1.6 }, 3 : { priceFactor:1.5 }, 4 : { priceFactor:1.5 }, 12 : { priceFactor:1.8 }, 33 : { energyFactor:2 }, 36 : { priceFactor:5, energyFactor:2.5 }, 124 : { priceFactor:1.75 }, 199 : { priceFactor:3, energyFactor:3 }, // ship 202: { metal:2000, crystal:2000, deut:0 }, 203: { metal:6000, crystal:6000, deut:0 }, 204: { metal:3000, crystal:1000, deut:0 }, 205: { metal:6000, crystal:4000, deut:0 }, 206: { metal:20000, crystal:7000, deut:2000 }, 207: { metal:45000, crystal:15000, deut:0 }, 208: { metal:10000, crystal:20000, deut:10000 }, 209: { metal:10000, crystal:6000, deut:2000 }, 210: { crystal:1000, deut:0 }, 211: { metal:50000, crystal:25000, deut:15000 }, 212: { metal:0, crystal:2000, deut:500 }, 213: { metal:60000, crystal:50000, deut:15000 }, 214: { metal:5000000, crystal:4000000, deut:1000000 }, 215: { metal:30000, crystal:40000, deut:15000 }, 217: { metal:2000, crystal:2000, deut:1000 }, 218: { metal:85000, crystal:55000, deut:20000 }, 219: { metal:8000, crystal:15000, deut:8000 }, // def 401: { metal:2000, crystal:0, deut:0 }, 402: { metal:1500, crystal:500, deut:0 }, 403: { metal:6000, crystal:2000, deut:0 }, 404: { metal:20000, crystal:15000, deut:2000 }, 405: { metal:5000, crystal:3000, deut:0 }, 406: { metal:50000, crystal:50000, deut:30000 }, 407: { metal:10000, crystal:10000, deut:0 }, 408: { metal:50000, crystal:50000, deut:0 }, // lifeforms "11101":{"name":"Residential Sector","type":"Building","lifeform":"Human","metal":7,"crystal":2,"deut":0,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":210,"factorBonus1":1.21,"maxBonus1":"","baseBonus2":16,"factorBonus2":1.2,"maxBonus2":"","baseBonus3":9,"factorBonus3":1.15,"maxBonus3":"","durationFactor":1.21,"duration":40},"11102":{"name":"Biosphere Farm","type":"Building","lifeform":"Human","metal":5,"crystal":2,"deut":0,"energy":8,"priceFactor":1.23,"energyFactor":1.02,"baseBonus1":10,"factorBonus1":1.15,"maxBonus1":"","baseBonus2":10,"factorBonus2":1.14,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.25,"duration":40},"11103":{"name":"Research Centre","type":"Building","lifeform":"Human","metal":20000,"crystal":25000,"deut":10000,"energy":10,"priceFactor":1.3,"energyFactor":1.08,"baseBonus1":0.25,"factorBonus1":1,"maxBonus1":0.25,"baseBonus2":2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.25,"duration":16000},"11104":{"name":"Academy of Sciences","type":"Building","lifeform":"Human","metal":5000,"crystal":3200,"deut":1500,"energy":15,"priceFactor":1.7,"energyFactor":1.25,"baseBonus1":20000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.6,"duration":16000},"11105":{"name":"Neuro-Calibration Centre","type":"Building","lifeform":"Human","metal":50000,"crystal":40000,"deut":50000,"energy":30,"priceFactor":1.7,"energyFactor":1.25,"baseBonus1":100000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.7,"duration":64000},"11106":{"name":"High Energy Smelting","type":"Building","lifeform":"Human","metal":9000,"crystal":6000,"deut":3000,"energy":40,"priceFactor":1.5,"energyFactor":1.1,"baseBonus1":1.5,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"11107":{"name":"Food Silo","type":"Building","lifeform":"Human","metal":25000,"crystal":13000,"deut":7000,"energy":"","priceFactor":1.09,"energyFactor":"","baseBonus1":1,"factorBonus1":1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":0.8,"baseBonus3":0.8,"factorBonus3":1,"maxBonus3":"","durationFactor":1.17,"duration":12000},"11108":{"name":"Fusion-Powered Production","type":"Building","lifeform":"Human","metal":50000,"crystal":25000,"deut":15000,"energy":80,"priceFactor":1.5,"energyFactor":1.1,"baseBonus1":1.5,"factorBonus1":1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":28000},"11109":{"name":"Skyscraper","type":"Building","lifeform":"Human","metal":75000,"crystal":20000,"deut":25000,"energy":50,"priceFactor":1.09,"energyFactor":1.02,"baseBonus1":1.5,"factorBonus1":1,"maxBonus1":"","baseBonus2":1.5,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":40000},"11110":{"name":"Biotech Lab","type":"Building","lifeform":"Human","metal":150000,"crystal":30000,"deut":15000,"energy":60,"priceFactor":1.12,"energyFactor":1.03,"baseBonus1":5,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":52000},"11111":{"name":"Metropolis","type":"Building","lifeform":"Human","metal":80000,"crystal":35000,"deut":60000,"energy":90,"priceFactor":1.5,"energyFactor":1.05,"baseBonus1":0.5,"factorBonus1":1,"maxBonus1":1,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":90000},"11112":{"name":"Planetary Shield","type":"Building","lifeform":"Human","metal":250000,"crystal":125000,"deut":125000,"energy":100,"priceFactor":1.2,"energyFactor":1.02,"baseBonus1":1.5,"factorBonus1":1,"maxBonus1":0.8,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":95000},"11201":{"name":"Intergalactic Envoys","type":"Tech 1","lifeform":"Human","metal":5000,"crystal":2500,"deut":500,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":1,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":1000},"11202":{"name":"High-Performance Extractors","type":"Tech 2","lifeform":"Human","metal":7000,"crystal":10000,"deut":5000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.06,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"11203":{"name":"Fusion Drives","type":"Tech 3","lifeform":"Human","metal":15000,"crystal":10000,"deut":5000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.5,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2500},"11204":{"name":"Stealth Field Generator","type":"Tech 4","lifeform":"Human","metal":20000,"crystal":15000,"deut":7500,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":3500},"11205":{"name":"Orbital Den","type":"Tech 5","lifeform":"Human","metal":25000,"crystal":20000,"deut":10000,"energy":"","priceFactor":1.4,"energyFactor":"","baseBonus1":4,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":4500},"11206":{"name":"Research AI","type":"Tech 6","lifeform":"Human","metal":35000,"crystal":25000,"deut":15000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":5000},"11207":{"name":"High-Performance Terraformer","type":"Tech 7","lifeform":"Human","metal":70000,"crystal":40000,"deut":20000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8000},"11208":{"name":"Enhanced Production Technologies","type":"Tech 8","lifeform":"Human","metal":80000,"crystal":50000,"deut":20000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.06,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":6000},"11209":{"name":"Light Fighter Mk II","type":"Tech 9","lifeform":"Human","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":6500},"11210":{"name":"Cruiser Mk II","type":"Tech 10","lifeform":"Human","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":7000},"11211":{"name":"Improved Lab Technology","type":"Tech 11","lifeform":"Human","metal":120000,"crystal":30000,"deut":25000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":7500},"11212":{"name":"Plasma Terraformer","type":"Tech 12","lifeform":"Human","metal":100000,"crystal":40000,"deut":30000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":10000},"11213":{"name":"Low-Temperature Drives","type":"Tech 13","lifeform":"Human","metal":200000,"crystal":100000,"deut":100000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8500},"11214":{"name":"Bomber Mk II","type":"Tech 14","lifeform":"Human","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":9000},"11215":{"name":"Destroyer Mk II","type":"Tech 15","lifeform":"Human","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":9500},"11216":{"name":"Battlecruiser Mk II","type":"Tech 16","lifeform":"Human","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":10000},"11217":{"name":"Robot Assistants","type":"Tech 17","lifeform":"Human","metal":300000,"crystal":180000,"deut":120000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":11000},"11218":{"name":"Supercomputer","type":"Tech 18","lifeform":"Human","metal":500000,"crystal":300000,"deut":200000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":13000},"12101":{"name":"Meditation Enclave","type":"Building","lifeform":"Rock´tal","metal":9,"crystal":3,"deut":0,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":150,"factorBonus1":1.22,"maxBonus1":"","baseBonus2":12,"factorBonus2":1.2,"maxBonus2":"","baseBonus3":5,"factorBonus3":1.15,"maxBonus3":"","durationFactor":1.21,"duration":40},"12102":{"name":"Crystal Farm","type":"Building","lifeform":"Rock´tal","metal":7,"crystal":2,"deut":0,"energy":10,"priceFactor":1.2,"energyFactor":1.03,"baseBonus1":8,"factorBonus1":1.15,"maxBonus1":"","baseBonus2":6,"factorBonus2":1.14,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.21,"duration":40},"12103":{"name":"Rune Technologium","type":"Building","lifeform":"Rock´tal","metal":40000,"crystal":10000,"deut":15000,"energy":15,"priceFactor":1.3,"energyFactor":1.1,"baseBonus1":0.25,"factorBonus1":1,"maxBonus1":0.25,"baseBonus2":2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.25,"duration":16000},"12104":{"name":"Rune Forge","type":"Building","lifeform":"Rock´tal","metal":5000,"crystal":3800,"deut":1000,"energy":20,"priceFactor":1.7,"energyFactor":1.35,"baseBonus1":16000000,"factorBonus1":1.14,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.6,"duration":16000},"12105":{"name":"Oriktorium","type":"Building","lifeform":"Rock´tal","metal":50000,"crystal":40000,"deut":50000,"energy":60,"priceFactor":1.65,"energyFactor":1.3,"baseBonus1":90000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.7,"duration":64000},"12106":{"name":"Magma Forge","type":"Building","lifeform":"Rock´tal","metal":10000,"crystal":8000,"deut":1000,"energy":40,"priceFactor":1.4,"energyFactor":1.1,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"12107":{"name":"Disruption Chamber","type":"Building","lifeform":"Rock´tal","metal":20000,"crystal":15000,"deut":10000,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":1.5,"factorBonus1":1,"maxBonus1":"","baseBonus2":0.5,"factorBonus2":1,"maxBonus2":0.4,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.25,"duration":16000},"12108":{"name":"Megalith","type":"Building","lifeform":"Rock´tal","metal":50000,"crystal":35000,"deut":15000,"energy":80,"priceFactor":1.5,"energyFactor":1.3,"baseBonus1":1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":1,"factorBonus2":1,"maxBonus2":0.5,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":40000},"12109":{"name":"Crystal Refinery","type":"Building","lifeform":"Rock´tal","metal":85000,"crystal":44000,"deut":25000,"energy":90,"priceFactor":1.4,"energyFactor":1.1,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":40000},"12110":{"name":"Deuterium Synthesiser","type":"Building","lifeform":"Rock´tal","metal":120000,"crystal":50000,"deut":20000,"energy":90,"priceFactor":1.4,"energyFactor":1.1,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":52000},"12111":{"name":"Mineral Research Centre","type":"Building","lifeform":"Rock´tal","metal":250000,"crystal":150000,"deut":100000,"energy":120,"priceFactor":1.8,"energyFactor":1.3,"baseBonus1":0.5,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":90000},"12112":{"name":"Advanced Recycling Plant","type":"Building","lifeform":"Rock´tal","metal":250000,"crystal":125000,"deut":125000,"energy":100,"priceFactor":1.5,"energyFactor":1.1,"baseBonus1":0.6,"factorBonus1":1,"maxBonus1":0.3,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":95000},"12201":{"name":"Volcanic Batteries","type":"Tech 1","lifeform":"Rock´tal","metal":10000,"crystal":6000,"deut":1000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.25,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":1000},"12202":{"name":"Acoustic Scanning","type":"Tech 2","lifeform":"Rock´tal","metal":7500,"crystal":12500,"deut":5000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"12203":{"name":"High Energy Pump Systems","type":"Tech 3","lifeform":"Rock´tal","metal":15000,"crystal":10000,"deut":5000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2500},"12204":{"name":"Cargo Hold Expansion (Civilian Ships)","type":"Tech 4","lifeform":"Rock´tal","metal":20000,"crystal":15000,"deut":7500,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.4,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":3500},"12205":{"name":"Magma-Powered Production","type":"Tech 5","lifeform":"Rock´tal","metal":25000,"crystal":20000,"deut":10000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":4500},"12206":{"name":"Geothermal Power Plants","type":"Tech 6","lifeform":"Rock´tal","metal":50000,"crystal":50000,"deut":20000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.25,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":5000},"12207":{"name":"Depth Sounding","type":"Tech 7","lifeform":"Rock´tal","metal":70000,"crystal":40000,"deut":20000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":5500},"12208":{"name":"Ion Crystal Enhancement (Heavy Fighter)","type":"Tech 8","lifeform":"Rock´tal","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":6000},"12209":{"name":"Improved Stellarator","type":"Tech 9","lifeform":"Rock´tal","metal":75000,"crystal":55000,"deut":25000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.15,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.3,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":6500},"12210":{"name":"Hardened Diamond Drill Heads","type":"Tech 10","lifeform":"Rock´tal","metal":85000,"crystal":40000,"deut":35000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":7000},"12211":{"name":"Seismic Mining Technology","type":"Tech 11","lifeform":"Rock´tal","metal":120000,"crystal":30000,"deut":25000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":7500},"12212":{"name":"Magma-Powered Pump Systems","type":"Tech 12","lifeform":"Rock´tal","metal":100000,"crystal":40000,"deut":30000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8000},"12213":{"name":"Ion Crystal Modules","type":"Tech 13","lifeform":"Rock´tal","metal":200000,"crystal":100000,"deut":100000,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8500},"12214":{"name":"Optimised Silo Construction Method","type":"Tech 14","lifeform":"Rock´tal","metal":220000,"crystal":110000,"deut":110000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":9000},"12215":{"name":"Diamond Energy Transmitter","type":"Tech 15","lifeform":"Rock´tal","metal":240000,"crystal":120000,"deut":120000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":9500},"12216":{"name":"Obsidian Shield Reinforcement","type":"Tech 16","lifeform":"Rock´tal","metal":250000,"crystal":250000,"deut":250000,"energy":"","priceFactor":1.4,"energyFactor":"","baseBonus1":0.5,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":10000},"12217":{"name":"Rune Shields","type":"Tech 17","lifeform":"Rock´tal","metal":500000,"crystal":300000,"deut":200000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":13000},"12218":{"name":"Rock’tal Collector Enhancement","type":"Tech 18","lifeform":"Rock´tal","metal":300000,"crystal":180000,"deut":120000,"energy":"","priceFactor":1.7,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":11000},"13101":{"name":"Assembly Line","type":"Building","lifeform":"Mecha","metal":6,"crystal":2,"deut":0,"energy":"","priceFactor":1.21,"energyFactor":"","baseBonus1":500,"factorBonus1":1.21,"maxBonus1":"","baseBonus2":24,"factorBonus2":1.2,"maxBonus2":"","baseBonus3":22,"factorBonus3":1.15,"maxBonus3":"","durationFactor":1.22,"duration":40},"13102":{"name":"Fusion Cell Factory","type":"Building","lifeform":"Mecha","metal":5,"crystal":2,"deut":0,"energy":8,"priceFactor":1.18,"energyFactor":1.02,"baseBonus1":18,"factorBonus1":1.15,"maxBonus1":"","baseBonus2":23,"factorBonus2":1.12,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":48},"13103":{"name":"Robotics Research Centre","type":"Building","lifeform":"Mecha","metal":30000,"crystal":20000,"deut":10000,"energy":13,"priceFactor":1.3,"energyFactor":1.08,"baseBonus1":0.25,"factorBonus1":1,"maxBonus1":0.25,"baseBonus2":2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.25,"duration":16000},"13104":{"name":"Update Network","type":"Building","lifeform":"Mecha","metal":5000,"crystal":3800,"deut":1000,"energy":10,"priceFactor":1.8,"energyFactor":1.2,"baseBonus1":40000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.6,"duration":16000},"13105":{"name":"Quantum Computer Centre","type":"Building","lifeform":"Mecha","metal":50000,"crystal":40000,"deut":50000,"energy":40,"priceFactor":1.8,"energyFactor":1.2,"baseBonus1":130000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.7,"duration":64000},"13106":{"name":"Automatised Assembly Centre","type":"Building","lifeform":"Mecha","metal":7500,"crystal":7000,"deut":1000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":2,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"13107":{"name":"High-Performance Transformer","type":"Building","lifeform":"Mecha","metal":35000,"crystal":15000,"deut":10000,"energy":40,"priceFactor":1.5,"energyFactor":1.05,"baseBonus1":1,"factorBonus1":1,"maxBonus1":"","baseBonus2":0.3,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":16000},"13108":{"name":"Microchip Assembly Line","type":"Building","lifeform":"Mecha","metal":50000,"crystal":20000,"deut":30000,"energy":40,"priceFactor":1.07,"energyFactor":1.01,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":2,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.17,"duration":12000},"13109":{"name":"Production Assembly Hall","type":"Building","lifeform":"Mecha","metal":100000,"crystal":10000,"deut":3000,"energy":80,"priceFactor":1.14,"energyFactor":1.04,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":6,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":40000},"13110":{"name":"High-Performance Synthesiser","type":"Building","lifeform":"Mecha","metal":100000,"crystal":40000,"deut":20000,"energy":60,"priceFactor":1.5,"energyFactor":1.1,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":52000},"13111":{"name":"Chip Mass Production","type":"Building","lifeform":"Mecha","metal":55000,"crystal":50000,"deut":30000,"energy":70,"priceFactor":1.5,"energyFactor":1.05,"baseBonus1":0.3,"factorBonus1":1,"maxBonus1":1,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":50000},"13112":{"name":"Nano Repair Bots","type":"Building","lifeform":"Mecha","metal":250000,"crystal":125000,"deut":125000,"energy":100,"priceFactor":1.4,"energyFactor":1.05,"baseBonus1":1.3,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":95000},"13201":{"name":"Catalyser Technology","type":"Tech 1","lifeform":"Mecha","metal":10000,"crystal":6000,"deut":1000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":1000},"13202":{"name":"Plasma Drive","type":"Tech 2","lifeform":"Mecha","metal":7500,"crystal":12500,"deut":5000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"13203":{"name":"Efficiency Module","type":"Tech 3","lifeform":"Mecha","metal":15000,"crystal":10000,"deut":5000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.03,"factorBonus1":1,"maxBonus1":0.3,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":2500},"13204":{"name":"Depot AI","type":"Tech 4","lifeform":"Mecha","metal":20000,"crystal":15000,"deut":7500,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":3500},"13205":{"name":"General Overhaul (Light Fighter)","type":"Tech 5","lifeform":"Mecha","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":4500},"13206":{"name":"Automated Transport Lines","type":"Tech 6","lifeform":"Mecha","metal":50000,"crystal":50000,"deut":20000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.06,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":5000},"13207":{"name":"Improved Drone AI","type":"Tech 7","lifeform":"Mecha","metal":70000,"crystal":40000,"deut":20000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":5500},"13208":{"name":"Experimental Recycling Technology","type":"Tech 8","lifeform":"Mecha","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":1,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":6000},"13209":{"name":"General Overhaul (Cruiser)","type":"Tech 9","lifeform":"Mecha","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":6500},"13210":{"name":"Slingshot Autopilot","type":"Tech 10","lifeform":"Mecha","metal":85000,"crystal":40000,"deut":35000,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":0.15,"factorBonus1":1,"maxBonus1":0.9,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":7000},"13211":{"name":"High-Temperature Superconductors","type":"Tech 11","lifeform":"Mecha","metal":120000,"crystal":30000,"deut":25000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":7500},"13212":{"name":"General Overhaul (Battleship)","type":"Tech 12","lifeform":"Mecha","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":8000},"13213":{"name":"Artificial Swarm Intelligence","type":"Tech 13","lifeform":"Mecha","metal":200000,"crystal":100000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.06,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8500},"13214":{"name":"General Overhaul (Battlecruiser)","type":"Tech 14","lifeform":"Mecha","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":9000},"13215":{"name":"General Overhaul (Bomber)","type":"Tech 15","lifeform":"Mecha","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":9500},"13216":{"name":"General Overhaul (Destroyer)","type":"Tech 16","lifeform":"Mecha","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":10000},"13217":{"name":"Experimental Weapons Technology","type":"Tech 17","lifeform":"Mecha","metal":500000,"crystal":300000,"deut":200000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":13000},"13218":{"name":"Mechan General Enhancement","type":"Tech 18","lifeform":"Mecha","metal":300000,"crystal":180000,"deut":120000,"energy":"","priceFactor":1.7,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":11000},"14101":{"name":"Sanctuary","type":"Building","lifeform":"Kaelesh","metal":4,"crystal":3,"deut":0,"energy":"","priceFactor":1.21,"energyFactor":"","baseBonus1":250,"factorBonus1":1.21,"maxBonus1":"","baseBonus2":16,"factorBonus2":1.2,"maxBonus2":"","baseBonus3":11,"factorBonus3":1.15,"maxBonus3":"","durationFactor":1.22,"duration":40},"14102":{"name":"Antimatter Condenser","type":"Building","lifeform":"Kaelesh","metal":6,"crystal":3,"deut":0,"energy":9,"priceFactor":1.21,"energyFactor":1.02,"baseBonus1":12,"factorBonus1":1.15,"maxBonus1":"","baseBonus2":12,"factorBonus2":1.14,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.22,"duration":40},"14103":{"name":"Vortex Chamber","type":"Building","lifeform":"Kaelesh","metal":20000,"crystal":20000,"deut":30000,"energy":10,"priceFactor":1.3,"energyFactor":1.08,"baseBonus1":0.25,"factorBonus1":1,"maxBonus1":0.25,"baseBonus2":2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.25,"duration":16000},"14104":{"name":"Halls of Realisation","type":"Building","lifeform":"Kaelesh","metal":7500,"crystal":5000,"deut":800,"energy":15,"priceFactor":1.8,"energyFactor":1.3,"baseBonus1":30000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.7,"duration":16000},"14105":{"name":"Forum of Transcendence","type":"Building","lifeform":"Kaelesh","metal":60000,"crystal":30000,"deut":50000,"energy":30,"priceFactor":1.8,"energyFactor":1.3,"baseBonus1":100000000,"factorBonus1":1.1,"maxBonus1":"","baseBonus2":1,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.8,"duration":64000},"14106":{"name":"Antimatter Convector","type":"Building","lifeform":"Kaelesh","metal":8500,"crystal":5000,"deut":3000,"energy":"","priceFactor":1.25,"energyFactor":"","baseBonus1":1,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.35,"duration":2000},"14107":{"name":"Cloning Laboratory","type":"Building","lifeform":"Kaelesh","metal":15000,"crystal":15000,"deut":20000,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":12000},"14108":{"name":"Chrysalis Accelerator","type":"Building","lifeform":"Kaelesh","metal":75000,"crystal":25000,"deut":30000,"energy":30,"priceFactor":1.05,"energyFactor":1.03,"baseBonus1":2,"factorBonus1":1,"maxBonus1":"","baseBonus2":6,"factorBonus2":1,"maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.18,"duration":16000},"14109":{"name":"Bio Modifier","type":"Building","lifeform":"Kaelesh","metal":87500,"crystal":25000,"deut":30000,"energy":40,"priceFactor":1.2,"energyFactor":1.02,"baseBonus1":200,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":40000},"14110":{"name":"Psionic Modulator","type":"Building","lifeform":"Kaelesh","metal":150000,"crystal":30000,"deut":30000,"energy":140,"priceFactor":1.5,"energyFactor":1.05,"baseBonus1":1,"factorBonus1":1,"maxBonus1":0.25,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.8,"duration":52000},"14111":{"name":"Ship Manufacturing Hall","type":"Building","lifeform":"Kaelesh","metal":75000,"crystal":50000,"deut":55000,"energy":90,"priceFactor":1.2,"energyFactor":1.04,"baseBonus1":1.5,"factorBonus1":1,"maxBonus1":0.7,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":90000},"14112":{"name":"Supra Refractor","type":"Building","lifeform":"Kaelesh","metal":500000,"crystal":250000,"deut":250000,"energy":100,"priceFactor":1.4,"energyFactor":1.05,"baseBonus1":0.5,"factorBonus1":1,"maxBonus1":0.3,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":95000},"14201":{"name":"Heat Recovery","type":"Tech 1","lifeform":"Kaelesh","metal":10000,"crystal":6000,"deut":1000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.03,"factorBonus1":1,"maxBonus1":0.3,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":1000},"14202":{"name":"Sulphide Process","type":"Tech 2","lifeform":"Kaelesh","metal":7500,"crystal":12500,"deut":5000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.08,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":2000},"14203":{"name":"Psionic Network","type":"Tech 3","lifeform":"Kaelesh","metal":15000,"crystal":10000,"deut":5000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.05,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":2500},"14204":{"name":"Telekinetic Tractor Beam","type":"Tech 4","lifeform":"Kaelesh","metal":20000,"crystal":15000,"deut":7500,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":3500},"14205":{"name":"Enhanced Sensor Technology","type":"Tech 5","lifeform":"Kaelesh","metal":25000,"crystal":20000,"deut":10000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":4500},"14206":{"name":"Neuromodal Compressor","type":"Tech 6","lifeform":"Kaelesh","metal":50000,"crystal":50000,"deut":20000,"energy":"","priceFactor":1.3,"energyFactor":"","baseBonus1":0.4,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":5000},"14207":{"name":"Neuro-Interface","type":"Tech 7","lifeform":"Kaelesh","metal":70000,"crystal":40000,"deut":20000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":5500},"14208":{"name":"Interplanetary Analysis Network","type":"Tech 8","lifeform":"Kaelesh","metal":80000,"crystal":50000,"deut":20000,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":0.6,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":6000},"14209":{"name":"Overclocking (Heavy Fighter)","type":"Tech 9","lifeform":"Kaelesh","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":6500},"14210":{"name":"Telekinetic Drive","type":"Tech 10","lifeform":"Kaelesh","metal":85000,"crystal":40000,"deut":35000,"energy":"","priceFactor":1.2,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.2,"duration":7000},"14211":{"name":"Sixth Sense","type":"Tech 11","lifeform":"Kaelesh","metal":120000,"crystal":30000,"deut":25000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":7500},"14212":{"name":"Psychoharmoniser","type":"Tech 12","lifeform":"Kaelesh","metal":100000,"crystal":40000,"deut":30000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.06,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8000},"14213":{"name":"Efficient Swarm Intelligence","type":"Tech 13","lifeform":"Kaelesh","metal":200000,"crystal":100000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":0.99,"baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":8500},"14214":{"name":"Overclocking (Large Cargo)","type":"Tech 14","lifeform":"Kaelesh","metal":160000,"crystal":120000,"deut":50000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":1,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":9000},"14215":{"name":"Gravitation Sensors","type":"Tech 15","lifeform":"Kaelesh","metal":240000,"crystal":120000,"deut":120000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.1,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":9500},"14216":{"name":"Overclocking (Battleship)","type":"Tech 16","lifeform":"Kaelesh","metal":320000,"crystal":240000,"deut":100000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.3,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":10000},"14217":{"name":"Psionic Shield Matrix","type":"Tech 17","lifeform":"Kaelesh","metal":500000,"crystal":300000,"deut":200000,"energy":"","priceFactor":1.5,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":0.5,"baseBonus2":0.2,"factorBonus2":1,"maxBonus2":0.99,"baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.3,"duration":13000},"14218":{"name":"Kaelesh Discoverer Enhancement","type":"Tech 18","lifeform":"Kaelesh","metal":300000,"crystal":180000,"deut":120000,"energy":"","priceFactor":1.7,"energyFactor":"","baseBonus1":0.2,"factorBonus1":1,"maxBonus1":"","baseBonus2":"","factorBonus2":"","maxBonus2":"","baseBonus3":"","factorBonus3":"","maxBonus3":"","durationFactor":1.4,"duration":11000} } return tech[parseInt(id)]; } } class Util { static importToPTRE(apiKey, ogl) { Util.getJSON(`https://ptre.chez.gg/scripts/oglight_import.php?tool=oglight&team_key=${ogl.ptre}&sr_id=${apiKey}`, result => { fadeBox(result.message_verbose, result.code != 1); }); } static genTrashsimLink(apiKey, ogl) { let coords = ogl.current.coords; let jsonTechs = {"0": [{ planet: { galaxy:coords[0], system:coords[1], position:coords[2], }, class: ogl.account.class, characterClassesEnabled: true, "research": {} }]}; for(let [key, value] of Object.entries(ogl.db.me.techs)) { jsonTechs[0][0].research[key] = {"level":value}; } jsonTechs = btoa(JSON.stringify(jsonTechs)); let lang = ogl.universe.lang == 'us' ? 'en' : ogl.universe.lang == 'ar' ? 'es' : ogl.universe.lang; return 'https://trashsim.universeview.be/' + lang + '?SR_KEY=' + apiKey + '#prefill=' + jsonTechs; } static getXML(url, callback) { let cancelController = new AbortController(); let signal = cancelController.signal; fetch(url, {signal:signal}) .then(response => response.text()) .then(data => { let xml = new DOMParser().parseFromString(data, 'text/html'); callback(xml); }) .catch(error => console.log(`Failed to fetch ${url} : ${error}`)); //window.addEventListener('beforeunload', () => cancelController.abort()); } static getJSON(url, callback) { let cancelController = new AbortController(); let signal = cancelController.signal; fetch(url, {signal:signal}) .then(response => response.json()) .then(data => callback(data)) .catch(error => console.log(`Failed to fetch ${url} : ${error}`)); //window.addEventListener('beforeunload', () => cancelController.abort()); } static getRaw(url, callback) { let cancelController = new AbortController(); let signal = cancelController.signal; fetch(url, {method:'get', signal:signal, headers:{'Accept':'application/json'}}) .then(response => response.text()) .then(data => callback(data)) .catch(error => console.log(`Failed to fetch ${url} : ${error}`)); //window.addEventListener('beforeunload', () => cancelController.abort()); } static createDom(element, params, content) { params = params || {}; content = content ?? ''; let dom = document.createElement(element); Object.entries(params).forEach(p => dom.setAttribute(p[0], p[1])); dom.innerHTML = content; return dom; } static updateCheckIntInput(callback) { let old = checkIntInput; checkIntInput = function(id, minVal, maxVal) { old.call(window, id, minVal, maxVal); callback(); } } static formatToUnits(value, forced, offset) { if(!value) return 0; value = value.toString().replace(/[\,\. ]/g, ''); if(isNaN(value)) return value; let precision = 0; value = parseInt(value); if(value == 0 || forced == 0 || value < 1000) precision = 0; else if(value < 1000000 || forced == 1) precision = 1; else precision = 2; // const abbrev = ['', LocalizationStrings.unitKilo, LocalizationStrings.unitMega, LocalizationStrings.unitMilliard]; const abbrev = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; const unrangifiedOrder = Math.floor(Math.log10(Math.abs(value)) / 3); const order = Math.max(0, Math.min(unrangifiedOrder, abbrev.length-1)); const suffix = abbrev[order]; let result = (value / Math.pow(10, order * 3)).toFixed(precision); /*if(offset) { result = `<span style="font-size:${Math.max(10 + Math.floor((order-1) * 1.5), 10)}px;">${result} ${suffix}</span>`; } else { result = suffix ? result + ' ' + suffix : result; }*/ return suffix ? result + ' ' + suffix : result; } static formatFromUnits(value) { if(!value) return 0; let offset = (value.split(LocalizationStrings.thousandSeperator).length - 1) * 3; if(LocalizationStrings.thousandSeperator == LocalizationStrings.decimalPoint) offset = 0; let splitted = value.match(/\d+/g)[0].length; //let splitted = value.split(/[\,\.]/g)[0].length; //if(value.match(/\d+/g) && value.match(/\d+/g).map(Number).length == 1) splitted -= 1; if(value.indexOf(LocalizationStrings.unitMilliard) > -1) { //let padEnd = value.indexOf(LocalizationStrings.thousandSeperator) > -1 ? 12 : 9; value = value.replace(LocalizationStrings.unitMilliard, ''); value = value.replace(/[\,\. ]/g, ''); value = value.padEnd(9 + offset + splitted, '0'); } else if(value.indexOf(LocalizationStrings.unitMega) > -1) { value = value.replace(LocalizationStrings.unitMega, ''); value = value.replace(/[\,\. ]/g, ''); value = value.padEnd(6 + offset + splitted, '0'); } else if(value.indexOf(LocalizationStrings.unitKilo) > -1) { value = value.replace(LocalizationStrings.unitKilo, ''); value = value.replace(/[\,\. ]/g, ''); value = value.padEnd(3 + offset + splitted, '0'); } else { value = value.replace(/[\,\. ]/g, ''); } return parseInt(value); } static formatNumber(number) { return (number || '0').toLocaleString('de-DE'); } static findObjectByValue(object, value) { return Object.keys(object).find(key => object[key] === value); } static logPtre(data, params) { params = params || { galaxy:0, system:0, id:0 }; let source = params.galaxy && params.system ? `${params.galaxy}:${params.system}` : `#${params.playerID}`; let div = document.querySelector('.ogl_ptreLogs') || (document.querySelector('#middle') || document.querySelector('#highscoreContent')).appendChild(Util.createDom('div', {'class':'ogl_ptreLogs'}, '<h3>PTRE Logs :</h3>')); div.appendChild(Util.createDom('div', {}, `<span>${new Date(Date.now()).toLocaleTimeString('fr-FR')}</span> ➜ ${data.message} <b>[${source}]</b>`)); if(div.querySelectorAll('div').length > 5) div.querySelectorAll('div')[0].remove(); } static takeScreenshot(element, button, name) { if(typeof html2canvas === 'undefined') { Util.getRaw('https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.5/dist/html2canvas.min.js', result => { document.head.appendChild(Util.createDom('script', {'type':'text/javascript'}, result)); Util.takeScreenshot(element, button, name); }) } else { html2canvas(element, {backgroundColor:'#151f28'}).then(canvas => { const dataURL = canvas.toDataURL(); const link = Util.createDom('a', {'download':name, 'href':dataURL}); link.click(); button.innerHTML = '<i class="material-icons">file_download</i>Download (.jpg)'; button.classList.remove('ogl_disabled'); }); } } static redirect(url, ogl) { if(ogl) ogl.component.popup.load(true); setTimeout(() => window.location.href = url, 200); } } class MessageManager { constructor(ogl) { this.ogl = ogl; this.spyTable; this.dataList = []; this.tableReady = false; this.reportList = []; this.trashQueue = []; if(this.ogl.page == 'messages') { // check reports tab this.ogl.observeMutation(() => this.checkCurrentTab(), 'tablereport'); // check opened message this.ogl.observeMutation(() => { let detail = document.querySelector('.detail_msg'); if(detail && detail.getAttribute('data-message-type') == 10 && !detail.classList.contains('ogl_detailReady')) { detail.classList.add('ogl_detailReady'); let apiKey = Util.createDom('div', {}); //apiKey.innerHTML = detail.querySelector('.icon_apikey').getAttribute('data-tooltip') || detail.querySelector('.icon_apikey').getAttribute('title'); apiKey.innerHTML = detail.querySelector('.icon_apikey').getAttribute('title'); apiKey = apiKey.querySelector('input').value; let simButton = detail.querySelector('.msg_actions').appendChild(Util.createDom('div', {'class':'icon_nf ogl_sim'}, 'S')); simButton.addEventListener('click', () => window.open(Util.genTrashsimLink(apiKey, this.ogl), '_blank')); if(this.ogl.ptre) { let ptreButton = detail.querySelector('.msg_actions').appendChild(Util.createDom('div', {'class':'icon_nf ogl_sim tooltip', 'title':'import to PTRE'}, 'P')); ptreButton.addEventListener('click', () => Util.importToPTRE(apiKey, this.ogl)); } } }, 'simbutton'); this.ogl.performances.push(['Message',performance.now()]); } } checkCurrentTab() { this.trashQueueProcessing = false; this.trashQueue = []; if(document.querySelectorAll('.msg').length < 1) return; let tokenInterval = setInterval(() => { this.tokenInput = document.querySelectorAll('[name="token"]')[0]; if(!this.tokenInput) return; clearInterval(tokenInterval); let self = this; const { get, set } = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); try { Object.defineProperty(this.tokenInput, "value", { get() { return get.call(this); }, set(newVal) { setTimeout(() => { if(self.trashQueue.length > 0 && !self.trashQueueProcessing) { self.trashQueueProcessing = true; let id = self.trashQueue[0]; let buttonSelector = document.querySelector(`[data-msg-id="${id}"] .js_actionKill`); if(buttonSelector && !buttonSelector.classList.contains('ogl_noPointer')) { buttonSelector.click(); let line = self.spyTable?.querySelector(`[data-spy-id="${id}"]`); if(line) { if(line.nextSibling?.tagName == 'ASIDE') line.nextSibling.remove(); self.sum = self.sum || 0; self.sum -= parseInt(line.getAttribute('data-renta')); self.sumDetail = self.sumDetail || [0, 0, 0]; self.sumDetail[0] -= parseInt(line.getAttribute('data-metal')); self.sumDetail[1] -= parseInt(line.getAttribute('data-crystal')); self.sumDetail[2] -= parseInt(line.getAttribute('data-deut')); self.calcTotal(self.sum, self.sumDetail, self.sumDetail[0] + self.sumDetail[1] + self.sumDetail[2]); line.remove(); const isValid = e => e.id == id; for(let i=0, len=self.dataList.length; i<len; i++) { let item = self.dataList[i]; if(isValid(item)) { self.dataList.splice(i, 1); break; } } } } else this.value = newVal; self.tokenReady = true; self.trashQueue.shift(); } else self.trashQueueProcessing = false; }, 50); return set.call(this, newVal); } }); if(this.trashQueue.length > 0) this.tokenInput.value = this.tokenInput.value; } catch(e) {}; }, 100); let tabID = ogame.messages.getCurrentMessageTab(); if(tabID == 21) this.checkRaid(); else if(tabID == 22) this.checkExpeditions(); else if(tabID == 23) this.checkTransports(); else if(tabID == 24) this.checkDebris(); else if(tabID == 25) this.checkTrash(); else if(tabID == 20) this.checkReports(); if(this.spyTable) { if(tabID == 20) { this.spyTable.classList.remove('ogl_hidden'); document.querySelector('#subtabs-nfFleetTrash .ogl_trash') && document.querySelector('#subtabs-nfFleetTrash .ogl_trash').classList.remove('ogl_hidden'); } else { this.spyTable.classList.add('ogl_hidden'); document.querySelector('#subtabs-nfFleetTrash .ogl_trash') && document.querySelector('#subtabs-nfFleetTrash .ogl_trash').classList.add('ogl_hidden'); } } } checkTrash() { this.reviveReady = true; // ogame bug fix document.querySelectorAll('.msg .js_actionRevive').forEach(button => { button.classList.remove('js_actionRevive'); button.addEventListener('click', () => { if(!this.reviveReady) { setTimeout(() => button.click(), 150); return; } let msg = button.closest('.msg'); let id = msg.getAttribute('data-msg-id'); let tokenMsg = document.querySelectorAll('[name="token"]')[0].getAttribute('value'); this.reviveReady = false; $.ajax( { type:'POST', url:'?page=messages', dataType:'json', data: { ajax:1, token:tokenMsg, messageId:id, action:104 } }).done(result => { if(result[id] == true && result.newAjaxToken) { msg.remove(); document.querySelectorAll('[name="token"]').forEach(e => e.setAttribute('value', result.newAjaxToken)); ogame.messages.token = result.newAjaxToken; this.reviveReady = true; } }).fail(result => { console.log('bug, please refresh'); this.reviveReady = true; }); }); }); } checkRaid() { let messages = document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_raidDone)'); if(messages.length > 0 && messages.length != document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_raidDone) .msg_date.ogl_timeZone').length) { setTimeout(() => this.checkRaid(), 100); return; } let urls = []; this.ogl.cache.msg = this.ogl.cache.msg || {}; messages.forEach((message, index) => { let content = message.querySelector('.msg_content'); if(!message.querySelector('.ogl_timeZone')) return; message.classList.add('ogl_raidDone'); if(!content.querySelector('.msg_ctn2')) return; if(document.querySelector('#subtabs-nfFleetTrash.ui-state-active')) return; let id = message.getAttribute('data-msg-id'); if(this.ogl.cache.msg[id]) this.loadRaidMessages(id); else { console.log('fetch') let groupID = Math.floor(index / 15) * 10; urls[groupID] = urls[groupID] || []; urls[groupID].push(`https://${window.location.host}/game/index.php?page=messages&messageId=${id}&tabid=21&ajax=1`); } }); urls.forEach((group, index) => { setTimeout(() => { Promise.all(group.map(url => fetch(url).then(response => { if(response.status == 503) { throw Error(response.status) } else return response.text() }).catch(err => { const mute = err }))) .then(texts => { texts.forEach(data => { let result = new DOMParser().parseFromString(data, 'text/html'); if(!result.querySelector('.detail_msg')) { console.error("Can't fetch combat report : server data error | " + data); return; } let id = result.querySelector('.detail_msg').getAttribute('data-msg-id'); let message = document.querySelector(`.msg[data-msg-id="${id}"]`); if(!message.querySelector('.msg_date')) { console.error("Can't fetch combat report : message date error | " + data); return; } let htmlReport = result.getElementsByClassName('detail_msg')[0].innerHTML; let json = JSON.parse(htmlReport.substring((htmlReport.search("var combatData") + 35),(htmlReport.search("var attackerJson") - 12))); this.ogl.cache.msg[id] = json; this.loadRaidMessages(id); }); // this.ogl.saveAsync(); this.ogl.component.empire.addStats(); }) .catch(error => console.log(`Failed to fetch combat report : ${error}`)); }, index * 150); }); } loadRaidMessages(id) { let report = {}; let json = this.ogl.cache.msg[id]; let message = document.querySelector(`.msg[data-msg-id="${id}"]`); let date = new Date(parseInt(message.querySelector('.msg_date').getAttribute('data-servertime'))); let midnight = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0).getTime(); let loot = { metal:json.loot.metal, crystal:json.loot.crystal, deut:json.loot.deuterium, food:json.loot.food }; let renta = { metal:0, crystal:0, deut:0, food:0 }; let loss = { metal:0, crystal:0, deut:0, food:0 }; /*let loot = [json.loot.metal, json.loot.crystal, json.loot.deuterium]; let renta = [0,0,0]; let loss = [0,0,0];*/ let fleetID = []; let leftSide = false; let probesOnly = false; Object.values(json.attackerJSON.member).forEach(v => { if(v && v.ownerID == this.ogl.account.id) fleetID.push(v.fleetID) }); if(fleetID.length > 0) leftSide = true; Object.values(json.defenderJSON.member).forEach(v => { if(v && v.ownerID == this.ogl.account.id) fleetID.push(v.fleetID) }); let atkRounds = json.attackerJSON.combatRounds; let defRounds = json.defenderJSON.combatRounds; fleetID.forEach(fleet => { if(Object.values(atkRounds[0].ships).length == 1 && Object.values(atkRounds[0].ships)[0]?.[210]) probesOnly = true; // def if(defRounds[defRounds.length-1].losses && defRounds[defRounds.length-1].losses[fleet]) { for(let [k,v] of Object.entries(defRounds[defRounds.length-1].losses[fleet])) { let shipData = Datafinder.getTech(k); Object.keys(shipData).forEach(x => loss[x] = (loss[x] || 0) + shipData[x] * v); } } // atk if(atkRounds[atkRounds.length-1].losses && atkRounds[atkRounds.length-1].losses[fleet]) { for(let [k,v] of Object.entries(atkRounds[atkRounds.length-1].losses[fleet])) { let shipData = Datafinder.getTech(k); Object.keys(shipData).forEach(x => loss[x] = (loss[x] || 0) + shipData[x] * v); } } }); // repaired if(json.defender[0] && json.defender[0].ownerID == this.ogl.account.id) { for(let [k,v] of Object.entries(json.repairedDefense)) { let shipData = Datafinder.getTech(k); Object.keys(shipData).forEach(x => loss[x] = (loss[x] || 0) - shipData[x] * v); } } if(leftSide) Object.keys(loss).forEach(x => renta[x] = (renta[x] || 0) - loss[x] + loot[x]); else Object.keys(loss).forEach(x => renta[x] = (renta[x] || 0) - loss[x] - loot[x]); let line = Util.createDom('div', {'class':'ogl_expeResult'}); Object.keys(renta).forEach(r => { report[r] = renta[r]; line.appendChild(Util.createDom('div', {'class':`ogl_${r}`}, Util.formatToUnits(renta[r] || '0'))); }); message.prepend(line); let target = json.coordinates.position == 16 ? 'expe' : 'raid'; this.ogl.db.stats[midnight] = this.ogl.db.stats[midnight] || { idList:[], expe:{}, raid:{}, expeOccurences:{}, raidOccurences:0, consumption:0 }; this.ogl.db.stats.ignored = this.ogl.db.stats.ignored || {}; this.ogl.db.stats.total = this.ogl.db.stats.total || {}; this.ogl.db.stats.total.expeOccurences = this.ogl.db.stats.total.expeOccurences || {}; this.ogl.db.stats.total.raidOccurences = this.ogl.db.stats.total.raidOccurences || 0; let newEntry = !this.ogl.db.stats[midnight].idList.includes(id) && !this.ogl.db.stats.ignored[id]; //let totalRenta = renta.reduce((sum, x) => sum + x); let saveReport = () => { this.ogl.db.stats.total[target] = this.ogl.db.stats.total[target] || {}; if(!this.ogl.db.stats[midnight].idList.includes(id) && !this.ogl.db.stats.ignored[id]) { this.ogl.db.stats[midnight].idList.push(id); for(let [k,v] of Object.entries(report)) { this.ogl.db.stats[midnight][target][k] = (this.ogl.db.stats[midnight][target][k] || 0) + v; this.ogl.db.stats.total[target][k] = (this.ogl.db.stats.total[target][k] || 0) + v; } if(target == 'expe') { this.ogl.db.stats[midnight].expeOccurences['fight'] = (this.ogl.db.stats[midnight].expeOccurences['fight'] || 0) + 1; this.ogl.db.stats.total.expeOccurences['fight'] = (this.ogl.db.stats.total.expeOccurences['fight'] || 0) + 1; this.ogl.db.stats[midnight].expeOccurences['none'] = (this.ogl.db.stats[midnight].expeOccurences['none'] || 0) - 1; this.ogl.db.stats.total.expeOccurences['none'] = (this.ogl.db.stats.total.expeOccurences['none'] || 0) - 1; } else { this.ogl.db.stats[midnight].raidOccurences = (this.ogl.db.stats[midnight].raidOccurences || 0) + 1; this.ogl.db.stats.total.raidOccurences = (this.ogl.db.stats.total.raidOccurences || 0) + 1; } } } let deleteReport = () => { if(target == 'raid') { this.ogl.db.stats.total[target] = this.ogl.db.stats.total[target] || {}; this.ogl.db.stats[midnight].raidOccurences = (this.ogl.db.stats[midnight].raidOccurences || 0) - 1; this.ogl.db.stats.total.raidOccurences = (this.ogl.db.stats.total.raidOccurences || 0) - 1; } } saveReport(); // ignore button if(target == 'raid') { let ignore = line.appendChild(Util.createDom('div', {'class':'ogl_button ogl_ignoreRaid material-icons tooltip', 'title':this.ogl.component.lang.getText('ignoreRaid')})); if(this.ogl.db.stats.ignored[id]) ignore.classList.add('ogl_active'); ignore.addEventListener('click', () => { if(this.ogl.db.stats.ignored[id]) { delete this.ogl.db.stats.ignored[id]; ignore.classList.remove('ogl_active'); } else { ignore.classList.add('ogl_active'); let index = this.ogl.db.stats[midnight].idList.indexOf(id); this.ogl.db.stats.ignored[id] = serverTime.getTime(); this.ogl.db.stats[midnight].idList.splice(index, 1); deleteReport(); for(let [k,v] of Object.entries(report)) { this.ogl.db.stats[midnight][target][k] = (this.ogl.db.stats[midnight][target][k] || 0) - v; this.ogl.db.stats.total[target][k] = (this.ogl.db.stats.total[target][k] || 0) - v; } } saveReport(); // this.ogl.saveAsync(); this.ogl.component.empire.addStats(); }); // ignore spies fights if(newEntry && probesOnly && !this.ogl.db.ships[210]?.capacity) ignore.click(); } } checkExpeditions() { let messages = document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_expeditionDone)'); if(messages.length > 0 && messages.length != document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_expeditionDone) .msg_date.ogl_timeZone').length) { setTimeout(() => this.checkExpeditions(), 100); return; } this.messagePending = []; messages.forEach((message, messageIndex) => { if(!message.querySelector('.ogl_timeZone')) return; message.classList.add('ogl_expeditionDone'); if(document.querySelector('#subtabs-nfFleetTrash.ui-state-active')) return; if(message.querySelector('.msg_title a').textContent.indexOf(':16]') == -1) return; setTimeout(() => { let id = message.getAttribute('data-msg-id'); let date = new Date(parseInt(message.querySelector('.msg_date').getAttribute('data-servertime'))); let midnight = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0).getTime(); let type = 'none'; let typeList = ['metal','crystal','deut','dm',202,203,204,205,206,207,208,209,210,211,213,214,215,217,218,219]; this.messagePending.push(id); let result = {}; typeList.forEach(typeID => { if(message.textContent.indexOf(this.ogl.component.lang.getText(typeID)) > -1) { if(!isNaN(typeID)) type = 'ships'; else if(typeID == 'metal' || typeID == 'crystal' || typeID == 'deut') type = 'resources'; else if(typeID == 'dm') type = 'dm'; result[typeID] = this.getExpeValue(this.ogl.component.lang.getText(typeID), message); } if(result[typeID] == -1) { type = 'none'; delete result[typeID]; } }); if(message.querySelector('a.itemLink')) { type = 'item'; result.item = 1; } message.querySelector('.msg_content').prepend(Util.createDom('div', {'class':'ogl_expeResult'}, type.replace('none', '-'))); this.ogl.db.stats[midnight] = this.ogl.db.stats[midnight] || { idList:[], expe:{}, raid:{}, expeOccurences:{}, raidOccurences:0, consumption:0 }; if(this.ogl.db.stats[midnight].idList.indexOf(id) == -1) { this.ogl.db.stats[midnight].idList.push(id); this.ogl.db.stats.total.expe = this.ogl.db.stats.total.expe || {}; this.ogl.db.stats.total.expeOccurences = this.ogl.db.stats.total.expeOccurences || {}; for(let [k,v] of Object.entries(result)) { this.ogl.db.stats[midnight].expe[k] = (this.ogl.db.stats[midnight].expe[k] || 0) + v; this.ogl.db.stats.total.expe[k] = (this.ogl.db.stats.total?.expe?.[k] || 0) + v; } this.ogl.db.stats[midnight].expeOccurences[type] = (this.ogl.db.stats[midnight].expeOccurences[type] || 0) + 1; this.ogl.db.stats.total.expeOccurences[type] = (this.ogl.db.stats.total.expeOccurences[type] || 0) + 1; } if(this.messagePending.length == messages.length) { // this.ogl.saveAsync(); this.ogl.component.empire.addStats(); } }, messageIndex * 5); }); } checkDebris() { let messages = document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_debrisDone)'); if(messages.length > 0 && messages.length != document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_debrisDone) .msg_date.ogl_timeZone').length) { setTimeout(() => this.checkDebris(), 100); return; } messages.forEach(message => { if(!message.querySelector('.ogl_timeZone')) return; message.classList.add('ogl_debrisDone'); if(!message.querySelector('.icon_apikey') && message.querySelector('.msg_head').textContent.indexOf(':17]') < 0) return; let content = message.querySelector('.msg_content'); let regex = new RegExp('\\'+LocalizationStrings.thousandSeperator, 'g'); let id = message.getAttribute('data-msg-id'); let date = new Date(parseInt(message.querySelector('.msg_date').getAttribute('data-servertime'))); let midnight = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0).getTime(); let report = {}; let numList = content.textContent.replace(regex, '').match(/\d+/g); let target = parseInt(numList[numList.length - 3]) == 16 ? 'expe' : 'raid'; if(!message.querySelector('.icon_apikey')) { report.dm = parseInt(numList[numList.length - 2]); message.prepend(Util.createDom('div', {'class':'ogl_expeResult'}, `Renta: ${report.DM} ${this.ogl.component.lang.getText('DM')}`)); } else { report.metal = parseInt(numList[numList.length - 3]); report.crystal = parseInt(numList[numList.length - 2]); report.deut = parseInt(numList[numList.length - 1]); message.prepend(Util.createDom('div', {'class':'ogl_expeResult'}, `Renta: ${Util.formatToUnits(report.metal)} | ${Util.formatToUnits(report.crystal)} | ${Util.formatToUnits(report.deut)}`)); } this.ogl.db.stats[midnight] = this.ogl.db.stats[midnight] || { idList:[], expe:{}, raid:{}, expeOccurences:{}, raidOccurences:0, consumption:0 }; this.ogl.db.stats.total = this.ogl.db.stats.total || {}; this.ogl.db.stats.total[target] = this.ogl.db.stats.total[target] || {}; if(this.ogl.db.stats[midnight].idList.indexOf(id) == -1) { this.ogl.db.stats[midnight].idList.push(id); this.ogl.db.stats.total.expe = this.ogl.db.stats.total.expe || {}; this.ogl.db.stats.total.expeOccurences = this.ogl.db.stats.total.expeOccurences || {}; for(let [k,v] of Object.entries(report)) { this.ogl.db.stats[midnight][target][k] = (this.ogl.db.stats[midnight][target][k] || 0) + v; this.ogl.db.stats.total[target][k] = (this.ogl.db.stats.total[target][k] || 0) + v; } } }); // this.ogl.saveAsync(); this.ogl.component.empire.addStats(); } checkReports() { if(document.querySelector('#subtabs-nfFleetTrash.ui-state-active')) return; if(this.ogl.db.options.togglesOff.indexOf('spytable') > -1) return; this.dataList = []; this.reportList = []; if(this.spyTable) this.spyTable.remove(); if(!document.querySelector('#subtabs-nfFleetTrash .ogl_trash')) { let deleteSpyDef = document.querySelector('#subtabs-nfFleetTrash').appendChild(Util.createDom('div', {'class':'material-icons ogl_button ogl_trash tooltip', 'title':this.ogl.component.lang.getText('deleteSpyDef')}, 'visibility_off')); deleteSpyDef.addEventListener('click', () => { document.querySelectorAll('.msg').forEach(e => { let id = e.getAttribute('data-msg-id'); if(e.querySelector('.espionageDefText') && this.trashQueue.indexOf(id) == -1) this.trashQueue.push(id); if(this.trashQueue.length == 1) this.tokenInput.value = this.tokenInput.value; }); }); } let messages = document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_ready)'); if(messages.length > 0 && messages.length != document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_ready) .msg_date.ogl_timeZone').length) { setTimeout(() => this.checkReports(), 100); return; } let positionsList = this.ogl.getPositionsByCoords(); if(this.ogl.ptre) { let ptreJSON = {}; messages.forEach(report => { if(report.querySelector('.espionageDefText')) { let id = report.getAttribute('data-msg-id'); let tmpHTML = Util.createDom('div', {}, report.querySelector('span.player').getAttribute('title') || report.querySelector('span.player').getAttribute('data-title')); let playerID = tmpHTML.querySelector('[data-playerId]').getAttribute('data-playerId'); let a = report.querySelector('.espionageDefText a'); let params = new URLSearchParams(a.getAttribute('href')); let coords = [params.get('galaxy') || "0", params.get('system') || "0", params.get('position') || "0"]; let type = a.querySelector('figure.moon') ? 3 : 1; let timestamp = report.querySelector('.msg_date.ogl_timeZone').getAttribute('data-servertime'); ptreJSON[id] = {}; ptreJSON[id].player_id = playerID; ptreJSON[id].teamkey = this.ogl.ptre; ptreJSON[id].galaxy = coords[0]; ptreJSON[id].system = coords[1]; ptreJSON[id].position = coords[2]; ptreJSON[id].spy_message_ts = timestamp; ptreJSON[id].moon = {}; if(type == 1) { ptreJSON[id].activity = '*'; ptreJSON[id].moon.activity = '60'; } else { ptreJSON[id].activity = '60'; ptreJSON[id].moon.activity = '*'; } } }); if(Object.keys(ptreJSON).length > 0) { fetch('https://ptre.chez.gg/scripts/oglight_import_player_activity.php?tool=oglight', { method:'POST', body:JSON.stringify(ptreJSON) }) .then(response => response.json()) .then(data => { if(data.code != 1) { console.log('error', data); } else { Object.keys(ptreJSON).forEach(id => { document.querySelector(`.msg[data-msg-id="${id}"] .msg_title`).appendChild(Util.createDom('div', {'class':'material-icons ogl_checked tooltipLeft', 'title':'activities imported to PTRE'}, 'check_circle')); }); } }); } } // prevent the user to spam click on the same delete button document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_ready) .js_actionKill').forEach(button => { button.addEventListener('click', () => button.classList.add('ogl_noPointer')); }); messages.forEach((report, index) => { let id = report.getAttribute('data-msg-id'); report.classList.add('ogl_ready'); if(this.reportList.indexOf(id) > -1) return; if(report.closest('#fleettrashmessagespage')) return; let params = new URLSearchParams(report.querySelector('.msg_head a')?.href); let compacting = report.querySelectorAll('.compacting'); if((compacting.length > 0 && !compacting[3].querySelector('.resspan')) || !report.querySelector('.msg_title a')) { if(this.trashQueue.indexOf(id) == -1) this.trashQueue.push(id); } else if(compacting.length > 0 && compacting[3].querySelector('.resspan')) { this.reportList.push(id); let typeList = ['metal','crystal','deut','dm']; typeList.forEach(typeID => { let regex = new RegExp(`<span class="resspan">${this.ogl.component.lang.getText(typeID)}:`, 'g'); report.querySelector('.msg_content').innerHTML = report.querySelector('.msg_content').innerHTML.replace(regex, `<span class="resspan" data-type="${typeID}"><span>${this.ogl.component.lang.getText(typeID)}:</span>`); }); let data = {}; data.id = report.getAttribute('data-msg-id'); data.date = report.querySelector('.msg_date').getAttribute('data-servertime'); data.clientDate = report.querySelector('.msg_date').getAttribute('data-clienttime'); data.status = compacting[0].querySelectorAll('span[class^="status"]')[0].className; data.name = compacting[0].querySelectorAll('span[class^="status"]')[0].textContent.replace(/ /g,'').trim(); data.coords = [params.get('galaxy') || "0", params.get('system') || "0", params.get('position') || "0"]; data.tmpCoords = data.coords.map(x => x.padStart(3, '0')).join(''); data.type = report.querySelector('.msg_head figure.moon') ? 3 : 1; //data.color = (this.ogl.db.positions[this.ogl.find(this.ogl.db.positions, 'coords', data.coords.join(':'))] || {}).color; data.color = positionsList[data.tmpCoords]?.[0]?.color; data.activityColor = compacting[0].querySelectorAll('span.fright')[0].querySelector('font') && compacting[0].querySelectorAll('span.fright')[0].querySelector('font').getAttribute('color'); data.activity = compacting[0].querySelectorAll('span.fright')[0].textContent ? parseInt(compacting[0].querySelectorAll('span.fright')[0].textContent.match(/\d+/)[0]) : -1; data.resources = [ Util.formatFromUnits(compacting[3].querySelectorAll('.resspan')[0].textContent.replace(/(\D*)/, '')), Util.formatFromUnits(compacting[3].querySelectorAll('.resspan')[1].textContent.replace(/(\D*)/, '')), Util.formatFromUnits(compacting[3].querySelectorAll('.resspan')[2].textContent.replace(/(\D*)/, '')), ]; data.total = data.resources.reduce((sum, x) => sum + x); data.loot = parseInt(compacting[4].querySelector('.ctn').textContent.replace(/(\D*)/, '').replace(/%/, '')) / 100; data.renta = Math.ceil(data.total * data.loot); data.fleet = compacting[5].querySelectorAll('span').length > 0 ? Util.formatFromUnits(compacting[5].querySelectorAll('span.ctn')[0].textContent.replace(/(\D*)/, '').split(' ')[0]) : -1; data.defense = compacting[5].querySelectorAll('span').length > 1 ? Util.formatFromUnits(compacting[5].querySelectorAll('span.ctn')[1].textContent.replace(/(\D*)/, '').split(' ')[0]) : -1; data.attacked = report.querySelector('.msg_actions .icon_attack img') ? true : false; data.trash = report.querySelector('.msg_head .fright a .icon_refuse'); data.detail = report.querySelector('.msg_actions a.fright').href; data.spy = report.querySelector('a[onclick*="sendShipsWithPopup"]').getAttribute('onclick'); data.attack = report.querySelector('.icon_attack').closest('a').href; data.api = report.querySelector('.icon_apikey'); data.dom = report; if(data.renta < this.ogl.db.options.rval && data.fleet == 0 && this.ogl.db.options.togglesOff.indexOf('autoclean') == -1) { if(this.trashQueue.indexOf(data.id) == -1) this.trashQueue.push(data.id); } else { this.dataList.push(data); } } }); if(this.dataList.length > 0) { setTimeout(() => this.buildSpyTable()); } } checkTransports() { let messages = document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_transpoDone)'); if(messages.length > 0 && messages.length != document.querySelectorAll('#ui-id-2 div[aria-hidden="false"] .msg:not(.ogl_transpoDone) .msg_date.ogl_timeZone').length) { setTimeout(() => this.checkTransports(), 100); return; } messages.forEach(message => { if(!message.querySelector('.ogl_timeZone')) return; message.classList.add('ogl_transpoDone'); let typeList = ['metal','crystal','deut','dm']; let regex = new RegExp(`${this.ogl.component.lang.getText(typeList[0])}[ ]?:[ ]?(.*?) ${this.ogl.component.lang.getText(typeList[1])}`, 'g'); message.innerHTML = message.innerHTML.replace(/ /g, ' ').trim().replace(regex, `${this.ogl.component.lang.getText(typeList[0])}: <span class="ogl_metal">$1</span> ${this.ogl.component.lang.getText(typeList[1])}`); regex = new RegExp(`${this.ogl.component.lang.getText(typeList[1])}[ ]?:[ ]?(.*?) ${this.ogl.component.lang.getText(typeList[2])}`, 'g'); message.innerHTML = message.innerHTML.replace(/ /g, ' ').trim().replace(regex, `${this.ogl.component.lang.getText(typeList[1])}: <span class="ogl_crystal">$1</span> ${this.ogl.component.lang.getText(typeList[2])}`); regex = new RegExp(`${this.ogl.component.lang.getText(typeList[2])}[ ]?:[ ]?([^a-zA-Z<]+)`, 'g'); message.innerHTML = message.innerHTML.replace(/ /g, ' ').trim().replace(regex, `${this.ogl.component.lang.getText(typeList[2])}: <span class="ogl_deut">$1</span>`); }); } cleanString(str) { ['.', '(', ')', ':', ','].forEach(car => str = str.replace(new RegExp('\\'+car, 'g'), '')); // remove caracter(s) [' de '].forEach(car => str = str.replace(new RegExp('\\'+car, 'g'), ' ')); // replace caracter(s) with a space return str; } getExpeValue(locaAttr, message) { let regex; let isResource; ['metal', 'crystal', 'deut'].forEach(res => { if(this.ogl.component.lang.getText(res) == locaAttr) isResource = true; }); let regexBefore = new RegExp('(\\d+) '+this.cleanString(locaAttr), 'g'); let regexAfter = new RegExp(this.cleanString(locaAttr)+' (\\d+)', 'g'); let stringResult = regexBefore.exec(this.cleanString(message.innerHTML))?.[1] || regexAfter.exec(this.cleanString(message.innerHTML))?.[1] || -1; return parseInt(stringResult); } buildSpyTable() { let highlightIndex; this.dataList.sort((a, b) => { if(this.ogl.db.options.spyFilter == "$") return b.renta - a.renta; else if(this.ogl.db.options.spyFilter == "COORDS") return a.tmpCoords - b.tmpCoords; else if(this.ogl.db.options.spyFilter == "FLEET") return b.fleet - a.fleet; else if(this.ogl.db.options.spyFilter == "DEF") return b.defense - a.defense; else if(this.ogl.db.options.spyFilter == "DATE") return b.date - a.date; else if(this.ogl.db.options.spyFilter == "R_$") return a.renta - b.renta; else if(this.ogl.db.options.spyFilter == "R_COORDS") return b.tmpCoords - a.tmpCoords; else if(this.ogl.db.options.spyFilter == "R_FLEET") return a.fleet - b.fleet; else if(this.ogl.db.options.spyFilter == "R_DEF") return a.defense - b.defense; else if(this.ogl.db.options.spyFilter == "R_DATE") return a.date - b.date; }); if(this.spyTable) this.spyTable.remove(); let tmpTable = Util.createDom('div', {'class':'ogl_spyTable'}); let thead = tmpTable.appendChild(Util.createDom('div')); let tbody = tmpTable.appendChild(Util.createDom('div')); let header = thead.appendChild(Util.createDom('div')); //header.appendChild(Util.createDom('th', {}, '')); header.appendChild(Util.createDom('th', {'data-filter':'DATE'}, 'age')); header.appendChild(Util.createDom('th', {'data-filter':'COORDS'}, 'coords')); header.appendChild(Util.createDom('th', {}, 'name')); header.appendChild(Util.createDom('th', {'data-filter':'$'}, 'renta')); header.appendChild(Util.createDom('th', {'data-filter':'FLEET'}, 'fleet')); header.appendChild(Util.createDom('th', {'data-filter':'DEF'}, 'def')); //header.appendChild(Util.createDom('th', {'class':'ogl_shipIcon ogl_'+this.ogl.db.options.defaultShip})); let headerActions = header.appendChild(Util.createDom('th', {'class':'ogl_headerActions'})); let clean = headerActions.appendChild(Util.createDom('div', {'class':'material-icons ogl_button tooltip', 'title':this.ogl.component.lang.getText('cleanReport')}, 'cleaning_services')); clean.addEventListener('click', () => { this.spyTable.querySelectorAll('div[data-coords]').forEach(line => { if(!line.querySelector('.ogl_renta.ogl_important') && !line.querySelector('.ogl_refleet.ogl_important')) { (line.querySelector('.ogl_reportOptions div[data-title="delete"]') || line.querySelector('.ogl_reportOptions div[title="delete"]')).click(); } }); }); header.querySelectorAll('th[data-filter]').forEach(filter => { if(this.ogl.db.options.spyFilter.indexOf(filter.getAttribute('data-filter')) > -1) { filter.classList.add('ogl_active'); highlightIndex = [].indexOf.call(filter.parentNode.children, filter); } filter.addEventListener('click', () => { highlightIndex = [].indexOf.call(filter.parentNode.children, filter); this.ogl.db.options.spyFilter = this.ogl.db.options.spyFilter.indexOf('R_') > -1 ? filter.getAttribute('data-filter') : 'R_'+filter.getAttribute('data-filter'); // this.ogl.saveAsync(); this.spyTable.remove(); this.spyTable = false; document.querySelectorAll('.msg.ogl_ready').forEach(e => e.classList.remove('ogl_ready')); this.checkReports(); }); }); let sum = 0; let sumTotal = 0; let sumDetail = [0,0,0]; for(let r=0, len=this.dataList.length; r<len; r++) { let report = this.dataList[r]; if(report.coords.join(':') == '0:0:0') return; let content = tbody.appendChild(Util.createDom('div', {'data-coords':report.coords.join(':'), 'data-color':report.color, 'data-spy-id':report.id, 'data-renta':report.renta, 'data-metal':report.resources[0], 'data-crystal':report.resources[1] ,'data-deut':report.resources[2]})); let expanded = tbody.appendChild(Util.createDom('aside')); if(report.attacked) content.classList.add('ogl_attacked'); // index //let indexContent = content.appendChild(Util.createDom('td')); // date let deltaDate = serverTime.getTime() - report.date; let dateObj = new Date(parseInt(report.clientDate)); let formatedDate = `${dateObj.toLocaleDateString('fr-FR')} ${dateObj.toLocaleTimeString('fr-FR')}`; let dateContent = content.appendChild(Util.createDom('td', {'class':'ogl_reportDate tooltip', 'title':formatedDate})); let date = dateContent.appendChild(Util.createDom('div')); if(deltaDate < 3600000) date.textContent = Math.max(0, (Math.floor(deltaDate / 60000) || 0)).toString() + LocalizationStrings.timeunits.short.minute; else if(deltaDate < 86400000) date.textContent = Math.max(0, (Math.floor(deltaDate / 3600000) || 0)).toString() + LocalizationStrings.timeunits.short.hour; else date.textContent = Math.max(0, (Math.floor(deltaDate / 86400000) || 0)).toString() + LocalizationStrings.timeunits.short.day; if(report.activity > 0 && report.activity < 16 && report.activityColor != '#FFFF00') date.classList.add('ogl_danger'); else if(report.activity > 0 && report.activity < 60) date.classList.add('ogl_warning'); // coords let coords = content.appendChild(Util.createDom('td', {'class':'ogl_coords'})); let coordsA = Util.createDom('a', { 'href': `https://${window.location.host}/game/index.php?page=ingame&component=galaxy&galaxy=${report.coords[0]}&system=${report.coords[1]}&position=${report.coords[2]}`}, `<span>${report.coords.join(':')}</span>`); coords.appendChild(coordsA); // type coordsA.appendChild(Util.createDom('div', {'class':'material-icons ogl_type'}, report.type == 1 ? 'language' : 'brightness_2')) if(report.attacked) coords.appendChild(Util.createDom('div', {'class':'ogl_inFlight'})); // player let detail = content.appendChild(Util.createDom('td', {'class':'ogl_name '+report.status})); detail.appendChild(Util.createDom('a', {'class':'msg_action_link overlay', 'href':report.detail}, report.name)); // ships let shipsA; //shipList = [this.ogl.db.options.defaultShip, this.ogl.db.options.secondShip]; [this.ogl.db.options.defaultShip].forEach(shipID => { let shipsCount = this.ogl.component.fleet.calcRequiredShips(shipID, Math.round(report.renta * 1.07)); // 7% more resources shipsA = Util.createDom('a', { 'href': `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${ report.coords[0]}&system=${report.coords[1]}&position=${report.coords[2]}&type=${report.type == 3 ? 3 : 1}&mission=1&am${shipID}=${shipsCount}&ogl_mode=2&oglLazy=true` }, '<span>' + Util.formatToUnits(shipsCount, 1) + ' ' + this.ogl.component.lang.getText('abbr' + this.ogl.db.options.defaultShip) + '</span>'); if(!this.ogl.current.techs[this.ogl.db.options.defaultShip] || this.ogl.current.techs[this.ogl.db.options.defaultShip] < shipsCount) shipsA.classList.add('ogl_danger'); }); // renta let renta = content.appendChild(Util.createDom('td', {'class':'tooltip ogl_renta'})); shipsA.innerHTML += `<div>${Util.formatNumber(report.renta) || '0'}</div>`; renta.appendChild(shipsA); if(report.renta >= this.ogl.db.options.rval) renta.classList.add('ogl_important'); let resources = ['metal', 'crystal', 'deut']; let resourcesName = [this.ogl.component.lang.getText('metal'), this.ogl.component.lang.getText('crystal'), this.ogl.component.lang.getText('deut')]; resources.forEach((res, index) => { renta.title += `<div>${resourcesName[index]}: <span class="ogl_${resources[index]} float_right">${Util.formatToUnits(report.resources[index])}</span></div>`; }); renta.title += `<hr><div>Total: <span class="float_right">${Util.formatToUnits(report.total)}</span></div>`; let currentRes = report.total; let currentRenta = report.renta; let shipList = [202,203,219,210]; expanded.appendChild(Util.createDom('ul')); shipList.forEach(ship => expanded.appendChild(Util.createDom('ul', {'data-ship':ship}, `<div class="ogl_shipIcon ogl_${ship}"></div>`))); for(let i=0; i<6; i++) { currentRenta = Math.ceil(currentRes * report.loot); currentRes = currentRes - currentRenta; expanded.querySelector('ul').appendChild(Util.createDom('li', {}, Util.formatToUnits(currentRenta))); shipList.forEach(ship => { let shipsCount = this.ogl.component.fleet.calcRequiredShips(ship, Math.round(currentRenta * 1.07)); let a = Util.createDom('a', { 'class' : 'ogl_added', 'href': `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${ report.coords[0]}&system=${report.coords[1]}&position=${report.coords[2]}&type=${report.type == 3 ? 3 : 1}&mission=1&am${ship}=${shipsCount}&ogl_mode=2&oglLazy=true` }, shipsCount.toLocaleString('de-DE') || '0'); expanded.querySelector(`[data-ship="${ship}"]`).appendChild(a); if(shipsCount === Infinity) a.classList.add('ogl_disabled'); }); } // fleet let fleet = content.appendChild(Util.createDom('td', {'class':'ogl_refleet'}, (Util.formatToUnits(report.fleet, 1) || '0').replace('-1', '?'))) if(report.fleet >= this.ogl.db.options.rval || report.fleet == -1) { fleet.classList.add('ogl_important'); content.classList.add('ogl_caution'); } // def let def = content.appendChild(Util.createDom('td', {'class':'ogl_redef'}, (Util.formatToUnits(report.defense, 1) || '0').replace('-1', '?'))); if(report.defense > 0 || report.defense == -1) { def.classList.add('ogl_important'); content.classList.add('ogl_caution'); } // color let colorContent = coords.appendChild(Util.createDom('div', {'class':'ogl_colorButton tooltipClose'})); colorContent.addEventListener('click', event => { if(report.coords[2] <= 15) { let colors = Util.createDom('div', {'class':'ogl_colorAll ogl_tooltipColor'}); let planetIndexes = this.ogl.find(this.ogl.db.positions, 'coords', report.coords.join(':')); let playerIndex = this.ogl.find(this.ogl.db.players, 'name', report.name)[0]; if(planetIndexes.length == 0 && !playerIndex) { console.log(`This player doesn't exist in OGL database, please check the galaxy`); } else if(planetIndexes.length == 0 && playerIndex) { this.ogl.component.crawler.checkPlayerApi(this.ogl.db.players[playerIndex].id, () => { planetIndexes = this.ogl.find(this.ogl.db.positions, 'coords', report.coords.join(':')); this.ogl.component.color.addColorUI(colorContent, colors, planetIndexes, event, color => report.color = color); this.ogl.component.tooltip.open(colorContent, false, colors); }); } else { this.ogl.component.color.addColorUI(colorContent, colors, planetIndexes, event, color => report.color = color); this.ogl.component.tooltip.open(colorContent, false, colors); } } }); //actions let actions = content.appendChild(Util.createDom('td', {'class':'ogl_reportOptions'})); actions.appendChild(Util.createDom('div', {'class':'material-icons tooltip', 'onclick':report.spy, 'title':'spy this planet'}, 'visibility')); let more = actions.appendChild(Util.createDom('div', {'class':'material-icons tooltip ogl_expand', 'title':'expand'})); more.addEventListener('click', () => { expanded.classList.toggle('ogl_active'); }); // attack let attack = actions.appendChild(Util.createDom('a', {'class':'material-icons tooltip', 'href':report.attack, 'title':'attack this planet'}, 'adjust')); let apiKey = Util.createDom('div', {}); apiKey.innerHTML = report.api.getAttribute('title') || report.api.getAttribute('data-title'); if(!apiKey.querySelector('input')) console.log(report); apiKey = apiKey.querySelector('input').value; if(report.api && report.coords[2] <= 15) { let simButton = actions.appendChild(Util.createDom('div', {'class':'tooltip', 'title':'trashsim'}, 'S')); simButton.addEventListener('click', () => window.open(Util.genTrashsimLink(apiKey, this.ogl), '_blank')); if(this.ogl.ptre) { let ptreButton = actions.appendChild(Util.createDom('div', {'class':'ogl_smallPTRE tooltip', 'title':'import to PTRE'}, 'P')); ptreButton.addEventListener('click', () => Util.importToPTRE(apiKey, this.ogl)); } } let trash = actions.appendChild(Util.createDom('div', {'class':'material-icons tooltip', 'title':'delete'}, 'clear')); trash.addEventListener('click', () => { if(this.trashQueue.indexOf(report.id) == -1) this.trashQueue.push(report.id); if(this.trashQueue.length == 1 && !this.trashQueueProcessing) { this.tokenInput.value = this.tokenInput.value; } /*let token = document.querySelectorAll('[name="token"]')[0].getAttribute('value'); if(token == this.oldToken) return; this.oldToken = token;*/ /*this.sum = this.sum || 0; this.sum -= report.renta; this.sumDetail = this.sumDetail || [0, 0, 0]; this.sumDetail[0] -= report.metal; this.sumDetail[1] -= report.crystal; this.sumDetail[2] -= report.deut; this.calcTotal(this.sum, this.sumDetail, this.sumDetail[0] + this.sumDetail[1] + this.sumDetail[2]); const isValid = e => e.id == report.id; const isValid = e => e.id == report.id; for(let i=0, len=this.dataList.length; i<len; i++) { let item = this.dataList[i]; if(isValid(item)) { this.dataList.splice(i, 1); break; } } content.remove(); expanded.remove(); report.trash?.click();*/ }); if(report.api && !report.dom.querySelector('.ogl_sim')) { let otherSimbutton = report.dom.querySelector('.msg_actions').appendChild(Util.createDom('div', {'class':'icon_nf ogl_sim'}, 'S')); otherSimbutton.addEventListener('click', () => window.open(Util.genTrashsimLink(apiKey, this.ogl), '_blank')); if(this.ogl.ptre) { let otherPtreButton = report.dom.querySelector('.msg_actions').appendChild(Util.createDom('div', {'class':'icon_nf ogl_sim tooltip', 'title':'import to PTRE'}, 'P')); otherPtreButton.addEventListener('click', () => Util.importToPTRE(apiKey, this.ogl)); } } if(highlightIndex) content.querySelectorAll(`td`)[highlightIndex].classList.add('highlighted'); sumTotal += report.total; sum += report.renta; for(let i=0; i<3; i++) sumDetail[i] += report.resources[i]; if(r == this.dataList.length - 1) { this.spyTable = tmpTable; document.querySelector('ul.subtabs').after(this.spyTable); this.sum = sum; this.sumDetail = sumDetail; this.calcTotal(sum, sumDetail, sumTotal); } } //document.querySelector('.ogl_key.material-icons') && document.querySelector('.ogl_key.material-icons').classList.remove('ogl_hidden'); } calcTotal(sumValue, sumDetail, sumTotal) { document.querySelector('.ogl_spyTable .ogl_totalSum') && document.querySelector('.ogl_spyTable .ogl_totalSum').remove(); let total = this.spyTable.appendChild(Util.createDom('div', {'class':'ogl_totalSum'})); total.appendChild(Util.createDom('th', {}, '')); total.appendChild(Util.createDom('th', {}, '')); total.appendChild(Util.createDom('th', {}, '')); let cell = total.appendChild(Util.createDom('th', {'class':'tooltip'}, Util.formatToUnits(sumValue))); total.appendChild(Util.createDom('th', {}, '')); total.appendChild(Util.createDom('th', {}, '')); total.appendChild(Util.createDom('th', {}, '')); let resources = ['metal', 'crystal', 'deut']; let resourcesName = [this.ogl.component.lang.getText('metal'), this.ogl.component.lang.getText('crystal'), this.ogl.component.lang.getText('deut')]; sumDetail.forEach((res, index) => { cell.title += `<div>${resourcesName[index]}: <span class="ogl_${resources[index]} float_right">${Util.formatToUnits(sumDetail[index])}</span></div>`; }); cell.title += `<hr><div>Total: <span class="float_right">${Util.formatToUnits(sumTotal)}</span></div>`; } } class KeyboardManager { constructor(ogl) { this.ogl = ogl; this.dom = (document.querySelector('#cutty') || document.querySelector('#norm')).appendChild(Util.createDom('div', {'class':'ogl_keyList'})); this.sent = false; document.addEventListener('keypress', event => { if(!this.sent && (!document.querySelector('.ui-dialog') || document.querySelector('.ui-dialog').style.display == 'none') && !document.querySelector('.chat_box_textarea:focus') && document.activeElement.tagName != 'INPUT' && document.activeElement.tagName != 'TEXTAREA') { this.sent = true; let keycode = event.keyCode ? event.keyCode : event.which; let keyNumber = parseInt(String.fromCharCode(keycode)); let charList = Object.keys(this.ogl.keyboardActionsList).map(x => x.split('|')); if(keycode == 91 || keycode == 17) return; // windows key charList.forEach(c => { if(c.indexOf(String.fromCharCode(keycode).toLowerCase()) > -1) { this.ogl.keyboardActionsList[c.join('|')](event); } else if(keyNumber > 1 && keyNumber <= 9 && keycode) { this.ogl.keyboardActionsList['2-9'] && this.ogl.keyboardActionsList['2-9'](keyNumber); } else if(keycode == 13 && this.ogl.keyboardActionsList['enter']) { this.ogl.keyboardActionsList['enter'](); } }); } }); document.addEventListener('keyup', () => this.sent = false); this.addKey('i', this.ogl.component.lang.getText('prevPlanet'), () => this.goToNextPlanet(this.ogl.prevLink)); this.addKey('o', this.ogl.component.lang.getText('nextPlanet'), () => this.goToNextPlanet(this.ogl.nextLink)); if(this.ogl.page == 'fleetdispatch') { this.addKey('r', this.ogl.component.lang.getText('reverseAllShipsRes'), () => { if(fleetDispatcher.currentPage == 'fleet1') document.querySelectorAll('#fleet1 li[data-status="on"] .ogl_delta').forEach(e => e.click()); if(fleetDispatcher.currentPage == 'fleet2') document.querySelectorAll('#fleet2 .res .ogl_delta').forEach(e => e.click()); }); this.addKey('s', this.ogl.component.lang.getText('scExpe'), () => { if(fleetDispatcher.currentPage == 'fleet1') this.ogl.component.fleet.expedition(202); }); this.addKey('l', this.ogl.component.lang.getText('lcExpe'), () => { if(fleetDispatcher.currentPage == 'fleet1') this.ogl.component.fleet.expedition(203); }); this.addKey('f', this.ogl.component.lang.getText('pfExpe'), () => { if(fleetDispatcher.currentPage == 'fleet1') this.ogl.component.fleet.expedition(219); }); this.addKey('a', this.ogl.component.lang.getText('allShipsRes'), event => { if(fleetDispatcher.currentPage == 'fleet1') fleetDispatcher.selectAllShips(); if(fleetDispatcher.currentPage == 'fleet2') { if(event.shiftKey) fleetDispatcher.selectForcedMaxAll(); else fleetDispatcher.selectMaxAll(); } fleetDispatcher.refresh(); }); this.addKey('2-9', this.ogl.component.lang.getText('splitShipsRes'), keyNumber => { this.keyNumberClickFleet1 = this.keyNumberClickFleet1 || 0; this.keyNumberClickFleet2 = this.keyNumberClickFleet2 || 0; if(fleetDispatcher.currentPage == 'fleet1') { if(isNaN(keyNumber)) keyNumber = 2 + this.keyNumberClickFleet1; this.keyNumberClickFleet2 = this.keyNumberClickFleet1; this.keyNumberClickFleet1++; if(this.keyNumberClickFleet1 > 7) this.keyNumberClickFleet1 = 0; fleetDispatcher.shipsOnPlanet.forEach(ship => fleetDispatcher.selectShip(ship.id, Math.ceil(ship.number / keyNumber))); } else if(fleetDispatcher.currentPage == 'fleet2') { if(isNaN(keyNumber)) keyNumber = 2 + this.keyNumberClickFleet2; this.keyNumberClickFleet2++; if(this.keyNumberClickFleet2 > 7) this.keyNumberClickFleet2 = 0; let fleetDispatcherResources = ['metalOnPlanet', 'crystalOnPlanet', 'deuteriumOnPlanet']; document.querySelectorAll('#fleet2 #resources .res_wrap').forEach((resource, index) => { let cargoType = ['cargoMetal', 'cargoCrystal', 'cargoDeuterium']; let currentMax = fleetDispatcher[fleetDispatcherResources[index]]; if(index == 2) currentMax -= fleetDispatcher.getConsumption(); fleetDispatcher[cargoType[index]] = Math.max(Math.ceil(currentMax / keyNumber), 0); resource.querySelector('input').value = fleetDispatcher[cargoType[index]]; //fleetDispatcher.focusSendFleet(); }); } fleetDispatcher.refresh(); }); this.addKey('p', this.ogl.component.lang.getText('prevFleet'), () => { if(fleetDispatcher.currentPage != 'fleet1' || !this.ogl.component.fleet.sliderSpeed || !fleetDispatcher) return; if(!this.ogl.db.lastFleet) return; fleetDispatcher.resetShips(); if(this.ogl.db.lastFleet.shipsToSend) Object.values(this.ogl.db.lastFleet.shipsToSend).forEach(ship => fleetDispatcher.selectShip(ship.id, ship.number)); if(this.ogl.db.lastFleet.targetPlanet) { document.querySelector('#galaxy').value = this.ogl.db.lastFleet.targetPlanet.galaxy; document.querySelector('#system').value = this.ogl.db.lastFleet.targetPlanet.system; document.querySelector('#position').value = this.ogl.db.lastFleet.targetPlanet.position; document.querySelector('#position').value = this.ogl.db.lastFleet.targetPlanet.position; fleetDispatcher.targetPlanet = this.ogl.db.lastFleet.targetPlanet; fleetDispatcher.mission = this.ogl.db.lastFleet.mission; fleetDispatcher.cargoMetal = Math.min(this.ogl.db.lastFleet.cargoMetal, fleetDispatcher.metalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoCrystal = Math.min(this.ogl.db.lastFleet.cargoCrystal, fleetDispatcher.crystalOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.cargoDeuterium = Math.min(this.ogl.db.lastFleet.cargoDeuterium, fleetDispatcher.deuteriumOnPlanet, fleetDispatcher.getFreeCargoSpace()); fleetDispatcher.speedPercent = this.ogl.db.lastFleet.speedPercent; if(fleetDispatcher.mission == 15) { fleetDispatcher.expeditionTime = this.ogl.db.lastFleet.expeditionTime; fleetDispatcher.updateExpeditionTime(); } this.ogl.component.fleet.updateSpeedPercent(); } fleetDispatcher.refresh(); this.ogl.component.fleet.updatePlanetList(); }); this.addKey('t', this.ogl.component.lang.getText('attackCurrentTarget'), () => { if(!fleetDispatcher) return; new Promise(resolve => resolve(this.ogl.component.sidebar.displayTargetList(true))) .then(() => { if(this.ogl.db.options.nextTargets[0]) { fleetDispatcher.resetShips(); let shipID = this.ogl.db.options.defaultShip; let shipCount = this.ogl.component.fleet.calcRequiredShips(shipID, this.ogl.db.options.rval); fleetDispatcher.selectShip(shipID, shipCount); let coords = this.ogl.db.options.nextTargets[0].split(':'); fleetDispatcher.targetPlanet.galaxy = coords[0]; fleetDispatcher.targetPlanet.system = coords[1]; fleetDispatcher.targetPlanet.position = coords[2]; fleetDispatcher.targetPlanet.type = 1; fleetDispatcher.targetPlanet.name = '-'; fleetDispatcher.mission = 1; fleetDispatcher.refresh(); if(fleetDispatcher.currentPage == 'fleet2') fleetDispatcher.updateTarget(); this.ogl.component.fleet.targetSelected = true; if(!this.ogl.db.options.nextTargets[0] && !this.ogl.db.options.nextTargets[1]) { fadeBox(this.ogl.component.lang.getText('targetListEnd'), true); fleetDispatcher.resetShips(); fleetDispatcher.refresh(); return; } } else { fadeBox(this.ogl.component.lang.getText('noTargetSelected'), true); } }); }); } if(this.ogl.page == 'galaxy') { this.addKey('s', 'Previous galaxy', () => submitOnKey('ArrowDown')); this.addKey('z|w', 'Next galaxy', () => submitOnKey('ArrowUp')); this.addKey('q|a', 'Previous system', () => submitOnKey('ArrowLeft')); this.addKey('d', 'Next system', () => submitOnKey('ArrowRight')); } if(this.ogl.page == 'messages') { this.addKey('enter', 'Send fleet on next spies table line', () => { let nextRaidDom = document.querySelectorAll('.ogl_spyTable div[data-coords]:not(.ogl_attacked):not(.ogl_caution)')[0]; if(document.querySelector('.ogl_spyTable') && nextRaidDom) { nextRaidDom.querySelector('.ogl_renta a').click(); } }); } this.ogl.performances.push(['Keyboard',performance.now()]); } addKey(key, text, callback) { this.ogl.keyboardActionsList = this.ogl.keyboardActionsList || {}; this.ogl.keyboardActionsList[key] = callback; let tip = this.dom.appendChild(Util.createDom('div', {'class':'ogl_button tooltipLeft', 'title':text, 'data-trigger':key.toUpperCase()}, key.toUpperCase())); if(key == 'enter') { tip.classList.add('material-icons'); tip.textContent = 'subdirectory_arrow_left'; } tip.addEventListener('click', event => callback(event)); } goToNextPlanet(link) { if((this.ogl.mode != 1 && this.ogl.mode != 4) || this.ogl.component.fleet.linksUpdated) { Util.redirect(link, this.ogl); /*fetch(`https://${window.location.host}/game/index.php?page=fetchResources&ajax=1`) .then(() => { Util.redirect(link, this.ogl); return; });*/ } } } class SidebarManager { constructor(ogl) { this.ogl = ogl; this.dom = document.body.appendChild(Util.createDom('div', {'class':'ogl_sideView'})); this.cross = this.dom.appendChild(Util.createDom('div', {'class':'ogl_close material-icons'}, 'clear')); this.content = this.dom.appendChild(Util.createDom('div')); this.ogl.db.sidebarView = this.ogl.db.sidebarView || false; this.cross.addEventListener('click', () => this.close()); this.init(); } init() { if(this.ogl.db.sidebarView == 'pinned') this.displayPinnedTarget(); if(this.ogl.db.sidebarView == 'targetList') this.displayTargetList(); this.ogl.performances.push(['Sidebar',performance.now()]); } displayPinnedTarget() { if(this.ogl.db.sidebarView != 'pinned') { this.ogl.db.sidebarView = 'pinned'; // this.ogl.saveAsync(); } this.oldContent = Util.createDom('div', {}, this.content.innerHTML); this.content.textContent = ''; if(this.ogl.db.pinnedList.length > 0) { let player = this.ogl.db.players[this.ogl.find(this.ogl.db.players, 'id', this.ogl.db.pinnedList[0])[0]]; let container = Util.createDom('div'); container.innerHTML = ` <h1><span>${player.name}</span></h1> <div class="splitLine"></div> <div class="ogl_scrollable"> <div class="ogl_stalkPoints"> <div title="${player.total}"><i class="material-icons">star</i>${Util.formatToUnits(player.total)}</div> <div title="${player.eco}"><i class="material-icons">attach_money</i>${Util.formatToUnits(player.eco)}</div> <div title="${player.tech}"><i class="material-icons">science</i>${Util.formatToUnits(player.tech)}</div> <div title="${player.fleet}"><i class="material-icons">military_tech</i>${Util.formatToUnits(player.fleet)}</div> <div title="${player.def}"><i class="material-icons">security</i>${Util.formatToUnits(player.def)}</div> </div> <div class="ogl_actionsContainer"></div> <div class="splitLine"></div> <div class="ogl_stalkInfo"> <div class="ogl_stalkPlanets ogl_pinnedContent"></div> </div> </div> `; let rawStart = '000000'; let multi = 1; let isMulti = false; let positionsList = this.ogl.getPositionsByPlayerId(this.ogl.db.pinnedList[0]); let buttonsContainer; if(positionsList && this.ogl.db.pinnedList[0] && positionsList[this.ogl.db.pinnedList[0]]) { positionsList[this.ogl.db.pinnedList[0]].sort((a, b) => a.rawCoords - b.rawCoords).forEach(planetIndex => { let planet = planetIndex; let splitted = planet.coords.split(':'); let item = Util.createDom('div', {'data-coords':planet.coords}); let coordsDiv = item.appendChild(Util.createDom('span', {}, planet.coords)); coordsDiv.addEventListener('click', () => { this.scroll = document.querySelector('.ogl_pinnedContent').scrollTop; this.ogl.component.tooltip.close(); this.ogl.component.galaxy.goToPosition(splitted[0], splitted[1], splitted[2]); }); if(this.ogl.page == 'galaxy' && document.querySelector('#galaxy_input').value == splitted[0] && document.querySelector('#system_input').value == splitted[1]) { coordsDiv.classList.add('ogl_currentSystem'); } if(this.oldContent.querySelector(`[data-coords="${planet.coords}"] .ogl_checked`)) { item.appendChild(Util.createDom('div', {'class':'material-icons ogl_checked'}, 'check_circle')); } if(this.oldContent.textContent.trim() && !this.oldContent.querySelector(`[data-coords="${planet.coords}"]`)) { item.classList.add('ogl_new'); } if(planet.main) coordsDiv.appendChild(Util.createDom('div', {'class':'material-icons ogl_mainPlanet'}, 'star')); let mSpy = item.appendChild(Util.createDom('div', {'class':'ogl_moonIcon material-icons', 'data-type':3}, 'brightness_2')); mSpy.addEventListener('click', () => this.ogl.component.fleet.sendSpyProbe([splitted[0], splitted[1], splitted[2], 3], this.ogl.db.spyProbesCount, mSpy, true)); if(serverTime.getTime() - planet.lastMoonSpy < 60 * 60 * 1000) mSpy.classList.add('ogl_done'); let pSpy = item.appendChild(Util.createDom('div', {'class':'ogl_planetIcon material-icons', 'data-type':1}, 'language')); pSpy.addEventListener('click', () => this.ogl.component.fleet.sendSpyProbe([splitted[0], splitted[1], splitted[2], 1], this.ogl.db.spyProbesCount, pSpy, true)); if(serverTime.getTime() - planet.lastSpy < 60 * 60 * 1000) pSpy.classList.add('ogl_done'); if(planet.moonID == -1) mSpy.classList.add('ogl_noPointer'); planet.color ? item.setAttribute('data-color', planet.color) : item.removeAttribute('data-color'); // refresh old activities after 3h if(planet.activity && serverTime.getTime() - planet.lastUpdate > 3 * 60 * 60 * 1000) planet.activity = false; if(planet.moonActivity && serverTime.getTime() - planet.lastUpdate > 3 * 60 * 60 * 1000) planet.moonActivity = false; let pActivityDom = item.appendChild(Util.createDom('div', {'class':'ogl_planetActivity', 'data-activity':planet.activity}, planet.activity || '?')); let mActivityDom = item.appendChild(Util.createDom('div', {'class':'ogl_moonActivity', 'data-activity':planet.moonActivity}, planet.moonActivity || '?')); if(planet.activity) { pActivityDom.textContent = planet.activity; if(planet.activity == '*') pActivityDom.classList.add('ogl_short'); } if(planet.moonID > -1 && planet.moonActivity) { mActivityDom.textContent = planet.moonActivity; if(planet.moonActivity == '*') mActivityDom.classList.add('ogl_short'); } if(planet.moonID == -1) mActivityDom.classList.add('ogl_hidden'); if(rawStart == planet.rawCoords.slice(0, -3)) { item.setAttribute('data-multi', multi); isMulti = true; } else if(isMulti) { multi++; isMulti = false; } rawStart = planet.rawCoords.slice(0, -3); container.querySelector('.ogl_stalkPlanets').appendChild(item); }); buttonsContainer = container.querySelector('.ogl_actionsContainer'); let ptreAction = frame => { frame = frame || 'week'; this.ogl.component.popup.load(); let container = Util.createDom('div', {'class':'ptreContent'}); if(!this.ogl.ptre) { container.innerHTML = `Error: no teamkey registered`; this.ogl.component.popup.open(container); return; } Util.getJSON(`https://ptre.chez.gg/scripts/oglight_get_player_infos.php?tool=oglight&team_key=${this.ogl.ptre}&pseudo=${player.name}&player_id=${player.id}&input_frame=${frame}`, result => { if(result.code == 1 && result.activity_array.activity_array && result.activity_array.check_array) { let arrData = JSON.parse(result.activity_array.activity_array); let checkData = JSON.parse(result.activity_array.check_array); container.innerHTML = ` <h3>${this.ogl.component.lang.getText('reportFound')} :</h3> <div class="ptreBestReport"> <div> <div><b class="ogl_fleet"><i class="material-icons">military_tech</i>${Util.formatToUnits(result.top_sr_fleet_points)} pts</b></div> <div><b>${new Date(result.top_sr_timestamp * 1000).toLocaleDateString('fr-FR')}</b></div> </div> <div> <a class="ogl_button" target="_blank" href="${result.top_sr_link}">${this.ogl.component.lang.getText('topReportDetails')}</a> <a class="ogl_button" target="_blank" href="https://ptre.chez.gg/?country=${this.ogl.universe.lang}&univers=${this.ogl.universe.number}&player_id=${player.id}">${this.ogl.component.lang.getText('playerProfile')}</a> </div> </div> <div class="splitLine"></div> <h3>${result.activity_array.title}</h3> <div class="ptreActivities"><span></span><div></div></div> <div class="splitLine"></div> <div class="ptreFrames"></div> <!--<ul class="ptreLegend"> <li><u>Green circle</u>: no activity detected & fully checked</li> <li><u>Green dot</u>: no activity detected</li> <li><u>Red dot</u>: multiple activities detected</li> <li><u>Transparent dot</u>: not enough planet checked</li> </ul>--> `; ['last24h', '2days', '3days', 'week', '2weeks', 'month'].forEach(f => { let btn = container.querySelector('.ptreFrames').appendChild(Util.createDom('div', {'class':'ogl_button'}, f)); btn.addEventListener('click', () => ptreAction(f)); }); if(result.activity_array.succes == 1) { arrData.forEach((line, index) => { if(!isNaN(line[1])) { let div = Util.createDom('div', {'class':'tooltip'}, `<div>${line[0]}</div>`); let span = div.appendChild(Util.createDom('span', {'class':'ptreDotStats'})); let dot = span.appendChild(Util.createDom('div', {'data-acti':line[1], 'data-check':checkData[index][1]})); let dotValue = line[1] / result.activity_array.max_acti_per_slot * 100 * 7; dotValue = Math.ceil(dotValue / 30) * 30; dot.style.color = `hsl(${Math.max(0, 100 - dotValue)}deg 75% 40%)`; dot.style.opacity = checkData[index][1] + '%'; dot.style.padding = '7px'; let title; let checkValue = Math.max(0, 100 - dotValue); if(checkValue === 100) title = '- No activity detected'; else if(checkValue >= 60) title = '- A few activities detected'; else if(checkValue >= 40) title = '- Some activities detected'; else title = '- A lot of activities detected'; if(checkData[index][1] == 100) title += '<br>- Perfectly checked'; else if(checkData[index][1] >= 75) title += '<br>- Nicely checked'; else if(checkData[index][1] >= 50) title += '<br>- Decently checked'; else if(checkData[index][1] > 0) title = 'Poorly checked'; else title = 'Not checked'; div.setAttribute('title', title); if(checkData[index][1] === 100 && line[1] == 0) dot.classList.add('ogl_active'); container.querySelector('.ptreActivities > div').appendChild(div); } }); } else { container.querySelector('.ptreActivities > span').textContent = result.activity_array.message; } } else if(result.code == 1) { container.textContent = result.activity_array.message; } else container.textContent = result.message; this.ogl.component.popup.open(container); }); } let ptreBtn = buttonsContainer.appendChild(Util.createDom('div', {'class':'ogl_button ptrePinned tooltip', 'title':'Display PTRE data'}, 'PTRE')); ptreBtn.addEventListener('click', () => ptreAction()); let ptreSyncBtn = buttonsContainer.appendChild(Util.createDom('div', {'class':'material-icons ogl_button tooltip', 'title':'Sync data with OGame API and PTRE'}, 'sync')); ptreSyncBtn.addEventListener('click', () => { this.ogl.component.crawler.checkPlayerApi(this.ogl.db.pinnedList[0], () => { fadeBox('Data synced successfully'); }, true); }); } else { buttonsContainer = container.querySelector('.ogl_actionsContainer'); } let historyBtn = buttonsContainer.appendChild(Util.createDom('div', {'class':'material-icons ogl_button tooltip', 'title':'History list'}, 'history')); historyBtn.addEventListener('click', () => this.displayPinnedList()); let deleteBtn = buttonsContainer.appendChild(Util.createDom('div', {'class':'material-icons ogl_button tooltip', 'title':'Remove'}, 'delete')); deleteBtn.addEventListener('click', () => { this.ogl.db.pinnedList.forEach((e, index) => { if(e && e == player.id) { this.ogl.db.pinnedList.splice(index, 1); this.ogl.db.pinnedList.length > 0 ? historyBtn.click() : this.ogl.component.sidebar.close(); } }); }); this.open(container, true); } if(this.scroll) document.querySelector('.ogl_pinnedContent').scrollTo(0, this.scroll); } displayPinnedList() { let content = Util.createDom('div', {'class':'ogl_historyList'}); this.ogl.db.pinnedList.forEach(playerID => { let historyPlayer = this.ogl.db.players[this.ogl.find(this.ogl.db.players, 'id', playerID)[0]]; let btn = content.appendChild(Util.createDom('div', {'class':`ogl_button ${historyPlayer.status}`})); btn.appendChild(Util.createDom('b', {}, historyPlayer.name)); btn.appendChild(Util.createDom('span', {}, '#' + (historyPlayer.rank?.toString().replace('-1', '(b)') || '?'))); btn.appendChild(Util.createDom('i', {'class':'float_right'}, `<i class="material-icons">military_tech</i>${Util.formatToUnits(historyPlayer.fleet)}`)); this.open(content); btn.addEventListener('click', () => { this.ogl.db.pinnedList.forEach((e, index) => { if(e && e == playerID) this.ogl.db.pinnedList.splice(index, 1); }); this.ogl.db.pinnedList.unshift(playerID); if(this.ogl.db.pinnedList.length > this.ogl.maxPinnedTargets) this.ogl.db.pinnedList.length = this.ogl.maxPinnedTargets; // this.ogl.saveAsync(); this.ogl.component.sidebar.displayPinnedTarget(); this.ogl.component.crawler.checkPlayerApi(this.ogl.db.pinnedList[0]); }); }); } displayTargetList(silencedMode) { if(!silencedMode && this.ogl.db.sidebarView != 'targetList') { this.ogl.db.sidebarView = 'targetList'; // this.ogl.saveAsync(); } if(!silencedMode) this.load(); let ignoreVacation = this.ogl.db.options.togglesOff.indexOf('ignoreVacation') == -1; let playersList = this.ogl.getPlayersById(); let positionsList = this.ogl.getPositionsByCoords(true); let container = Util.createDom('div'); let currentGalaxy = this.ogl.db.options?.targetFilter?.[0] || 1; let currentSystem = this.ogl.db.options?.targetFilter?.[1] || 0; let systemSteps = 50; //let currentRaw = parseInt(`${currentGalaxy}:${currentSystem}:1`.split(':').map(x => x.padStart(3, '0')).join('')); let targetCoords; let nextTargetCoords; this.ogl.db.options.nextTargets = this.ogl.db.options.nextTargets || [0, 0]; let colors = container.appendChild(Util.createDom('div', {'class':'ogl_toggleColors'})); let gMenu = container.appendChild(Util.createDom('div', {'class':'ogl_toggleGalaxies'})); let sMenu = container.appendChild(Util.createDom('div', {'class':'ogl_toggleSystems'})); let content = container.appendChild(Util.createDom('div', {'class':'ogl_stalkPlanets ogl_scrollable'})); ['red', 'halfred', 'yellow', 'halfyellow', 'green', 'halfgreen', 'blue', 'halfblue', 'violet', 'halfviolet', 'gray'].forEach(color => { let toggle = colors.appendChild(Util.createDom('div', {'class':'ogl_toggle', 'data-toggle':color})); if(this.ogl.db.options.excludedColors.indexOf(color) == -1) toggle.classList.add('ogl_active'); toggle.addEventListener('click', () => { let colorIndex = this.ogl.db.options.excludedColors.indexOf(color); if(colorIndex > -1) this.ogl.db.options.excludedColors.splice(colorIndex, 1); else this.ogl.db.options.excludedColors.push(color); // this.ogl.saveAsync(); this.displayTargetList(); }); }); for(let g=1; g<=12; g++) { let gDiv = gMenu.appendChild(Util.createDom('div', {'class':'ogl_disabled', 'data-galaxy':g}, g)); if(currentGalaxy == g) gDiv.classList.add('ogl_active'); gDiv.addEventListener('click', () => { this.ogl.db.options.targetFilter[0] = g; // this.ogl.saveAsync(); this.displayTargetList(); }); for(let s=0; s<500; s+=systemSteps) { let planetsList = []; if(g==1) { let sDiv = sMenu.appendChild(Util.createDom('div', {'class':'ogl_disabled', 'data-system':s}, s.toString())); sDiv.addEventListener('click', () => { this.ogl.db.options.targetFilter[1] = s; // this.ogl.saveAsync(); this.displayTargetList(); }); } /*let loopRawStart = parseInt(`${g}:${s}:1`.split(':').map(x => x.padStart(3, '0')).join('')); let loopRawEnd = loopRawStart + systemSteps * 1000;*/ for(let sr=s; sr<s+systemSteps; sr++) { let loopRawPosition = `${g}:${sr}:1`.split(':').map(x => x.padStart(3, '0')).join('').slice(0, -3); if(positionsList[loopRawPosition]) planetsList.push(positionsList[loopRawPosition]); } let indexList = planetsList.flat(); //let indexList = this.ogl.findTargets(this.ogl.db.positions, 'rawCoords', loopRawStart, loopRawEnd); if(indexList.length > 0) { gDiv.classList.remove('ogl_disabled'); if(g == currentGalaxy) sMenu.querySelector(`[data-system="${s}"]`).classList.remove('ogl_disabled'); } indexList.forEach(entry => { //let entry = this.ogl.db.positions[index]; let player = playersList[entry.playerID]; if(ignoreVacation && player?.status?.indexOf('vacation') > -1) return; if(targetCoords && !nextTargetCoords) { nextTargetCoords = entry.coords; this.ogl.db.options.nextTargets[1] = entry.coords; } if(this.ogl.db.options.nextTargets[0] == entry.coords) { targetCoords = entry.coords; nextTargetCoords = false; } if(currentGalaxy == g && currentSystem == s) { gDiv.classList.add('ogl_active'); sMenu.querySelector(`[data-system="${s}"]`).classList.add('ogl_active'); let splitted = entry.coords.split(':'); let div = content.appendChild(Util.createDom('div', {'data-color':entry.color, 'data-playerID':entry.playerID, 'data-planetID':entry.id, 'data-minicoords':`${splitted[0]}:${splitted[1]}`})); // coords let coordsDiv = div.appendChild(Util.createDom('div', {}, entry.coords)); coordsDiv.addEventListener('click', () => { this.ogl.component.tooltip.close(); this.ogl.component.galaxy.goToPosition(splitted[0], splitted[1], splitted[2]); }); // player name div.appendChild(Util.createDom('div', {'class':player?.status}, player?.name || '?')); let pSpy = div.appendChild(Util.createDom('div', {'class':'ogl_planetIcon material-icons', 'data-type':1}, 'language')); pSpy.addEventListener('click', () => this.ogl.component.fleet.sendSpyProbe([splitted[0], splitted[1], splitted[2], 1], this.ogl.db.spyProbesCount, pSpy, true)); if(serverTime.getTime() - entry.lastSpy < 60 * 60 * 1000) pSpy.classList.add('ogl_done'); let mSpy = div.appendChild(Util.createDom('div', {'class':'ogl_moonIcon material-icons ogl_noPointer', 'data-type':3}, 'brightness_2')); if(entry.moonID && entry.moonID > -1) mSpy.classList.remove('ogl_noPointer'); mSpy.addEventListener('click', () => this.ogl.component.fleet.sendSpyProbe([splitted[0], splitted[1], splitted[2], 3], this.ogl.db.spyProbesCount, mSpy, true)); if(serverTime.getTime() - entry.lastMoonSpy < 60 * 60 * 1000) mSpy.classList.add('ogl_done'); let flag = div.appendChild(Util.createDom('div', {'class':'ogl_flagIcon material-icons'}, 'flag')); if(targetCoords == entry.coords) flag.classList.add('ogl_active'); flag.addEventListener('click', () => { this.ogl.db.options.nextTargets = [entry.coords, 0]; this.displayTargetList(); }); } }); } } if(!silencedMode) this.open(container); } open(html, noLoad) { let update = () => { this.content.textContent = ''; this.content.appendChild(html); this.dom.classList.add('ogl_active'); if(this.ogl.page == 'galaxy') { document.querySelectorAll('.ogl_stalkPlanets.ogl_scrollable > div.ogl_currentSystem').forEach(item => item.classList.remove('ogl_currentSystem')); document.querySelectorAll(`.ogl_stalkPlanets.ogl_scrollable > div[data-minicoords="${galaxy}:${system}"]`).forEach(item => item.classList.add('ogl_currentSystem')); } } if(noLoad) update(); else setTimeout(() => update(), 100); } load() { this.content.innerHTML = '<div class="ogl_loader"></div>'; this.dom.classList.add('ogl_active'); } close() { this.ogl.db.sidebarView = false; this.dom.classList.remove('ogl_active'); // this.ogl.saveAsync(); } } class PopupManager { constructor(ogl) { this.ogl = ogl; this.overlay = document.body.appendChild(Util.createDom('div', {'class':'ogl_overlay'})); this.dom = this.overlay.appendChild(Util.createDom('div', {'class':'ogl_popup'})); this.cross = this.dom.appendChild(Util.createDom('div', {'class':'ogl_close material-icons'}, 'clear')); this.content = this.dom.appendChild(Util.createDom('div')); this.cross.addEventListener('click', () => this.close()); this.overlay.addEventListener('click', event => { if(event.target === this.overlay) this.close(); }); this.ogl.performances.push(['Popup',performance.now()]); } load() { this.content.innerHTML = ''; this.content.appendChild(Util.createDom('div', {'class':'ogl_loader'})); document.body.classList.add('ogl_active'); this.dom.classList.add('ogl_active'); this.overlay.classList.add('ogl_active'); this.dom.classList.add('ogl_cleaned'); } open(html, callback) { setTimeout(() => { clearTimeout(this.ogl.component.tooltip.openTimer); clearTimeout(this.ogl.component.tooltip.updateTimer); this.ogl.component.tooltip.close(); this.content.innerHTML = ''; this.content.appendChild(html); document.body.classList.add('ogl_active'); this.dom.classList.remove('ogl_cleaned'); this.dom.classList.add('ogl_active'); this.overlay.classList.add('ogl_active'); if(callback) callback(); }, Math.random() * (400 - 100 + 1) + 100); } close() { document.body.classList.remove('ogl_active'); this.dom.classList.remove('ogl_active'); this.overlay.classList.remove('ogl_active'); } } class JumpgateManager { constructor(ogl) { this.ogl = ogl; this.ogl.db.jumpGateTimers = this.ogl.db.jumpGateTimers || {}; if(this.page == 'facilities' || this.ogl.current.type == 'moon') { let calcTimer = level => { return (0.25 * Math.pow(level, 2) - 7.57 * level + 67.34) / this.ogl.universe.fleetSpeedWar * 60000; } jumpgateDone = a => { var a = $.parseJSON(a); if(a.status) { planet = a.targetMoon; $(".overlayDiv").dialog("destroy"); let originCoords = this.ogl.current.coords.join(':'); let originLevel = this.ogl.current.smallplanet.querySelector('.moonlink').getAttribute('data-jumpgatelevel'); let destinationCoords = document.querySelector(`.moonlink[href*="${jumpGateTargetId}"]`).parentNode.querySelector('.planet-koords').textContent.slice(1, -1); let destinationLevel = document.querySelector(`.moonlink[href*="${jumpGateTargetId}"]`).getAttribute('data-jumpgatelevel'); let now = serverTime.getTime(); this.ogl.db.jumpGateTimers[originCoords] = now + calcTimer(originLevel); this.ogl.db.jumpGateTimers[destinationCoords] = now + calcTimer(destinationLevel); this.ogl.save(); } errorBoxAsArray(a.errorbox); if(typeof(a.newToken) != "undefined") setNewTokenData(a.newToken); } } this.ogl.observeMutation(() => { if(document.querySelector('#jumpgateForm') && !document.querySelector('#jumpgateForm').classList.contains('ogl_ready')) { document.querySelector('#jumpgateForm').classList.add('ogl_ready'); document.querySelectorAll('#jumpgateForm .ship_txt_row:not(.tdInactive)').forEach(ship => { ship.style.position = 'relative'; let delta = ship.appendChild(Util.createDom('div',{'class':'ogl_delta'}, '<i class="material-icons">fiber_smart_record</i>')); delta.addEventListener('click', event => { let input = ship.nextElementSibling.querySelector('input'); let selected = input.value.replace(/\./g, '') || 0; let amount = parseInt(input.getAttribute('rel')); input.value = amount - selected; }); }); } }, 'jumpgate'); this.addTimer(); this.ogl.performances.push(['Jumpgate',performance.now()]); } addTimer() { document.querySelectorAll('.smallplanet').forEach(planet => { let coords = planet.querySelector('.planet-koords').textContent.slice(1, -1); if(this.ogl.db.jumpGateTimers[coords] && this.ogl.db.jumpGateTimers[coords] > serverTime.getTime()) { if(!planet.querySelector('.moonlink')) return; let updateTimer = () => new Date(this.ogl.db.jumpGateTimers[coords] - (serverTime.getTime() + 3600000)).toLocaleTimeString('fr-FR').substr(3); let timer = updateTimer(); let div = planet.querySelector('.moonlink').appendChild(Util.createDom('div', {'class':'ogl_jumpGateTimer'}, timer)); let interval = setInterval(() => { if(this.ogl.db.jumpGateTimers[coords] <= serverTime.getTime()) clearInterval(interval); else div.textContent = updateTimer(); }, 1000); } }); } } class TimeManager { constructor(ogl) { this.ogl = ogl; this.currentDetail; const ping = (performance.timing.responseEnd - performance.timing.requestStart) / 1000; let li = Util.createDom('li', {'class':'ogl_ping'}, `${ping} s`); document.querySelector('#bar ul').appendChild(li); if(ping >= 2) li.classList.add('ogl_danger'); else if(ping >= 1) li.classList.add('ogl_warning'); if(this.ogl.page == 'messages') { this.ogl.observeMutation(() => { document.querySelectorAll('.msg_date:not(.ogl_timeZone)').forEach(element => { this.updateTime(element); }); }, 'messagesdate'); } this.checkCurrentBuilding(); // update ogame main clock let clock = document.querySelector('#bar ul li.OGameClock:not(.ogl_ready)'); clock.classList.add('ogl_ready'); this.updateTime(clock); this.observe(clock); // update fleets timers this.ogl.addToUpdateQueue(() => { document.querySelectorAll('#arrivalTime:not(.ogl_ready), #returnTime:not(.ogl_ready)').forEach((element, index) => { element.classList.add('ogl_ready'); if(element.closest('#rocketattack')) return; this.updateTime(element); this.observe(element); }); document.querySelectorAll('.allianceAttack .arrivalTime:not(.ogl_ready), .eventFleet .arrivalTime:not(.ogl_ready), .fleetDetails .absTime:not(.ogl_ready), .fleetDetails .nextabsTime:not(.ogl_ready)').forEach((element, index) => { element.classList.add('ogl_ready'); if(element.closest('#rocketattack')) return; this.updateTime(element); }); }); let pages = ['supplies', 'facilities', 'shipyard', 'defenses', 'research', 'lfbuildings', 'lfresearch']; if(pages.indexOf(this.ogl.page) > -1) { Util.updateCheckIntInput(() => this.checkDetail()); this.ogl.observeMutation(() => this.checkDetail(), 'details'); } this.ogl.performances.push(['Time',performance.now()]); } observe(target) { let observer = new MutationObserver(() => this.updateTime(target)); observer.observe(target, {childList:true}); } updateTime(domElement) { domElement.classList.add('ogl_hiddenContent'); domElement.classList.add('ogl_timeZone'); let serverRawTime = domElement.textContent; if(!serverRawTime || serverRawTime.trim() == '') return; let timeMode = false; let splitted = serverRawTime.replace(/ \.$/, '').trim().replace(/[ \.]/g, ':').split(':'); if(splitted.length <= 5) { timeMode = true; splitted = ["01","01","2000"].concat(splitted); } splitted = splitted.map(e => e.padStart(2, '0')); if(splitted[2].length == 2) splitted[2] = '20' + splitted[2]; // ex: 10.05.22 => 10.05.2022 let serverDate = new Date(`${splitted[2]}-${splitted[1]}-${splitted[0]}T${splitted[3]}:${splitted[4]}:${splitted[5]}`); let unixTimestamp = serverDate.getTime() + this.ogl.db.servertTimezone; let serverTimeMs = serverDate.getTime(); //let serverClientTimeDiff = timeDiff > 1000000 || timeDiff < -1000000 ? timeDiff : 0; let serverClientTimeDiff = this.ogl.db.servertTimezone - this.ogl.db.clientTimezone; let clientTimeMs = this.ogl.db.options.togglesOff.indexOf('timezoneMode') == -1 ? serverDate.getTime() + serverClientTimeDiff : serverDate.getTime(); let clientDate = new Date(clientTimeMs); domElement.setAttribute('data-unixtimestamp', unixTimestamp); domElement.setAttribute('data-servertime', serverTimeMs); domElement.setAttribute('data-clienttime', clientTimeMs); if(timeMode) { domElement.setAttribute('data-timezone', clientDate.toLocaleTimeString('fr-FR')); } else { domElement.classList.add('ogl_fulldate'); domElement.setAttribute('data-datezone', `${clientDate.toLocaleDateString('fr-FR').replace(/\//g, '.')} `); domElement.setAttribute('data-timezone', ` ${clientDate.toLocaleTimeString('fr-FR')}`); } /* let time = domElement.textContent; let newTime; let timeMode = false; if(!time) return; time = time.replace(/ \.$/, ''); time = time.trim().replace(/[ \.]/g, ':'); time = time.split(':'); if(time.length <= 5) { timeMode = true; time = ["01","01","2000"].concat(time); } time.forEach((t, index) => time[index] = t.padStart(2, '0')); if(time[2].length == 2) time[2] = '20' + time[2]; newTime = new Date(`${time[2]}-${time[1]}-${time[0]}T${time[3]}:${time[4]}:${time[5]}`).getTime(); domElement.setAttribute('data-servertime', newTime); //newTime = new Date(newTime - Math.round(timeDiff / 100000) * 100000); //domElement.setAttribute('data-timestamp', newTime.getTime()); if(timeMode) { domElement.setAttribute('data-timezone', newTime.toLocaleTimeString('fr-FR')); } else { domElement.classList.add('ogl_fulldate'); domElement.setAttribute('data-datezone', `${newTime.toLocaleDateString('fr-FR').replace(/\//g, '.')} `); domElement.setAttribute('data-timezone', ` ${newTime.toLocaleTimeString('fr-FR')}`); }*/ } checkCurrentBuilding() { let countDownID = ['buildingCountdown', 'researchCountdown', 'shipyardCountdown2', 'lfbuildingCountdown']; ['restTimebuilding', 'restTimeresearch', 'restTimeship2', 'restTimelfbuilding '].forEach((building, index) => { try { let time = new Date(serverTime - Math.round(timeDiff / 100000) * 100000 + eval(building) * 1000); let parent = document.querySelector(`span#${countDownID[index]}`).closest('.content'); let div = parent.appendChild(Util.createDom('div', {'class':'ogl_endTime'})); div.innerHTML = `${time.toLocaleDateString('fr-FR').replace(/\//g, '.')} <span>${time.toLocaleTimeString('fr-FR')}</span>`; } catch(e){} }); } checkDetail() { // fix an ogame bug when an user spam click if(document.querySelectorAll('#technologydetails').length > 1) { document.querySelectorAll('#technologydetails').forEach((e, index) => { if(index > 0) e.remove() }); } this.currentDetail = document.querySelector('#technologydetails_content'); if(this.currentDetail && this.currentDetail.querySelector('.og-loading') && this.currentDetail.querySelector('.og-loading').style.display == 'none') { //let amount = parseInt(this.currentDetail.querySelector('#build_amount')?.value || 1) || 1; let domTime = this.currentDetail.querySelector('.build_duration time'); // prev / next / lock buttons actions if(!this.currentDetail.querySelector('.ogl_detailActions')) { let isInitial = true; let tech = {}; tech.id = parseInt(this.currentDetail.querySelector('#technologydetails').getAttribute('data-technology-id')); tech.name = this.currentDetail.querySelector('#technologydetails h3').textContent; tech.initial = {}; tech.initial.time = domTime.getAttribute('datetime'); tech.initial.level = parseInt(this.currentDetail.querySelector('.information .level') ? this.currentDetail.querySelector('.information .level').getAttribute('data-value') : 0); tech.initial.metal = parseInt(!this.currentDetail.querySelector('.costs .metal') ? 0 : this.currentDetail.querySelector('.costs .metal').getAttribute('data-value')); tech.initial.crystal = parseInt(!this.currentDetail.querySelector('.costs .crystal') ? 0 : this.currentDetail.querySelector('.costs .crystal').getAttribute('data-value')); tech.initial.deut = parseInt(!this.currentDetail.querySelector('.costs .deuterium') ? 0 : this.currentDetail.querySelector('.costs .deuterium').getAttribute('data-value')); tech.initial.energy = parseInt(!this.currentDetail.querySelector('.costs .energy') ? 0 : this.currentDetail.querySelector('.costs .energy').getAttribute('data-value')); tech.current = {}; tech.current.level = tech.initial.level; tech.current.metal = tech.initial.metal; tech.current.crystal = tech.initial.crystal; tech.current.deut = tech.initial.deut; tech.current.energy = tech.initial.energy; tech.data = Datafinder.getTech(tech.id) || {}; tech.data.priceFactor = tech.data.priceFactor || 2; tech.data.energyFactor = tech.data.energyFactor || 2; tech.data.durationFactor = tech.data.durationFactor || tech.data.priceFactor; tech.isBaseBuilding = tech.id < 100; tech.isBaseResearch = tech.id > 100 && tech.id <= 199; tech.isShip = tech.id > 200 && tech.id <= 299; tech.isDef = tech.id > 400 && tech.id <= 499; tech.isLfBuilding = (tech.id > 11100 && tech.id <= 11199) || (tech.id > 12100 && tech.id <= 12199) || (tech.id > 13100 && tech.id <= 13199) || (tech.id > 14100 && tech.id <= 14199); tech.isLfResearch = (tech.id > 11200 && tech.id <= 11299) || (tech.id > 12200 && tech.id <= 12299) || (tech.id > 13200 && tech.id <= 13299) || (tech.id > 14200 && tech.id <= 14299); let self = this; let coords = this.ogl.current.coords.join(':'); if(this.ogl.current.type == 'moon') coords += ':M'; let baseTechs = { // buildings robot:this.ogl.db.me?.planets?.[coords]?.techs?.[14] || 0, nanite:this.ogl.db.me?.planets?.[coords]?.techs?.[15] || 0, labo:this.ogl.db.me?.planets?.[coords]?.techs?.[31] || 0, // researches energy:this.ogl.db.me?.planets?.[coords]?.techs?.[113] || 0, network:this.ogl.db.me?.planets?.[coords]?.techs?.[123] || 0, }; let humanTechs = { center:this.ogl.db.me?.planets?.[coords]?.techs?.[11103] || 0, }; let rocktalTechs = { center:this.ogl.db.me?.planets?.[coords]?.techs?.[12104] || 0, }; let mechanTechs = { center:this.ogl.db.me?.planets?.[coords]?.techs?.[13103] || 0, }; let kaeleshTechs = { center:this.ogl.db.me?.planets?.[coords]?.techs?.[14103] || 0, }; let currentRace = document.querySelector('#lifeform .lifeform-item-icon')?.className.replace(/\D/g, '') || 0; let center = currentRace == 1 ? humanTechs.center : currentRace == 2 ? rocktalTechs.center : currentRace == 3 ? mechanTechs.center : currentRace == 4 ? kaeleshTechs.center : 0; // best labs let networkLevel = 0; let laboList = []; Object.entries(this.ogl.db.me.planets).forEach(p => { if(p[0] != coords && p[0].indexOf(':M') == -1) laboList.push(p[1].techs[31])}); laboList.sort((a, b) => b - a); laboList.length = Math.min(laboList.length, baseTechs.network); if(laboList.length) networkLevel = laboList.reduce((a, b) => a + b); let updateFullDate = () => { let li = this.currentDetail.querySelector('.ogl_timeZone.ogl_fulldate') || this.currentDetail.querySelector('.build_duration').appendChild(Util.createDom('div', {'class':'ogl_timeZone ogl_fulldate'})); let totalTime = 0; let indexArr = domTime.getAttribute('datetime').replace('PT', '').replace('P', '').match(/\D+/g).map(String); let valueArr = domTime.getAttribute('datetime').replace('PT', '').replace('P', '').match(/\d+/g).map(Number); valueArr.forEach((value, index) => { if(indexArr[index] == "DT") totalTime += value * 86400; if(indexArr[index] == "H") totalTime += value * 3600; if(indexArr[index] == "M") totalTime += value * 60; if(indexArr[index] == "S") totalTime += value; }); let seconds = totalTime; let newTime = new Date(serverTime.getTime() + seconds * 1000); li.setAttribute('data-datezone', `${newTime.toLocaleDateString('fr-FR').replace(/\//g, '.')} `); li.setAttribute('data-timezone', ` ${newTime.toLocaleTimeString('fr-FR')}`); } let updateDomTime = () => { let totalTime = 0; let indexArr = tech.initial.time.replace('PT', '').replace('P', '').match(/\D+/g).map(String); let valueArr = tech.initial.time.replace('PT', '').replace('P', '').match(/\d+/g).map(Number); valueArr.forEach((value, index) => { if(indexArr[index] == "DT") totalTime += value * 86400; if(indexArr[index] == "H") totalTime += value * 3600; if(indexArr[index] == "M") totalTime += value * 60; if(indexArr[index] == "S") totalTime += value; }); if(!isInitial) { if(this.currentDetail.querySelector('#build_amount')) totalTime = totalTime * parseInt(this.currentDetail.querySelector('#build_amount')?.value || 1) || 1; // time formulas for each techs type if(tech.isLfBuilding) { totalTime = Math.round(tech.current.level * tech.data.duration * Math.pow(tech.data.durationFactor, tech.current.level)) / (1 + baseTechs.robot) / (Math.pow(2, baseTechs.nanite)) / this.ogl.universe.ecoSpeed; } else if(tech.isLfResearch) { totalTime = Math.round(tech.current.level * tech.data.duration * Math.pow(tech.data.durationFactor, tech.current.level)) * (1 - 0.02 * center) / (this.ogl.db.researchSpeed * this.ogl.universe.ecoSpeed); } else if(tech.isBaseBuilding && tech.id != 15) { let levelRatio = tech.id == 43 ? 1 : 4 - tech.current.level / 2; totalTime = (tech.current.metal + tech.current.crystal) / (2500 * Math.max(levelRatio, 1) * (1 + baseTechs.robot) * (Math.pow(2, baseTechs.nanite))) / this.ogl.universe.ecoSpeed * 3600; } else if(tech.isBaseResearch) { totalTime = (tech.current.metal + tech.current.crystal) / (1000 * (1 + baseTechs.labo + networkLevel)) / (this.ogl.db.researchSpeed * this.ogl.universe.ecoSpeed) * 3600; } else if(tech.id != 15) { totalTime = totalTime * Math.pow(tech.data.durationFactor, tech.current.level - tech.initial.level); } let bonus = 0; if(tech.isBaseResearch && this.ogl.account.class == 3) bonus += 25; if(tech.isBaseResearch && document.querySelector(`[data-technology="${tech.id}"] .acceleration`)) bonus += parseInt(document.querySelector(`[data-technology="${tech.id}"] .acceleration`).getAttribute('data-value')); if(tech.isBaseResearch && document.querySelector('#officers .technocrat.on')) totalTime = totalTime - totalTime * 25 / 100; totalTime = totalTime - totalTime * bonus / 100; } let seconds = Math.ceil(totalTime || 1); let w = Math.floor(seconds / (3600*24*7)); let d = Math.floor(seconds % (3600*24*7) / (3600*24)); let h = Math.floor(seconds % (3600*24) / 3600); let m = Math.floor(seconds % 3600 / 60); let s = Math.floor(seconds % 60); let wd = Math.floor(seconds / (3600*24)); domTime.setAttribute('datetime', `${wd}DT${h}H${m}M${s}S`); domTime.textContent = ''; if(w > 0) domTime.textContent += `${w}${LocalizationStrings.timeunits.short.week} `; if(d > 0) domTime.textContent += `${d}${LocalizationStrings.timeunits.short.day} `; if(h > 0) domTime.textContent += `${h}${LocalizationStrings.timeunits.short.hour} `; if(m > 0 && w <= 0) domTime.textContent += `${m}${LocalizationStrings.timeunits.short.minute} `; if(s > 0 && w <= 0 && d <= 0) domTime.textContent += `${s}${LocalizationStrings.timeunits.short.second}`; updateFullDate(); } let updateLevel = function(newLevel, updateDom) { isInitial = false; tech.current.level = newLevel > 0 ? newLevel : 1; if(self.currentDetail.querySelector('.information .level')) self.currentDetail.querySelector('.information .level').setAttribute('data-step', tech.current.level - tech.initial.level); ['metal', 'crystal', 'deut', 'energy', 'energyConsumption', 'energyProduction'].forEach(res => { // cost if(res == 'energy' && tech.isLfBuilding) tech.current[res] = Math.ceil(tech.current.level * tech.data[res] * Math.pow(tech.data.energyFactor, tech.current.level)); else if(tech.isLfBuilding || tech.isLfResearch) tech.current[res] = Math.ceil(tech.data[res] * Math.pow(tech.data.priceFactor, tech.current.level - 1) * tech.current.level); else if(!tech.isShip && !tech.isDef) tech.current[res] = Math.ceil(tech.initial[res] * Math.pow(tech.data.priceFactor, tech.current.level - tech.initial.level)); // consumption if(res == 'energyConsumption') { let consumption = 0; let prevConsumption = 0; let domEnergy = document.querySelector('.additional_energy_consumption .value'); if(tech.id == 1 || tech.id == 2) { consumption = Math.ceil(10 * tech.current.level * Math.pow(1.1, tech.current.level)); prevConsumption = Math.ceil(10 * (tech.current.level-1) * Math.pow(1.1, (tech.current.level-1))); } else if(tech.id == 3) { consumption = Math.ceil(20 * tech.current.level * Math.pow(1.1, tech.current.level)); prevConsumption = Math.ceil(20 * (tech.current.level-1) * Math.pow(1.1, (tech.current.level-1))); } if(consumption && prevConsumption && domEnergy) { domEnergy.textContent = Util.formatNumber(consumption - prevConsumption); } } // production if(res == 'energyProduction') { let production = 0; let prevProduction = 0; let domEnergy = document.querySelector('.energy_production .value'); if(tech.id == 4) { production = Math.ceil(20 * tech.current.level * Math.pow(1.1, tech.current.level)); prevProduction = Math.ceil(20 * (tech.current.level-1) * Math.pow(1.1, (tech.current.level-1))); } else if(tech.id == 12) { production = Math.ceil(30 * tech.current.level * Math.pow((1.05 + baseTechs.energy * 0.01), tech.current.level)); prevProduction = Math.ceil(30 * (tech.current.level-1) * Math.pow((1.05 + baseTechs.energy * 0.01), (tech.current.level-1))); } if(production && prevProduction && domEnergy) { domEnergy.innerHTML = `${Util.formatNumber(production)} <span class="bonus" data-value="${production-prevProduction}">(+${Util.formatNumber(production-prevProduction)})</span>`; } } if(updateDom) { let target = self.currentDetail.querySelector('.costs .' + res.replace('deut', 'deuterium')); if(target) { target.textContent = Util.formatToUnits(tech.current[res]); target.setAttribute('data-total', tech.current[res]); target.setAttribute('title', `${Util.formatNumber(tech.current[res])} ${self.ogl.component.lang.getText(res)}`); self.currentDetail.querySelector('.information .level').innerHTML = `Level ${tech.current.level - 1} <i class="material-icons">arrow_forward</i> <span>${tech.current.level}</span>`; if(self.ogl.current[res] < tech.current[res]) target.classList.add('insufficient'); else target.classList.remove('insufficient'); } } /* if(tech.initial[res]) { let ratio = res == 'energy' ? tech.energyRatio : tech.ratio; let isLfBuilding = (tech.id > 11100 && tech.id <= 11199) || (tech.id > 12100 && tech.id <= 12199) || (tech.id > 13100 && tech.id <= 13199) || (tech.id > 14100 && tech.id <= 14199); let isLfResearch = (tech.id > 11200 && tech.id <= 11299) || (tech.id > 12200 && tech.id <= 12299) || (tech.id > 13200 && tech.id <= 13299) || (tech.id > 14200 && tech.id <= 14299); if(res == 'energy' && isLfBuilding) tech.current[res] = Math.ceil(tech.current.level * tech.basePrice[res] * Math.pow(ratio, tech.current.level)); else if(isLfBuilding) tech.current[res] = Math.ceil(tech.basePrice[res] * Math.pow(ratio, tech.current.level - 1) * tech.current.level); else if(isLfResearch) tech.current[res] = Math.ceil(tech.basePrice[res] * Math.pow(ratio, tech.current.level - 1) * tech.current.level); else tech.current[res] = Math.ceil(tech.initial[res] * Math.pow(ratio, tech.current.level - tech.initial.level)); if(updateDom) { let target = self.currentDetail.querySelector('.costs .' + res.replace('deut', 'deuterium')); target.textContent = Util.formatToUnits(tech.current[res]); target.setAttribute('data-total', tech.current[res]); target.setAttribute('title', `${Util.formatNumber(tech.current[res])} ${self.ogl.component.lang.getText(res)}`); self.currentDetail.querySelector('.information .level').innerHTML = `Level ${tech.current.level - 1} <i class="material-icons">arrow_forward</i> <span>${tech.current.level}</span>`; if(self.ogl.current[res] < tech.current[res]) target.classList.add('insufficient'); else target.classList.remove('insufficient'); } }*/ }); updateDomTime(); return tech; } let container = this.currentDetail.querySelector('.sprite_large').appendChild(Util.createDom('div', {'class':'ogl_detailActions'})); if(this.currentDetail.querySelector('.information .level')) { this.currentDetail.querySelector('.information .level').setAttribute('data-ratio', tech.ratio); let prevButton = container.appendChild(Util.createDom('div', {'class':'ogl_button material-icons'}, 'chevron_left')); let initButton = container.appendChild(Util.createDom('div', {'class':'ogl_button material-icons'}, 'cancel')); let nextButton = container.appendChild(Util.createDom('div', {'class':'ogl_button material-icons'}, 'chevron_right')); prevButton.addEventListener('click', () => updateLevel(tech.current.level - 1, true)); initButton.addEventListener('click', () => updateLevel(tech.initial.level, true)); nextButton.addEventListener('click', () => updateLevel(tech.current.level + 1, true)); //initButton.click(); } let lockButton = container.appendChild(Util.createDom('div', {'class':'ogl_button material-icons'}, 'lock')); lockButton.addEventListener('click', () => { let amount = 1; let levelDiff = tech.current.level - tech.initial.level; if(levelDiff < 0) return; if(this.currentDetail.querySelector('#build_amount')) { levelDiff = 0; amount = parseInt(this.currentDetail.querySelector('#build_amount').value || 1); } for(let i=0; i<=levelDiff; i++) { let tmpTech = updateLevel(tech.initial.level + i); let lockedTech = {}; lockedTech.id = tmpTech.id; lockedTech.name = tmpTech.name; lockedTech.amount = amount; lockedTech.level = tmpTech.current.level; lockedTech.metal = tmpTech.current.metal * amount; lockedTech.crystal = tmpTech.current.crystal * amount; lockedTech.deut = tmpTech.current.deut * amount; this.ogl.component.empire.lockTech(lockedTech); } }); let checkInput = () => { let currentAmount = parseInt(this.currentDetail.querySelector('#build_amount')?.value || 1) || 1; let energyProd = parseInt(this.currentDetail.querySelector('.energy_production .bonus')?.getAttribute('data-value') || 0) * currentAmount; let energyConso = parseInt(this.currentDetail.querySelector('.additional_energy_consumption .value')?.getAttribute('data-value') || 0) * currentAmount; if(energyProd) this.currentDetail.querySelector('.energy_production .value .bonus').textContent = `(+${Util.formatNumber(energyProd)})`; if(energyConso) this.currentDetail.querySelector('.additional_energy_consumption .value').textContent = Util.formatNumber(energyConso); ['metal', 'crystal', 'deut', 'energy'].forEach(res => { let target = self.currentDetail.querySelector('.costs .' + res.replace('deut', 'deuterium')); if(target) { let newValue = tech.initial[res] * currentAmount; target.textContent = Util.formatToUnits(newValue); target.setAttribute('data-total', newValue); target.setAttribute('title', `${Util.formatNumber(newValue)} ${self.ogl.component.lang.getText(res)}`); if(this.ogl.current[res] < newValue) target.classList.add('insufficient'); else target.classList.remove('insufficient'); } }); updateDomTime() } updateDomTime(); Util.updateCheckIntInput(() => checkInput()); if(this.currentDetail.querySelector('.information .level')) this.currentDetail.querySelector('.information .level').innerHTML = `Level ${tech.current.level - 1} <i class="material-icons">arrow_forward</i> <span>${tech.current.level}</span>`; if(this.currentDetail.querySelector('#build_amount')) // ships or def { this.currentDetail.querySelector('#build_amount').setAttribute('onkeyup', 'checkIntInput(this, 1, 999999);event.stopPropagation();'); this.currentDetail.querySelector('#build_amount').addEventListener('click', () => checkInput()); this.currentDetail.querySelector('.maximum') && this.currentDetail.querySelector('.maximum').addEventListener('click', () => setTimeout(checkInput, 20)); } this.ogl.addToUpdateQueue(() => updateFullDate()); } } } } class LangManager { constructor(ogl) { this.ogl = ogl; this.en = { abbr202 : "SC", abbr203 : "LC", abbr219 : "PF", abbr210 : "SP", planets : "planets", ships : "Ships", items : "Items", other : "Other", resources : "Resources", fight : "Fight", noMoonError : "Error, there is no moon here", capacityPicker : "Resources to send", scExpe : "Small cargo expedition", lcExpe : "Large cargo expedition", pfExpe : "Pathfinder expedition", allShipsRes : "Select all ships (page 1) <br>or all resources (page 2)", splitShipsRes : "Split all ships (page 1) <br>or all resources (page 2)", prevFleet : "Repeat previous fleet", required : "req.", reverseAllShipsRes : "Reverse all selected ships (page 1) <br>or all resources (page 2)", nextPlanet : "Go to next planet", prevPlanet : "Go to previous planet", gain : "Gain", timeLimits : "Day;Week;Month;All", spyPosition : "Spy this position", flagTarget : "Set next target", attackCurrentTarget : "Attack next target", noTargetSelected : "No target selected", timerInfo : "Last refresh", blackhole : "Black hole", signalBlackhole : "Signal a blackhole", moreStats : "More statistics", eraseData : "Erase data", defaultView : "Default view", economyView : "Economy view", productionView : "Production view", pinnedView : "Pinned target", targetView : "Targets list", oglConfig : "OGLight settings", defaultShip : "Default ship", defaultMission : "Default mission", autoCollect : "Collect resources", minifyPictures : "Minify large pictures", displayTimers : "Display refresh timers", rentaStats : "Display stats", excludeConso : "Exclude deut consumption from stats", spiesTable : "Display spies table", autoClean : "Autoclean spies table", cleanReport : "Clean spies reports", inFlight : "In flight", linkedMoons : "Linked moons", linkedPlanets : "Linked planets", kofi : "Do you like OGLight ? Then support me :)", wrongTarget : "Warning, the targeted planet has changed and will be removed from the list !", deleteSpyDef : "Delete spies agaisnt my planets", rentaPerDay : "Mean ($daysd)", totalPerDay : "Mean+prod ($daysd)", ignoreRaid : "Ignore this raid", keepOnPlanet : "to keep on planet", switchNameCoords : "switch coords/names", sendResources : "Send resources", sendMissingResources : "Deduct resources on the planet from the total", fleetDetailsName : "Display ships name in fleet details", onPlanets : "On planets", reportFound : "Top report", topReportDetails : "Top report details", playerProfile : "Player profile", rightMenuTooltips : "Hide right menu tooltips", bigShip : "Use the biggest available ship (expeditions)", targetListEnd : "End of targets list", ignoreVacation : "Hide players in vacation mode (targets list)", tooltipDelay : "Tooltip delay (ms)", timezoneMode : "Use timezone mode", ignoreExpeShips : "Ignore ships found in expeditions", } this.fr = { abbr202 : "PT", abbr203 : "GT", abbr219 : "EC", abbr210 : "SP", planets : "planètes", ships : "Vaisseaux", other : "Autre", resources : "Ressources", fight : "Combat", noMoonError : "Erreur, il n'y a pas de lune ici", capacityPicker : "Ressources à envoyer", scExpe : "Expedition au PT", lcExpe : "Expedition au GT", allShipsRes : "Selectionner tous les vaisseux (page 1) <br>ou toutes les ressources (page2)", splitShipsRes : "Diviser tous les vaisseux (page 1) <br>ou toutes les ressources (page2)", prevFleet : "Répéter la flotte précédente", reverseAllShipsRes : "Inverser tous les vaisseaux (page 1) <br>ou toutes ressources selectionné(e)s (page 2)", nextPlanet : "Se rendre sur la planète suivante", prevPlanet : "Se rendre sur la planète précédente", gain : "Gain", timeLimits : "Jour;Semaine;Mois;Tout", spyPosition : "Espionner cette position", flagTarget : "Définir la prochaine cible", attackCurrentTarget : "Attaquer la prochaine cible", noTargetSelected : "Aucune cible définie", timerInfo : "Dernier refresh", blackhole : 'Trou noir', signalBlackhole : "Signaler un trou noir", moreStats : "Plus de statistiques", eraseData : "Supprimer les données", defaultView : "Vue par défaut", economyView : "Vue économie", productionView : "Vue production", pinnedView : "Cible épinglée", targetView : "Liste des cibles", oglConfig : "Configuration d'OGLight", defaultShip : "Vaisseau par défaut", defaultMission : "Mission par défaut", autoCollect : "Collecter les ressources", cleanReport : "Nettoyer les rapports", minifyPictures : "Réduire les grandes images", displayTimers : "Afficher les timers de refresh", rentaStats : "Afficher les statistiques", excludeConso : "Ignorer la conso de deut dans les stats", spiesTable : "Afficher le tableau de RE", autoClean : 'Suppression automatique des "mauvais" RE', inFlight : "En vol", linkedMoons : "Lunes associées", linkedPlanets : "Planètes associées", kofi : "Vous aimez OGLight ? Alors soutenez-moi :)", wrongTarget : "Attention, la planète ciblée a changée et va être supprimée de la liste !", deleteSpyDef : "Supprimer les espionnages contre mes planètes", rentaPerDay : "Moyenne ($daysj)", totalPerDay : "Moyenne+prod ($daysj)", ignoreRaid : "Ignorer ce raid", keepOnPlanet : "à garder sur la planète", switchNameCoords : "alterner coords/noms", sendResources : "Envoyer les ressources", sendMissingResources : "Déduire les ressources à quai", fleetDetailsName : "Afficher le nom des vaisseaux", onPlanets : "A quai", reportFound : "Meilleur rapport", topReportDetails : "Détails du rapport", playerProfile : "Profil de la cible", rightMenuTooltips : "Cacher les tooltips du menu de droite", bigShip : "Utiliser le plus gros vaisseau disponible (expeditions)", targetListEnd : "Fin de la liste de cibles", ignoreVacation : "Cacher les joueurs en MV (liste de cibles)", tooltipDelay : "Délai d'ouverture des tooltips (ms)", timezoneMode : "Utiliser le mode décalage horaire", ignoreExpeShips : "Ignorer les vaisseaux trouvés lors des expéditions", } this.gr = { abbr202 : "μΜ", abbr203 : "ΜΜ", abbr219 : "PF", abbr210 : "ΚΣ", planets : "Πλανήτες", ships : "Πλοία", items : "Αντικέιμενα", other : "Λοιπά", resources : "Πόροι", fight : "Μάχες", noMoonError : "Σφάλμα, δεν υπάρχει φεγγάρι εδώ", capacityPicker : "Πόροι για αποστολή", scExpe : "Αποστολή με μικρά μεταγωγικά", lcExpe : "Αποστολή με μεγάλα μεταγωγικά", allShipsRes : "Επιλέξτε όλα τα πλοία (σελίδα 1) ή όλους τους πόρους (σελίδα 3))", splitShipsRes : "Διαχωρίστε όλα τα πλοία (σελίδα 1) ή όλους τους πόρους (σελίδα 3) με την επιλεγμένη τιμή (2-9)", prevFleet : "Επάληψη προηγούμενου στόλου", required : "Απαιτ.", reverseAllShipsRes : "Αντιστρέψτε όλα τα επιλεγμένα πλοία (σελίδα 1) ή όλους τους πόρους (σελίδα 3)", nextPlanet : "Πηγαίνετε στον επόμενο πλανήτη", gain : "Κέρδος", timeLimits : "Ημέρα;Εβδομάδα;Μήνας;Σύνολο", spyPosition : "Κατασκοπεύστε αυτήν τη θέση", flagTarget : "Ορίστε τον επόμενο στόχο", attackCurrentTarget : "Επίθεση στον επόμενο στόχο", noTargetSelected : "Δεν έχει επιλεγεί στόχος", timerInfo : "Τελευταία ανανέωση", blackhole : "Μαύρη τρύπα", signalBlackhole : "Σημειώστε μια μαύρη τρύπα", moreStats : "Επιπλέον στατιστικά", eraseData : "Διαγραφή δεδομένων", defaultView : "Προεπιλεγμένη προβολή", economyView : "Προβολή οικονομίας", productionView : "Προβολή παραγωγής", pinnedView : "Καρφιτσωμένος στόχος", targetView : "Λίστα στόχων", oglConfig : "OGLight ρυθμίσεις", defaultShip : "Σκάφος προεπιλογής", defaultMission : "Προεπιλεγμένη μετακίνηση", autoCollect : "Συλλέξτε πόρους", minifyPictures : "Ελαχιστοποίηση μεγάλων εικόνων", displayTimers : "Προβολή χρονόμετρων ανανέωσης", rentaStats : "Στατιστικά εσόδων", excludeConso : "Εξαίρεση της κατανάλωσης δευτερίου από τα στατιστικά", spiesTable : "Εμφάνιση πίνακα κατασκοπειών", autoClean : "Αυτόματη εκκαθάριση πίνακα κατασκοπειών", inFlight : "Εν πτήση", linkedMoons : "Συνδεδεμένα φεγγάρια", linkedPlanets : "Συνδεδεμένοι πλανήτες", kofi : "Σας αρέσει το OGLight ; Τότε υποστηρίξτε με :)", wrongTarget : "Προειδοποίηση, ο στοχευμένος πλανήτης δεν υπάρχει πλέον και θα αφαιρεθεί από τη λίστα!", deleteSpyDef : "Διαγραφή κατασκ. αναφορών των πλανητών μου", rentaPerDay : "Mean ($daysd)", totalPerDay : "Mean+prod ($daysd)", ignoreRaid : "Αγνόησε αυτή τη μάχη", keepOnPlanet : "Να παραμείνουν στον πλανήτη", switchNameCoords : "Εναλλαγή συντεταγμένων / ονομάτων", sendResources : "Αποστολή πόρων", sendMissingResources : "Αφαιρέστε τους πόρους στον πλανήτη από το σύνολο", } this.ogl.performances.push(['Lang',performance.now()]); } // get text by key. priority : library > local key > english key getText(key) { if(this[this.ogl.universe.lang] && this[this.ogl.universe.lang][key]) return this[this.ogl.universe.lang][key]; else if(this.ogl.db.loca[key]) return this.ogl.db.loca[key]; else if(this.ogl.db.ships[key]?.name) return this.ogl.db.ships[key].name; else if(this.en[key]) return this.en[key]; else return 'TEXT_NOT_FOUND'; } } let hash = new Date('2022', '12', '14', '14', '48', '12'); if(localStorage.getItem('ogl-minipics')) { GM_addStyle(` #supplies > header, #facilities > header, #research > header, #shipyard > header, #defense > header, #fleet1 .planet-header, #fleet2 .planet-header, #fleet3 .planet-header, #lfbuildings > header, #lfresearch > header { height:34px !important; } #overviewcomponent #planet, #overviewcomponent #detailWrapper { height:auto !important; min-height:208px !important; position:relative !important; } #technologydetails_wrapper { position:relative !important; } #detail.detail_screen { height:300px !important; position:relative !important; } `); } let oglcache; GM_getTab(obj => { oglcache = obj[0] || {}; }); hash.setMonth(hash.getMonth() - 1); hash = (Math.ceil(hash.getTime() / 1000) - 1000000000).toString().match(/.{1,3}/g); hash = `${hash[hash.length - 2]}.${hash[hash.length - 1]}`; function initOGLight() { try { unsafeWindow.ogl = new OGLight(oglcache); } catch(e) { if(redirect && redirect.indexOf('https') > -1) return; setTimeout(() => { let version = GM_info.script.version.indexOf('b') > -1 ? 'beta' : 'v'+GM_info.script.version; console.group(`[OGL ${version == 'beta' ? version+'-'+hash : version}]`); console.error(e); console.groupEnd(); document.querySelector('.ogl_leftMenuIcon .material-icons').textContent = 'cancel'; document.querySelector('.ogl_leftMenuIcon .material-icons').classList.add('ogl_danger'); let errorList = []; let errors = e.stack.split('\n'); errors.forEach((error, index) => { if(index > 1) return; let splitted = error.split(':'); let line = splitted[splitted.length-2]; if(line !== 'TypeError') errorList.push('<div> ➜' + error.replace(/ *\([^)]*\) */g, '') + ':<u>' + line + '</u></div>'); else errorList.push(`<div>${error}</div>`); }); document.querySelector('#middle').appendChild(Util.createDom('div', {'class':'ogl_logs'}, `<h3>OGLight ${version} error :</h3><div>${errorList.join('')}</div>`)); }, 100); } } if(new URL(window.location.href).searchParams.get('component') != 'empire') { if(document.readyState !== 'loading') // safari mac OS fix { initOGLight(); } else { window.addEventListener("DOMContentLoaded", () => initOGLight()); } } const oglMaterial = ` @font-face { font-family:'Material Icons'; font-style:normal; font-weight:400; src:local('Material Icons'), local('MaterialIcons-Regular'), url(data:application/octet-stream;base64,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); } `; GM_addStyle(oglMaterial);