# Copyright (C) 2024–present Loren Eteval & contributors # # This file is part of Furious. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wrap the embedded Hysteria 2 core process.""" from __future__ import annotations from Furious.Frozenlib import * from Furious.Core import * from enum import Enum from typing import Union import time import logging import functools import multiprocessing logger = logging.getLogger(__name__) __all__ = ['Hysteria2'] def startHysteria2(jsonString: str, msgQueue: multiprocessing.Queue): """Start hysteria2.""" try: import hysteria2 except ImportError: # Fake running process while True: time.sleep(3600) else: if versionToValue(hysteria2.__version__) <= versionToValue('2.0.0.1'): redirect = False else: redirect = True ProcessOutputRedirector.launch( msgQueue, functools.partial(hysteria2.startFromJSON, jsonString), redirect, ) class Hysteria2(CoreProcessWorker): """Manage the embedded Hysteria 2 core subprocess.""" class ExitCode(Enum): """Enumerate process exit codes.""" ConfigurationError = 23 # Windows: 4294967295. Darwin, Linux: 255 (-1) ServerStartFailure = 4294967295 if PLATFORM == 'Windows' else 255 # Windows shutting down SystemShuttingDown = 0x40010004 def __init__(self, **kwargs): """Initialize the Hysteria2.""" super().__init__(**kwargs) @staticmethod def name() -> str: """Return the process implementation name.""" return 'Hysteria2' @staticmethod def version() -> str: """Return the bundled core version.""" try: import hysteria2 return hysteria2.__version__ except Exception: # Any non-exit exceptions return '0.0.0' def launchSpec( self, config: Union[str, dict], **kwargs ) -> Union[CoreLaunchSpec, None]: """Build the child-process launch specification.""" param = self.toJSONString(config) if not param: return None return CoreLaunchSpec( target=startHysteria2, args=( param, self.msgQueue, ), processKwargs=kwargs, ) def start(self, config: Union[str, dict], **kwargs) -> bool: """Start the hysteria2.""" launchSpec = self.launchSpec(config, **kwargs) if launchSpec is None: return False return self.startWithSpec(launchSpec)