Register for your free account! | Forgot your password?

Go Back   elitepvpers > General Gaming > Early Access Games
You last visited: Today at 16:58

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Fellowship Dungeon Tools Overlay via METHOD

Discussion on Fellowship Dungeon Tools Overlay via METHOD within the Early Access Games forum part of the General Gaming category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jan 2014
Posts: 5
Received Thanks: 0
Wink Fellowship Dungeon Tools Overlay via METHOD

Hi zusammen, ich bin schon lange ein Member hier, habe aber nie etwas gemacht. Da ich derzeit fleißig Fellowship zocke, wollte ich mein kleines Tool teilen.

Ich hab mal ein Dungeon Tool Overlay gemacht in Python, welcher mit der Method Seite kommuniziert und es ermöglicht die Routen über das Game zu legen.

[Overlay] Hotkeys aktiv:
F8 → Seite auf Deutsch übersetzen
F9 → Beenden
F10 → Klickdurchlässigkeit umschalten
F11 → Transparenz erhöhen/verringern
Oben in der Leiste → steht immer der Dungeon Name und dort kann man sich kompakte Informationen holen zu den Dungeon und Bossen in Deutsch, sobald man die Seite zu dem Dungeon geladen hat.
Dazu hatte ich HTML-Dateien erstellt.

Das braucht PYTHON damit der Code funktioniert:
Code:
pip install PyQt5 PyQtWebEngine keyboard
Source Code:
Code:
import sys
import threading
import ctypes
import os
import re
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton
from PyQt5.QtWebEngineWidgets import QWebEngineView
import keyboard


class GameOverlay(QMainWindow):
    def __init__(self, url):
        super().__init__()

        # --- Fenster-Konfiguration ---
        self.setWindowTitle("Overlay Browser")
        self.setGeometry(300, 200, 1000, 800)
        self.setWindowOpacity(1)
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Window)

        # Zustände
        self.click_through = False
        self.opacity = 1
        self.scroll_offset = 388
        self.current_dungeon_name = ""

        # --- Webansicht ---
        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl(url))
        self.browser.setZoomFactor(1.0)
        self.browser.loadFinished.connect(self.scroll_to_position)
        self.browser.urlChanged.connect(self.update_info_button_text)

        # --- Info-Button (volle Breite) ---
        self.info_button = QPushButton()
        self.info_button.setFixedHeight(40)
        self.info_button.setStyleSheet("""
            QPushButton {
                background-color: rgba(40, 40, 40, 160);
                color: white;
                border: none;
                font-size: 18px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: rgba(70, 70, 70, 200);
            }
        """)
        self.info_button.clicked.connect(self.show_info_window)

        # --- Layouts ---
        layout = QVBoxLayout()
        layout.addWidget(self.info_button)
        layout.addWidget(self.browser)
        layout.setContentsMargins(0, 0, 0, 0)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.show()
        self.update_info_button_text()  # Initial setzen

        # Windows Handle
        self.hwnd = int(self.winId())
        self.make_clickable(self.hwnd)

        # Globaler Hotkey-Thread starten
        threading.Thread(target=self.hotkey_listener, daemon=True).start()

    # ---------------------------------------------
    # �� Globale Hotkeys
    # ---------------------------------------------
    def hotkey_listener(self):
        print("[Overlay] Hotkeys aktiv:")
        print("F8 → Seite auf Deutsch übersetzen")
        print("F9 → Beenden")
        print("F10 → Klickdurchlässigkeit umschalten")
        print("F11 → Transparenz erhöhen/verringern")

        keyboard.add_hotkey("f8", self.translate_to_german)
        keyboard.add_hotkey("f9", self.close_overlay)
        keyboard.add_hotkey("f10", self.toggle_clickthrough)
        keyboard.add_hotkey("f11", self.adjust_opacity)

        keyboard.wait("f9")

    # ---------------------------------------------
    # �� Übersetzen (F8)
    # ---------------------------------------------
    def translate_to_german(self):
        """Lädt Google Translate Overlay."""
        print("[Overlay] Übersetze Seite auf Deutsch ...")
        js_code = """
        if (!window.__googleTranslateLoaded) {
            var gt = document.createElement('script');
            gt.src = '//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
            document.body.appendChild(gt);

            window.googleTranslateElementInit = function() {
                new google.translate.TranslateElement({pageLanguage: 'en', includedLanguages: 'de'}, 'google_translate_element');
            };

            var div = document.createElement('div');
            div.id = 'google_translate_element';
            div.style.position = 'fixed';
            div.style.top = '10px';
            div.style.right = '10px';
            div.style.zIndex = '9999';
            div.style.background = 'rgba(0,0,0,0.4)';
            div.style.padding = '5px';
            document.body.appendChild(div);

            window.__googleTranslateLoaded = true;
        }
        """
        self.browser.page().runJavaScript(js_code)

    # ---------------------------------------------
    # �� Info-Button-Funktion
    # ---------------------------------------------
    def show_info_window(self):
        """Öffnet Info-Fenster für den aktuellen Dungeon."""
        if not self.current_dungeon_name:
            print("[Overlay] Kein Dungeon erkannt.")
            return

        def _norm(s: str) -> str:
            return re.sub(r'[^a-z0-9]+', '', s.lower())

        script_dir = os.path.dirname(os.path.abspath(__file__))
        info_folder = os.path.join(script_dir, "Information")
        if not os.path.isdir(info_folder):
            print(f"[Overlay] Ordner 'Information' nicht gefunden: {info_folder}")
            return

        page_key = _norm(self.current_dungeon_name)
        candidates = [f for f in os.listdir(info_folder) if f.lower().endswith(".html")]
        norm_map = {_norm(os.path.splitext(f)[0]): f for f in candidates}

        if page_key in norm_map:
            file_name = norm_map[page_key]
            file_path = os.path.join(info_folder, file_name)
            print(f"[Overlay] Öffne Info-Datei: {file_path}")

            info_window = QMainWindow(self)
            info_window.setWindowTitle(f"Information - {file_name}")
            info_window.setGeometry(self.geometry())

            info_browser = QWebEngineView()
            info_browser.setUrl(QUrl.fromLocalFile(file_path))
            info_window.setCentralWidget(info_browser)

            # --- Scrollt 660 Pixel runter nach dem Laden ---
            def _scroll():
                info_browser.page().runJavaScript("window.scrollTo(0, 880);")
                print("[Overlay] Info-Seite 880px nach unten gescrollt.")
            info_browser.loadFinished.connect(_scroll)

            info_window.show()
        else:
            print("[Overlay] Keine passende Info-Datei gefunden.")

    # ---------------------------------------------
    # �� Info-Button-Text aktualisieren
    # ---------------------------------------------
    def update_info_button_text(self):
        """Setzt den Button-Text passend zur aktuellen URL."""
        current_url = self.browser.url().toString()
        parts = [p for p in current_url.rstrip("/").split("/") if p]
        dungeon_name = parts[-1] if len(parts) > 0 else "unbekannt"
        dungeon_display = dungeon_name.replace("-", " ").replace("_", " ").title()
        self.current_dungeon_name = dungeon_name
        self.info_button.setText(f"ℹ️nformationen über {dungeon_display}")

    # ---------------------------------------------
    # �� Klickdurchlässigkeit
    # ---------------------------------------------
    def make_clickthrough(self, hwnd):
        GWL_EXSTYLE = -20
        WS_EX_TRANSPARENT = 0x00000020
        WS_EX_LAYERED = 0x00080000
        style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
        ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, style | WS_EX_TRANSPARENT | WS_EX_LAYERED)

    def make_clickable(self, hwnd):
        GWL_EXSTYLE = -20
        WS_EX_LAYERED = 0x00080000
        style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
        ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, (style & ~0x00000020) | WS_EX_LAYERED)

    def toggle_clickthrough(self):
        self.click_through = not self.click_through
        if self.click_through:
            self.make_clickthrough(self.hwnd)
            print("[Overlay] Klick-durchlässig aktiviert")
        else:
            self.make_clickable(self.hwnd)
            print("[Overlay] Overlay ist jetzt interaktiv")

    # ---------------------------------------------
    # ��️ Transparenz
    # ---------------------------------------------
    def adjust_opacity(self):
        if self.opacity > 0.5:
            self.opacity -= 0.1
        else:
            self.opacity = 1
        self.setWindowOpacity(self.opacity)
        print(f"[Overlay] Transparenz: {self.opacity:.1f}")

    # ---------------------------------------------
    # �� Automatisches Scrollen
    # ---------------------------------------------
    def scroll_to_position(self):
        js_code = f"window.scrollTo(0, {self.scroll_offset});"
        self.browser.page().runJavaScript(js_code)
        print(f"[Overlay] Seite wurde automatisch um {self.scroll_offset}px nach unten gescrollt.")

    # ---------------------------------------------
    # ❌ Beenden
    # ---------------------------------------------
    def close_overlay(self):
        print("[Overlay] Beende Overlay...")
        self.close()
        sys.exit(0)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    url = "https://www.method.gg/fellowship/route-planner/"
    overlay = GameOverlay(url)
    sys.exit(app.exec_())
Hier die komplette Exe, diese kann ich nicht hochladen, da Sie 107 MB hat:




Hier die Erklärung warum:
Code:
Durch Verwendung von PyQt5.QtWebEngine – das ist im Prinzip ein kompletter eingebauter Chromium-Browser (~80–100 MB!).

Diese Komponenten werden automatisch eingebunden:
QtWebEngineCore.dll
QtWebEngineWidgets.dll
Qt5Gui.dll, Qt5Core.dll, Qt5Widgets.dll
plus Chromium-Cache, Ressourcen & Plugin
Hoffe ihr könnt damit was anfangen.
Unten ist die py. Datei mit dem HTMLs zum runterladen.

Grüße
Attached Files
File Type: zip DungeonViewer.zip (40.7 KB, 13 views)
powerblobb is offline  
Reply


Similar Threads Similar Threads
Fellowship bot ?!
Yesterday - Early Access Games - 67 Replies
Is there already a bot for Fellowship?
Fellowship autoswitch target
10/23/2025 - Early Access Games - 1 Replies
Hello im looking for a Autoswitch target after death script. im working on my own but I don't know how to write script so im using Chatgpt and google for help. i dont care how polished it is or anything just as long as it servers the purpose of switching targets after death. :handsdown:
Quests in a fellowship party not working.
05/31/2021 - Last Chaos - 6 Replies
Hello everyone. anyone knows how to make quest kills count in a fellowship? or how to change a zone from needing a fellowship into needing a normal party. Thanks in advance!



All times are GMT +1. The time now is 16:59.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.