Skip to content

Commit

Permalink
Merge pull request #2 from alexzk1/more_privates
Browse files Browse the repository at this point in the history
More privates
  • Loading branch information
alexzk1 authored Apr 14, 2024
2 parents df6c558 + 55c3054 commit 33b87ee
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 61 deletions.
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# edmcoverlay2
# EDMC Overlay for Linux

This is port of the idea of [EDMC Overlay] to the Linux.

[EDMC Overlay][] for Linux.
Only API is ported, everything else is made from scratch. This repo supports X11 only yet.

## New Features
* TTF fonts are supported.


## Example Screenshot(s)

![ttf_example](https://github.com/alexzk1/edmcoverlay2/assets/4589845/60120533-ee49-4b47-9804-4cd3075d2426)

## Installation

- Clone the repo into your EDMC plugins' directory
- NB: you *must* name the directory `edmcoverlay`, not `edmcoverlay2`. You may clone repo elsewhere and symlink it as `edmcoverlay` to the plugins' directory. This is required because all other plugins use this name to access overlay (some are using `EDMCOverlay` naming too).
- NB: you *must* name the directory `edmcoverlay`, not `edmcoverlay_for_linux`. You may clone repo elsewhere and symlink it as `edmcoverlay` to the plugins' directory. This is required because all other plugins use this name to access overlay (some are using `EDMCOverlay` naming too).
- Install the dependencies (mostly X11 development headers; on Ubuntu,
the `xorg-dev` package may be sufficient)
the `xorg-dev` package may be sufficient), `cmake`.
- Run script `create_binary.sh` it will handle all needed.
- In the EDMC settings, configure the size and position of the overlay

Expand All @@ -17,20 +27,20 @@ Full list of libraries used check into `cpp/CMakeLists.txt`. Those must be pre-i

## Usage

edmcoverlay2 aims to be 100% compatible with EDMC Overlay. Python library is a wrapper to pass json to the compiled binary.
Compiled binary can be used stand-alone for any other purposes as overlay. Binary listens on port 5010.
TTF fonts are supported.
EDMCOverlay for Linux aims to be 100% compatible with EDMC Overlay.

![ttf_example](https://github.com/alexzk1/edmcoverlay2/assets/4589845/60120533-ee49-4b47-9804-4cd3075d2426)
Python library is a wrapper to pass json to the compiled binary.
Compiled binary can be used stand-alone for any other purposes as overlay. Binary listens on port 5010.

Some features are not yet implemented, and there are likely to be bugs.

## Copyright

Copyright © 2020 Ash Holland. Licensed under the GPL (version 3 only).

Copyright © 2021-2024 Oleksiy Zakharov. Licensed under the GPL (version 3 only).

### Original references by Ash Holland

edmcoverlay2 is heavily based on [X11 overlay][] by @ericek111 (GPLv3).

Additionally, parts of edmcoverlay2 are copied from other projects:
Expand Down
31 changes: 31 additions & 0 deletions _logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# See: https://github.com/EDCD/EDMarketConnector/blob/main/PLUGINS.md
# Use: from _logger import logger

import logging
import os

from config import appname

# This could also be returned from plugin_start3()
__plugin_name = os.path.basename(os.path.dirname(__file__))

# A Logger is used per 'found' plugin to make it easy to include the plugin's
# folder name in the logging output format.
# NB: plugin_name here *must* be the plugin's folder name as per the preceding
# code, else the logger won't be properly set up.
logger = logging.getLogger(f"{appname}.{__plugin_name}")

# If the Logger has handlers then it was already set up by the core code, else
# it needs setting up here.
if not logger.hasHandlers():
level = logging.INFO # So logger.info(...) is equivalent to print()

logger.setLevel(level)
logger_channel = logging.StreamHandler()
logger_formatter = logging.Formatter(
f"%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(lineno)d:%(funcName)s: %(message)s"
)
logger_formatter.default_time_format = "%Y-%m-%d %H:%M:%S"
logger_formatter.default_msec_format = "%s.%03d"
logger_channel.setFormatter(logger_formatter)
logger.addHandler(logger_channel)
24 changes: 20 additions & 4 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 3.5)

project(edmc_linux_overlay LANGUAGES CXX)

#Required packages, please install it using package manager, on Ubuntu it may have prefix "lib" or suffix "-dev" or both.
#Required packages, please install it using package manager, on Ubuntu it may have prefix "lib"
#or suffix "-dev" or both.

find_package(Freetype REQUIRED)
find_package(Fontconfig REQUIRED)
find_package(X11 COMPONENTS Xft Xfixes Xext REQUIRED)
Expand All @@ -12,9 +14,23 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_VERBOSE_MAKEFILE ON)


add_executable(${CMAKE_PROJECT_NAME} overlay.cpp json.hpp socket.cc socket.hh json_message.cc json_message.hh xoverlayoutput.cpp xoverlayoutput.h
opaque_ptr.h cm_ctors.h colors_mgr.h drawables.h layer_out.h runners.h)
set(PROJECT_SOURCES
main.cpp
colors_mgr.h
drawables.h
layer_out.h
xoverlayoutput.cpp xoverlayoutput.h
json_message.cc json_message.hh
socket.cc socket.hh

#Common helpers
json.hpp
cm_ctors.h
opaque_ptr.h
runners.h
)

add_executable(${CMAKE_PROJECT_NAME} ${PROJECT_SOURCES})

target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -march=native -Wall)

Expand Down
File renamed without changes.
41 changes: 19 additions & 22 deletions edmcoverlay.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from pathlib import Path
from config import appname
from functools import wraps
from _logger import logger

import logging
import secrets
import inspect
import errno
Expand All @@ -13,13 +12,10 @@
import random



plugin_name = Path(__file__).parent.name
logger = logging.getLogger(f"{appname}.{plugin_name}")
logger.debug("edmcoverlay2: lib loaded")
def check_game_running():
return True


class _OverlayImpl:
__instance = None
__lock = threading.Lock()
Expand All @@ -32,17 +28,18 @@ def __new__(cls, *args, **kwargs):
return cls.__instance

def __init__(self, server: str = "127.0.0.1", port: int = 5010):
logger.info("edmcoverlay2: loaded python plugin.")
logger.info("Loading implementation details...")
with self.__lock:
if self.__initialised:
logger.debug("edmcoverlay2: skipping init")
logger.debug("Details were already loaded.")
return
logger.debug("edmcoverlay2: init")
logger.debug("Initializing implementation details.")
self.__initialised = True
self._host = server
self._port = port

def _stop(self):
logger.info("Sending self-stop/exit request to the binary.")
self._send_raw_text("NEED_TO_STOP")

def _send_raw_text(self, inpstr: str):
Expand All @@ -57,7 +54,9 @@ def _send_raw_text(self, inpstr: str):
break
except socket.error as e:
if e.errno == errno.ECONNREFUSED:
logger.warning("edmcoverlay2: conn refused times %i", retries)
logger.warning(
"Connection to binary server was refused %i time(s).", retries
)
time.sleep(random.randint(200, 450) / 1000.0)
else:
raise
Expand Down Expand Up @@ -113,6 +112,15 @@ def send_shape(
self._send2bin(msg)


logger.debug("Instantiating class OverlayImpl ...")
__the_overlay: _OverlayImpl = _OverlayImpl()
logger.debug(" class OverlayImpl is instantiated.")


def RequestBinaryToStop():
__the_overlay._stop()


class Overlay:
__caller_path: str = None
__token: str = None
Expand All @@ -123,7 +131,7 @@ def __init__(self) -> None:
self.__overlay = _OverlayImpl()
callFrames = inspect.getouterframes(inspect.currentframe())
__caller_path = callFrames[1].filename
logger.debug('\tOverlay() is created from: "%s"\n', __caller_path)
logger.info('\tOverlay() is created from: "%s"\n', __caller_path)

def send_raw(self, msg):
if "msgid" in msg:
Expand Down Expand Up @@ -166,14 +174,3 @@ def send_shape(

def connect(self) -> bool:
return True


logger.debug("edmcoverlay2: instantiating overlay class")
__the_overlay = _OverlayImpl()


def RequestBinaryToStop():
__the_overlay._stop()


logger.debug("edmcoverlay2: overlay class instantiated")
49 changes: 23 additions & 26 deletions load.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
"""Totally definitely EDMCOverlay."""

import logging
import time
import tkinter as tk
from pathlib import Path
from subprocess import Popen
from tkinter import ttk

import myNotebook as nb
import plug
from config import appname, config
from config import config
from ttkHyperlinkLabel import HyperlinkLabel

import os
import sys


import edmcoverlay
from _logger import logger

plugin_name = Path(__file__).parent.name
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
logger = logging.getLogger(f"{appname}.{plugin_name}")
logger.debug("Loading plugin...")


__CaptionText: str = "EDMCOverlay for Linux"
__overlay_process: Popen = None
__xpos_var: tk.IntVar
__ypos_var: tk.IntVar
Expand All @@ -43,7 +35,7 @@ def __find_overlay_binary() -> Path:

for p in possible_paths:
if p.exists():
logger.info("Found overlay binary at \"%s\".", p)
logger.info('Found overlay binary at "%s".', p)
return p

raise RuntimeError("Unable to find overlay's binary.")
Expand All @@ -67,40 +59,45 @@ def __start_overlay():
"edmcintro", "EDMC Overlay for Linux is Ready", "yellow", 30, 165, ttl=10
)
else:
logger.warning("Overlay is already running, skipping the start.")
logger.debug("Overlay is already running, skipping the start.")


def __stop_overlay():
global __overlay_process
if __overlay_process:
logger.info("Stopping overlay.")
__overlay_process.terminate()
__overlay_process.communicate()
edmcoverlay.RequestBinaryToStop()
time.sleep(1)
if __overlay_process.poll() is None:
__overlay_process.terminate()
__overlay_process.communicate()
__overlay_process = None
else:
logger.warning("Overlay was not started. Nothing to stop.")


def plugin_start3(plugin_dir):
logger.info("Python code starts.")
__start_overlay()
return "EDMCOverlay for Linux"
logger.debug("Overlay was not started. Nothing to stop.")


# Reaction to the game start/stop.
def journal_entry(cmdr, is_beta, system, station, entry, state):
global __overlay_process
if entry["event"] in ["LoadGame", "StartUp"] and __overlay_process is None:
logger.info("edmcoverlay2: load event received, starting overlay")
logger.info("Load event received, ensuring binary overlay is started.")
__start_overlay()
elif entry["event"] in ["Shutdown", "ShutDown"]:
logger.info("edmcoverlay2: shutdown event received, stopping overlay")
logger.info("Shutdown event received, stopping binary overlay.")
__stop_overlay()


# Reaction to EDMC start.
def plugin_start3(plugin_dir):
logger.info("Python code starts.")
__start_overlay()
return __CaptionText


# Reaction to EDMC stop.
def plugin_stop():
global __overlay_process
logger.info("Finishing Python's code.")
edmcoverlay.RequestBinaryToStop()
__stop_overlay()


Expand All @@ -118,7 +115,7 @@ def plugin_prefs(parent: nb.Notebook, cmdr: str, is_beta: bool) -> nb.Frame:
f0 = nb.Frame(frame)
HyperlinkLabel(
f0,
text="edmcoverlay for linux",
text=__CaptionText,
url="https://github.com/alexzk1/edmcoverlay2",
background=nb.Label().cget("background"),
underline=True,
Expand Down

0 comments on commit 33b87ee

Please sign in to comment.