EliteRPC/load.py
2024-05-28 19:42:10 +02:00

356 lines
13 KiB
Python

#
# KodeBlox Copyright 2019 Sayak Mukhopadhyay
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http: //www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import functools
import logging
import threading
import tkinter as tk
from os.path import dirname, join
import semantic_version
import sys
import time
import l10n
import myNotebook as nb
from config import config, appname, appversion
from py_discord_sdk import discordsdk as dsdk
plugin_name = "DiscordPresenceNG"
logger = logging.getLogger(f'{appname}.{plugin_name}')
_ = functools.partial(l10n.Translations.translate, context=__file__)
CLIENT_ID = 1013117837310693438
VERSION = '1.0'
# Add global var for Planet name (landing + around)
planet = '<Hidden>'
landingPad = '2'
this = sys.modules[__name__] # For holding module globals
def ship(ship_type):
ship_name = ''
match ship_type:
case "sidewinder":
ship_name = "Sidewinder"
case "eagle":
ship_name = "Eagle"
case "hauler":
ship_name = "Hauler"
case "adder":
ship_name = "Adder"
case "adder_taxi":
ship_name = "Apex Shuttle"
case "empire_eagle":
ship_name = "Imperial Eagle"
case "viper":
ship_name = "Viper Mk III"
case "cobramkiii":
ship_name = "Cobra Mk III"
case "viper_mkiv":
ship_name = "Viper Mk IV"
case "diamondback":
ship_name = "Diamondback Scout"
case "cobramkiv":
ship_name = "Cobra Mk IV"
case "type6":
ship_name = "Type-6 Transporter"
case "dolphin":
ship_name = "Dolphin"
case "diamondbackxl":
ship_name = "Diamondback Explorer"
case "empire_courier":
ship_name = "Imperial Courier"
case "independant_trader":
ship_name = "Keelback"
case "asp_scout":
ship_name = "Asp Scout"
case "vulture":
ship_name = "Vulture"
case "asp":
ship_name = "Asp Explorer"
case "federation_dropship":
ship_name = "Federal Dropship"
case "type7":
ship_name = "Type-7 Transporter"
case "typex":
ship_name = "Alliance Chieftain"
case "federation_dropship_mkii":
ship_name = "Federal Assault Ship"
case "empire_trader":
ship_name = "Imperial Clipper"
case "typex_2":
ship_name = "Alliance Crusader"
case "typex_3":
ship_name = "Alliance Challenger"
case "federation_gunship":
ship_name = "Federal Gunship"
case "krait_light":
ship_name = "Krait Phantom"
case "krait_mkii":
ship_name = "Krait Mk II"
case "orca":
ship_name = "Orca"
case "ferdelance":
ship_name = "Fer-de-Lance"
case "mamba":
ship_name = "Mamba"
case "python":
ship_name = "Python"
case "type9":
ship_name = "Type-9 Heavy"
case "belugaliner":
ship_name = "Beluga Liner"
case "type9_military":
ship_name = "Type-10 Defender"
case "anaconda":
ship_name = "Anaconda"
case "federation_corvette":
ship_name = "Federal Corvette"
case "cutter":
ship_name = "Imperial Cutter"
case _: # Default case for any other value
ship_name = "Unknown Ship"
return ship_name
def callback(result):
logger.info(f'Callback: {result}')
if result == dsdk.Result.ok:
logger.info("Successfully set the activity!")
elif result == dsdk.Result.transaction_aborted:
logger.warning(f'Transaction aborted due to SDK shutting down: {result}')
else:
logger.error(f'Error in callback: {result}')
raise Exception(result)
def update_presence():
if isinstance(appversion, str):
core_version = semantic_version.Version(appversion)
elif callable(appversion):
core_version = appversion()
logger.info(f'Core EDMC version: {core_version}')
if core_version < semantic_version.Version('5.0.0-beta1'):
logger.info('EDMC core version is before 5.0.0-beta1')
if config.getint("disable_presence") == 0:
this.activity.state = this.presence_state
this.activity.details = this.presence_details
this.activity.assets.large_image = this.presence_large_image
this.activity.assets.large_text = this.presence_large_text
this.activity.assets.small_image = this.presence_small_image
this.activity.assets.small_text = this.presence_small_text
else:
logger.info('EDMC core version is at least 5.0.0-beta1')
if config.get_int("disable_presence") == 0:
this.activity.state = this.presence_state
this.activity.details = this.presence_details
this.activity.assets.large_image = this.presence_large_image
this.activity.assets.large_text = this.presence_large_text
this.activity.assets.small_image = this.presence_small_image
this.activity.assets.small_text = this.presence_small_text
this.activity.timestamps.start = int(this.time_start)
this.activity_manager.update_activity(this.activity, callback)
def plugin_prefs(parent, cmdr, is_beta):
"""
Return a TK Frame for adding to the EDMC settings dialog.
"""
if isinstance(appversion, str):
core_version = semantic_version.Version(appversion)
elif callable(appversion):
core_version = appversion()
logger.info(f'Core EDMC version: {core_version}')
if core_version < semantic_version.Version('5.0.0-beta1'):
logger.info('EDMC core version is before 5.0.0-beta1')
this.disablePresence = tk.IntVar(value=config.get_int("disable_presence"))
else:
logger.info('EDMC core version is at least 5.0.0-beta1')
this.disablePresence = tk.IntVar(value=config.get_int("disable_presence"))
frame = nb.Frame(parent)
nb.Checkbutton(frame, text="Disable Presence", variable=this.disablePresence).grid()
nb.Label(frame, text='Version %s' % VERSION).grid(padx=10, pady=10, sticky=tk.W)
return frame
def prefs_changed(cmdr, is_beta):
"""
Save settings.
"""
config.set('disable_presence', this.disablePresence.get())
config.set('disable_presence', this.disableName.get())
update_presence()
def plugin_start3(plugin_dir):
this.plugin_dir = plugin_dir
this.discord_thread = threading.Thread(target=check_run, args=(plugin_dir,))
this.discord_thread.setDaemon(True)
this.discord_thread.start()
return 'DiscordPresenceNG'
def plugin_stop():
this.activity_manager.clear_activity(callback)
this.call_back_thread = None
def journal_entry(cmdr, is_beta, system, station, entry, state):
global planet
global landingPad
presence_state = this.presence_state
presence_details = this.presence_details
presence_largeimage = this.presence_large_image
presence_largetext = this.presence_large_text
presence_smallimage = this.presence_small_image
presence_smalltext = this.presence_small_text
if entry['event'] == 'StartUp':
presence_largetext = ship(('{ship}').format(ship=state['ShipType']))
presence_smalltext = ('CMDR {cmdr}').format(cmdr=cmdr)
presence_largeimage = ('{ship}').format(ship=state['ShipType'])
presence_smallimage = 'edlogo'
#presence_smalltext = ('{cmdr}cr').format(credits=state['Credits'])
presence_state = _('In system {system}').format(system=system)
if station is None:
presence_details = _('Flying in normal space')
else:
presence_details = _('Docked at {station}').format(station=station)
elif entry['event'] == 'Location':
presence_state = _('In system {system}').format(system=system)
if station is None:
presence_details = _('Flying in normal space')
else:
presence_details = _('Docked at {station}').format(station=station)
elif entry['event'] == 'StartJump':
presence_state = _('Jumping')
if entry['JumpType'] == 'Hyperspace':
presence_details = _('Jumping to system {system}').format(system=entry['StarSystem'])
elif entry['JumpType'] == 'Supercruise':
presence_details = _('Preparing for supercruise')
elif entry['event'] == 'SupercruiseEntry':
presence_state = _('In system {system}').format(system=system)
presence_details = _('Supercruising')
elif entry['event'] == 'SupercruiseExit':
presence_state = _('In system {system}').format(system=system)
presence_details = _('Flying in normal space')
elif entry['event'] == 'FSDJump':
presence_state = _('In system {system}').format(system=system)
presence_details = _('Supercruising')
elif entry['event'] == 'Docked':
presence_state = _('In system {system}').format(system=system)
presence_details = _('Docked at {station}').format(station=station)
elif entry['event'] == 'Undocked':
presence_state = _('In system {system}').format(system=system)
presence_details = _('Flying in normal space')
elif entry['event'] == 'ShutDown':
presence_state = _('Main Menu')
presence_details = ''
elif entry['event'] == 'DockingGranted':
landingPad = entry['LandingPad']
elif entry['event'] == 'Music':
if entry['MusicTrack'] == 'MainMenu':
presence_state = _('In Main Menu')
presence_details = ''
# Todo: This elif might not be executed on undocked. Functionality can be improved
elif entry['event'] == 'Undocked' or entry['event'] == 'DockingCancelled' or entry['event'] == 'DockingTimeout':
presence_details = _('Flying near {station}').format(station=entry['StationName'])
# Planetary events
elif entry['event'] == 'ApproachBody':
presence_details = _('Approaching {body}').format(body=entry['Body'])
planet = entry['Body']
elif entry['event'] == 'Touchdown' and entry['PlayerControlled']:
presence_details = _('Landed on {body}').format(body=planet)
elif entry['event'] == 'Liftoff' and entry['PlayerControlled']:
if entry['PlayerControlled']:
presence_details = _('Flying around {body}').format(body=planet)
else:
presence_details = _('In SRV on {body}, ship in orbit').format(body=planet)
elif entry['event'] == 'LeaveBody':
presence_details = _('Supercruising')
elif entry['event'] == 'Loadout':
presence_largeimage = ('{ship}').format(ship=state['ShipType'])
presence_largetext = ship(('{ship}').format(ship=state['ShipType']))
# EXTERNAL VEHICLE EVENTS
elif entry['event'] == 'LaunchSRV':
presence_details = _('In SRV on {body}').format(body=planet)
elif entry['event'] == 'DockSRV':
presence_details = _('Landed on {body}').format(body=planet)
if (presence_state != this.presence_state or
presence_details != this.presence_details or
presence_largeimage != this.presence_large_image or
presence_largetext != this.presence_large_text or
presence_smallimage != this.presence_small_image or
presence_smalltext != this.presence_small_text) :
this.presence_state = presence_state
this.presence_details = presence_details
this.presence_large_image = presence_largeimage
this.presence_large_text = presence_largetext
this.presence_small_image = presence_smallimage
this.presence_small_text = presence_smalltext
update_presence()
def check_run(plugin_dir):
plugin_path = join(dirname(plugin_dir), plugin_name)
retry = True
while retry:
time.sleep(1 / 10)
try:
this.app = dsdk.Discord(CLIENT_ID, dsdk.CreateFlags.no_require_discord, plugin_path)
retry = False
except Exception:
pass
this.activity_manager = this.app.get_activity_manager()
this.activity = dsdk.Activity()
this.call_back_thread = threading.Thread(target=run_callbacks)
this.call_back_thread.setDaemon(True)
this.call_back_thread.start()
this.presence_state = _('Connecting CMDR Interface')
this.presence_details = ''
this.presence_large_image = 'edlogo'
this.presence_large_text = 'EliteRPC'
this.presence_small_image = ''
this.presence_small_text = ''
this.time_start = time.time()
this.disablePresence = None
this.disableName = None
update_presence()
def run_callbacks():
try:
while True:
time.sleep(1 / 10)
this.app.run_callbacks()
except Exception:
check_run(this.plugin_dir)