// ==UserScript==
// @name Grepolis tripjes detector
// @version 2025-01-26
// @description Laat op het profiel van een speler of op het eiland scherm zien welke steden wel/geen trip hebben
// @author archdukeDaan
// @match https://*.grepolis.com/*
// @license MIT
// @namespace https://tampermonkey.net/
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function() {
'use strict';
// maak een wrapper function over de createTownDiv function
// voordat een stad wordt gemaakt op de kaart, run eerst mijn functie en dan pas de grepo functie
var wrapper = function(originalFunc) {
return function() {
var wrapper = originalFunc.apply(this, arguments);
return generateTripjesOpKaart(wrapper, arguments);
};
};
MapTiles.createTownDiv = wrapper(MapTiles.createTownDiv);
function laadSettings(){
var settings = {
'archduke_menu_auto_trip_kaart': GM_getValue('archduke_menu_auto_trip_kaart'),
'archduke_menu_auto_trip_eiland': GM_getValue('archduke_menu_auto_trip_eiland'),
'archduke_menu_auto_trip_profiel': GM_getValue('archduke_menu_auto_trip_profiel'),
"archduke_menu_trip_allianties" : GM_getValue('archduke_menu_trip_allianties'),
"archduke_menu_trip_eigen_stad" : GM_getValue('archduke_menu_trip_eigen_stad'),
}
return settings
}
// timer om de menu knop te maken
setTimeout(function check() {
maakMenuKnop()
}, 5000);
// timer om te checken of de knop moet worden geplaatst
// er kan maar maximaal 1 profiel tegelijk open staan
setTimeout(function checkProfielWindowOpen() {
if (document.getElementById("player_towns") != null) {
if (document.getElementById("tripknopProfiel") == null){
addTripKnop('profiel')
}
}
setTimeout(checkProfielWindowOpen, 500);
}, 500);
// timer om te checken of de knop moet worden geplaatst
// er kunnen meerdere eilanden vensters tegelijk open staan
setTimeout(function checkEilandWindowOpen() {
if (document.getElementsByClassName("island_info_wrapper") != null) {
// verkrijg alle openstaande eiland vensters
var vensters = getAllOpenEilandVensters()
for(let i=0;i<vensters.length;i++){
var venster = vensters[i]
// check of dit eiland venster al een knop heeft
if (venster.querySelector("#tripknopEiland") == null){
addTripKnop('eiland',venster)
}
}
}
setTimeout(checkEilandWindowOpen, 500);
}, 500);
function addTripKnop(knop_type,venster) {
var button = document.createElement('span');
button.textContent = 'Tripjes';
button.style.zIndex = 1000;
button.style.width = '50px'
button.style.padding = '4px';
button.style.marginTop = '4px'
button.style.marginBottom = '4px'
button.style.color = 'white';
button.style.border = '1px solid black';
button.style.borderRadius = '5px';
button.style.cursor = 'pointer';
button.style.marginLeft = '15px';
if (knop_type == 'profiel'){
button.addEventListener('click', function(){
generateTripjesOpProfiel();
}, false);
button.setAttribute('id', 'tripknopProfiel');
// voeg de knop als tweede element toe aan de game_header van de stedenlijst op het profiel
var profiel = document.getElementById("player_towns")
var element = profiel.children[0].querySelector('.game_header');
element.insertBefore(button,element.children[0]);
var instelling = GM_getValue('archduke_menu_auto_trip_profiel')
if (instelling == true){
button.click()
}
} else if (knop_type == 'eiland'){
button.addEventListener('click', function(){
generateTripjesOpEiland(venster);
}, false);
button.setAttribute('id', `tripknopEiland`);
button.style.backgroundColor = 'blue';
var eiland_controls = venster.querySelector("#island_towns_controls")
eiland_controls.appendChild(button)
var instelling = GM_getValue('archduke_menu_auto_trip_eiland')
if (instelling == true){
button.click()
}
}
console.log("Trip knop toegevoegd!")
}
function getHuidigeSpeler(){
var playerObj = MM.getModels().Player
var player = Object.values(playerObj)[0].attributes;
var huidigeSpeler = player.name
return huidigeSpeler
}
function getTripLijst(){
// verkrijg alle tripjes en stop ze in een lijst
const steden_met_troepen_buiten = ITowns.all_supporting_units.fragments
var triplijst = []
Object.values(steden_met_troepen_buiten).forEach((stad) => {
var tripjes = stad.models
tripjes.forEach((trip) => {
var trip_info = trip.attributes
var stad_naam = trip_info.current_town_name
var stad_speler = trip_info.current_town_player_name
var stad_id = trip_info.current_town_id
//var trip_stad_herkomst = trip_info.home_town_name
var row = {"stad_naam":stad_naam,"stad_speler":stad_speler,"stad_id":stad_id}
triplijst.push( row )
});
});
//console.log(triplijst)
return triplijst
}
function getProfileName(){
// verkrijg speler naam van het huidige profiel dat open staat
var profiel = document.getElementById("player_info").children
var naam = ""
for(let i=0;i<profiel.length;i++){
var el = profiel[i]
if (el.tagName == "H3"){
naam = el.innerHTML
break
}
}
return naam
}
function getStedenLijstOpProfiel(){
// verkrijg stedenlijst dom element van een speler zn profiel
var profiel_steden = document.getElementById("player_towns").children[0].children
var steden = false
for(let i=0;i<profiel_steden.length;i++){
var el2 = profiel_steden[i]
if (el2.tagName == "UL"){
steden = el2.children
break
}
}
//console.log(steden)
return steden
}
function getStedenLijstOpEiland(venster){
// verkrijg stedenlijst dom element van een eiland
var eiland_steden = venster.querySelector("#island_info_towns_left_sorted_by_name").children
//console.log(steden)
return eiland_steden
}
function getAlliantieFromLink(stad_obj){
// verkrijg de alliantie van de eigenaar van een stad vanuit de GP link DOM element
// als speler geen alliantie heeft, return -1
if (stad_obj.querySelector('.gp_alliance_link') != null){
var link_as_str = stad_obj.querySelector('.gp_alliance_link').outerHTML;
var alliantie = link_as_str.split("Layout.allianceProfile.open")[1].split(",")[1].split(")")[0]
return alliantie
} else {
return -1
}
}
function getAllOpenEilandVensters(){
var vensters = document.getElementsByClassName("island_info_wrapper")
return vensters
}
function generateTripjesOpEiland(venster){
// indien van toepassing, verwijder de oude tags op het eiland informatie scherm
venster.querySelector("#island_info_towns_left_sorted_by_name").querySelectorAll('.tripTag').forEach(e => e.remove());
// verkrijg stedenlijst op het eiland
var steden = getStedenLijstOpEiland(venster)
// verkrijg de triplijst
var triplijst = getTripLijst()
// loop over de steden en voeg tag 'geen trip' toe als de stadsnaam niet in triplijst staat
for (let k=0; k < steden.length; k++){
var stad_obj = steden[k]
var stad_naam = stad_obj.querySelector(".gp_town_link").innerHTML;
var stad_eigenaar_dom = stad_obj.querySelector(".gp_player_link")
var stad_eigenaar = "Spookstad"
if (stad_eigenaar_dom != null){
stad_eigenaar = stad_eigenaar_dom.innerHTML;
}
var stad_alliantie = getAlliantieFromLink(stad_obj);
// plaats geen tag als de stad van de huidige speler is
// plaats geen tag als de alliantie van de eigenaar van de stad niet in de alliantie lijst staat
var allianties = GM_getValue("archduke_menu_trip_allianties")
if ( allianties.contains(stad_alliantie) == true ){
var settings = GM_getValue("archduke_menu_trip_eigen_stad")
if (settings == false){
if (stad_eigenaar == getHuidigeSpeler()){
return
}
}
var tag = document.createElement('div');
tag.style.zIndex = 1000;
tag.style.cursor = 'pointer';
tag.setAttribute('class','tripTag')
tag.style.fontWeight = 'bold';
tag.style.marginLeft = '10px';
// kijk of er een trip in de stad ligt
var j = triplijst.findIndex( e => (e.stad_naam == stad_naam) && (e.stad_speler == stad_eigenaar) )
if (j>-1){
tag.textContent = "Wel trip";
tag.style.color = 'green'
} else {
tag.textContent = "Geen trip";
tag.style.color = 'red'
}
// voeg de tag toe aan de DOM
steden[k].appendChild(tag);
}
}
}
function generateTripjesOpProfiel(){
// indien van toepassing, verwijder de oude tags op het profiel
document.getElementById("player_towns").querySelectorAll('.tripTag').forEach(e => e.remove());
// verkrijg naam op het profiel
var naam = getProfileName()
// verkrijg de triplijst
var triplijst = getTripLijst()
// verkrijg stedenlijst op het profiel
var steden = getStedenLijstOpProfiel()
// loop over de steden en voeg tag 'geen trip' of 'wel trip' toe
for (let k=0; k < steden.length; k++){
var stad = steden[k].children[1]
var stad_naam = stad.innerHTML
var tag = document.createElement('span');
tag.style.zIndex = 1000;
tag.style.cursor = 'pointer';
tag.setAttribute('class','tripTag')
tag.style.fontWeight = 'bold';
// kijk of er een trip in de stad ligt
var j = triplijst.findIndex( e => (e.stad_naam == stad_naam) & (e.stad_speler == naam) )
if (j>-1){
tag.textContent = "Wel trip";
tag.style.color = 'green'
} else {
tag.textContent = "Geen trip";
tag.style.color = 'red'
}
// voeg de tag toe aan de DOM
steden[k].appendChild(tag)
}
}
function generateTripjesOpKaart(originalFunc, args){
var stad = args[0]
//console.log(stad)
// check of stad een speler heeft, dus of het geen spookstad is
if(stad.player_id != null){
// createTownDiv 2 keer geroepen per stad, eens voor de stad en eens voor de stad vlag
for (let i=0;i<originalFunc.length;i++){
// maak tag alleen op de stadsvlag ivm dubbele tags per stad
var dom_element = originalFunc[i]
var class_list = dom_element.classList
//console.log(class_list)
if (class_list.contains("flag")){
// verkrijg de triplijst
var triplijst = getTripLijst()
var stad_id = stad.id
var stad_alliantie = stad.alliance_id
var stad_eigenaar = stad.player_name
var allianties = GM_getValue("archduke_menu_trip_allianties")
var eigen_stad = GM_getValue("archduke_menu_trip_eigen_stad")
if ((allianties.contains(stad_alliantie) == true)){
if(eigen_stad == false){
if(stad_eigenaar == getHuidigeSpeler()){
return originalFunc
}
}
// tag
var tag = document.createElement('div');
tag.style.zIndex = 1000;
tag.style.cursor = 'pointer';
tag.setAttribute('class','tripTag')
tag.style.fontWeight = 'bold';
tag.style.width = '15px';
tag.style.height = '15px';
tag.style.borderRadius = '50%'
tag.style.position = 'relative';
tag.style.top = "60%";
tag.style.left = "70%";
tag.style.border = '2px solid black'
// kijk of er een trip in de stad ligt
var j = triplijst.findIndex( e => (e.stad_id == stad_id) )
if (j>-1){
tag.style.backgroundColor = 'green'
} else {
tag.style.backgroundColor = 'red'
}
$(originalFunc[i]).append(tag);
}
}
}
}
return originalFunc
}
function maakMenuKnop(){
var knop = document.createElement("div")
knop.style.width = '60px'
knop.setAttribute("id","archduke_menu")
knop.style.height = '30px'
knop.style.position = 'absolute'
knop.style.bottom = '100px'
knop.style.backgroundColor = 'red'
knop.style.borderRadius = '10px'
knop.style.left = 0
knop.style.cursor = 'pointer'
knop.style.zIndex = '10001'
knop.innerHTML = 'Archduke Menu'
knop.addEventListener('click', maakMenu)
document.body.appendChild(knop)
}
function maakMenu(){
var menuTitel = 'Archduke Menu'
var titel_dom = null
// check of er al een menu window open staat
var find = false;
for(let i of document.getElementsByClassName('ui-dialog-title')){
if(i.innerHTML == menuTitel){
find = true;
titel_dom = i
}
}
// maak nieuwe window indien nodig
if(find == false){
var window = Layout.wnd.Create(Layout.wnd.TYPE_DIALOG, "Archduke Menu");
// zet window size
window.setHeight(document.body.scrollHeight/2);
window.setWidth('800');
window.setContent(''); // clear window
for(let i of document.getElementsByClassName('ui-dialog-title')){
if(i.innerHTML == menuTitel){
titel_dom = i;
}
}
}
// maak mini pagina om in de frame te zetten
var frame = titel_dom.parentElement.parentElement.children[1].children[4];
frame.innerHTML = '';
// maak menu voor module selectie aan de linker kant
var container_left = document.createElement("div")
container_left.setAttribute("id","archduke_menu_left")
container_left.setAttribute("class",'settings-menu')
frame.appendChild(container_left)
var ul = document.createElement("ul")
// maak module selectors
var el = document.createElement("b")
el.innerHTML = 'Scripts'
container_left.append(el)
var el = maakModuleSelector('Trip Detector')
ul.append(el)
var el = maakModuleSelector('Placeholder naam')
ul.append(el)
var el = maakModuleSelector('Placeholder naam')
ul.append(el)
container_left.appendChild(ul)
// maak instellingen voor module aan de rechter kant
var container_right = document.createElement("div")
container_right.setAttribute("id","archduke_menu_right")
container_right.setAttribute("class",'settings-container')
frame.appendChild(container_right)
// maak module instellingen
var el = maakTripInstellingen()
container_right.appendChild(el)
// check settings in de local storage
var settings = laadSettings()
if (settings.archduke_menu_auto_trip_eiland){ document.getElementById("archduke_menu_auto_trip_eiland").classList.add('checked') }
if (settings.archduke_menu_auto_trip_kaart){ document.getElementById("archduke_menu_auto_trip_kaart").classList.add('checked') }
if (settings.archduke_menu_auto_trip_profiel){ document.getElementById("archduke_menu_auto_trip_profiel").classList.add('checked') }
if (settings.archduke_menu_trip_eigen_stad){ document.getElementById("archduke_menu_trip_eigen_stad").classList.add('checked') }
for (let i=0; i < settings.archduke_menu_trip_allianties.length;i++){
var ally_id = settings.archduke_menu_trip_allianties[i]
addRowToMenuList(document.getElementById('archduke_menu_alliantie_list'),ally_id)
}
}
function maakModuleSelector(naam){
var el = document.createElement("li")
el.style.marginBottom = '10px'
var a = document.createElement('a')
a.innerHTML = naam
a.setAttribute("class","settings-link")
el.appendChild(a)
return el
}
function maakTripInstellingen(){
// maak container
var el = document.createElement("div")
el.setAttribute('id',"archduke_menu_instellingen")
var form = document.createElement("form")
el.appendChild(form)
// maak section
var section = createSection('Voorkeuren')
form.appendChild(section)
// maak groep waar alle knopjes in komen
var group = createGroup("Bepaal het gedrag van de tripjes detector door de checkboxen aan te vinken.")
// maak alle knopjes
var auto_weergeef_kaart = createCheckBox("Weergeef automatisch de trip tags op de kaart", 'auto_trip_kaart')
var auto_weergeef_eiland = createCheckBox("Weergeef automatisch de trip tags op het eiland scherm",'auto_trip_eiland')
var auto_weergeef_profiel = createCheckBox("Weergeef automatisch de trip tags op het profiel van een speler",'auto_trip_profiel')
var auto_weergeef_eigen_stad = createCheckBox("Weergeef trip tags bij je eigen steden",'trip_eigen_stad')
// opslaan knop
var btn = createKnop("Opslaan",saveInstellingen)
// voeg alles toe aan de section
group.appendChild(auto_weergeef_kaart)
group.appendChild(auto_weergeef_eiland)
group.appendChild(auto_weergeef_profiel)
group.appendChild(auto_weergeef_eigen_stad)
group.appendChild(document.createElement("br"))
group.appendChild(btn)
section.append(group)
// maak inner box
var box = createInnerBox("Alleen voor onderstaande allianties zullen trip tags worden getoond.",'input_ally_id','Alliantie ID', 'Opslaan',"archduke_menu_alliantie_list",saveInstellingenAllianties)
group.appendChild(box)
// maak inner box
//var box = createInnerBox("Onderstaande spelers zullen geen trip tags krijgen",'input_player_id','Spelernaam', 'Opslaan',"archduke_menu_player_list",null)
//group.appendChild(box)
return el
}
function createSection(sectie_naam){
var section = document.createElement("div")
section.setAttribute("class",'section')
section.style.display = 'block'
var section_titel = document.createElement("div")
section_titel.innerHTML = sectie_naam
section_titel.setAttribute("class",'game_header bold')
section.appendChild(section_titel)
return section
}
function createGroup(beschrijving){
var group = document.createElement("div")
group.setAttribute("class",'group')
var group_text = document.createElement("p")
group_text.innerHTML = beschrijving
group.appendChild(group_text)
return group
}
function createCheckBox(beschrijving, id){
var el = document.createElement("div")
el.setAttribute('class',"checkbox_new large archduke_menu_checkbox")
el.setAttribute('id', `archduke_menu_${id}`)
var btn = document.createElement("div")
btn.setAttribute("class","cbx_icon")
el.appendChild(btn)
var text = document.createElement("div")
text.setAttribute("class","cbx_caption")
text.innerHTML = beschrijving
el.appendChild(text)
el.addEventListener('click', function(){
this.classList.toggle('checked')
})
return el
}
function createKnop(text, f){
var el = document.createElement("div")
el.setAttribute("class",'button_new')
var el2 = document.createElement("div")
el2.setAttribute("class",'left')
var el3 = document.createElement("div")
el3.setAttribute("class",'right')
var btn = document.createElement("div")
btn.setAttribute("class",'caption js-caption')
var btn_txt = document.createElement("span")
btn_txt.innerHTML = text
var btn_ef = document.createElement("div")
btn_ef.setAttribute('class',"effect js-effect")
el.appendChild(el2)
el.appendChild(el3)
btn.appendChild(btn_txt)
btn.appendChild(btn_ef)
el.appendChild(btn)
btn.addEventListener('click', f)
return el
}
function saveInstellingen(){
var checkboxen = document.body.querySelectorAll(".archduke_menu_checkbox")
for (let i=0;i<checkboxen.length;i++){
var box = checkboxen[i]
var id = box.id
var checked = false
if (box.classList.contains('checked')){
checked = true
}
GM_setValue(id,checked)
}
}
function saveInstellingenAllianties(){
var entries = document.body.querySelectorAll(".archduke_menu_trip_alliantie")
var allianties = []
for (let i=0;i<entries.length;i++){
var ally = entries[i]
var ally_id = ally.id.substring(24)
allianties.push(ally_id)
}
GM_setValue("archduke_menu_trip_allianties",allianties)
}
function addRowToMenuList(parent,txt){
var li = document.createElement("li")
li.style.listStyleType = 'square'
li.setAttribute("class",`archduke_menu_trip_alliantie`)
li.setAttribute('id',`archduke_menu_alliantie_${txt}`)
var a = document.createElement("a")
a.innerHTML = txt
li.appendChild(a)
var a = document.createElement("a")
a.setAttribute("class",'cancel')
a.addEventListener('click', function(){
li.remove()
saveInstellingenAllianties()
})
li.appendChild(a)
parent.appendChild(li)
}
function createInnerBox(box_title, input_id, label_text ,button_text, ul_list_id, f){
var el = document.createElement("div")
el.setAttribute("class",'game_inner_box')
el.style.marginTop = '20px'
var child = document.createElement('div')
child.setAttribute('class',"game_border")
el.appendChild(child)
var e = document.createElement('div')
e.setAttribute('class',"game_border_top")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_bottom")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_left")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_right")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_corner corner1")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_corner corner2")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_corner corner3")
child.appendChild(e)
var e = document.createElement('div')
e.setAttribute('class',"game_border_corner corner4")
child.appendChild(e)
var title = document.createElement('div')
title.setAttribute('class',"game_header bold")
title.style.margin = '5px 0 5px 0'
title.innerHTML = box_title
child.appendChild(title)
var list = document.createElement("div")
var list_ul = document.createElement("ul")
list_ul.setAttribute('id',ul_list_id)
list_ul.setAttribute("class",'game_list')
list_ul.style.listStyle = 'disc'
list_ul.style.width = '490px'
list_ul.style.margin = '5px 0px 15px 35px'
list.appendChild(list_ul)
child.appendChild(list)
var list_text = document.createElement('div')
list_text.style.float = 'left'
child.appendChild(list_text)
var label = document.createElement("label")
label.setAttribute("class","bold")
label.style.marginLeft = '5px'
label.innerHTML = label_text+" : "
list_text.appendChild(label)
var span = document.createElement("span")
span.setAttribute("class","grepo_input")
list_text.appendChild(span)
var span_left = document.createElement("span")
span_left.setAttribute("class","left")
span.appendChild(span_left)
var span_right = document.createElement("span")
span_right.setAttribute("class","right")
span_left.appendChild(span_right)
var input = document.createElement("input")
input.setAttribute("class", 'ac_input')
input.setAttribute("id",input_id)
input.type = 'text'
input.value = ''
input.autocomplete = 'off'
span_right.appendChild(input)
var btn = createKnop(button_text)
child.appendChild(btn)
btn.addEventListener('click', function(){
var input_txt = document.getElementById(input_id).value
if (input_txt != ""){
document.getElementById(input_id).value = ''
addRowToMenuList(list_ul,input_txt)
f()
}
})
return el
}
})();