我也不清楚改了啥,但是反正我不管(

This commit is contained in:
shenjack-mac 2023-05-14 18:44:25 +08:00 committed by shenjack
parent 6ee9d62937
commit c9e109fdb5
5 changed files with 183 additions and 19 deletions

View File

@ -22,7 +22,7 @@ import multiprocessing
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar
if __name__ == '__main__': # been start will not run this if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs') sys.path.append('/bin/libs')
@ -31,9 +31,13 @@ if __name__ == '__main__': # been start will not run this
from Difficult_Rocket import client, server, DR_option, DR_runtime from Difficult_Rocket import client, server, DR_option, DR_runtime
if TYPE_CHECKING: if TYPE_CHECKING:
from Difficult_Rocket.api.mod import ModInfo from Difficult_Rocket.api.mod import ModInfo
from Difficult_Rocket.crash import write_info_to_cache else:
ModInfo = TypeVar('ModInfo')
from Difficult_Rocket.utils import tools from Difficult_Rocket.utils import tools
from Difficult_Rocket.utils.translate import tr from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.crash import write_info_to_cache
from Difficult_Rocket.api.types import Options
from Difficult_Rocket.utils.thread import new_thread
class Game: class Game:
@ -114,7 +118,7 @@ class Game:
module.append(mod_class) module.append(mod_class)
self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version)) self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version))
except ImportError as e: except ImportError as e:
self.logger.warning(tr().main.mod.load.faild().format(mod, e)) self.logger.warning(tr().main.mod.load.faild.info().format(mod, e))
self.logger.info(tr().main.mod.load.done()) self.logger.info(tr().main.mod.load.done())
self.loaded_mods = module self.loaded_mods = module
mod_list = [] mod_list = []
@ -163,3 +167,121 @@ class Game:
def start(self) -> None: def start(self) -> None:
self._start() self._start()
class Console(Options):
name = 'python stdin console'
running: bool = False
@new_thread('python console', daemon=True, log_thread=True)
def main(self):
while self.running:
try:
get_str = input('>>>')
except (EOFError, KeyboardInterrupt):
get_str = 'stop'
self.caches.append(get_str)
if get_str == 'stop':
self.running = False
break
def start(self):
self.running = True
self.caches: List[str] = []
self.main()
def stop(self):
self.running = False
def get_command(self) -> str:
return self.caches.pop(0)
class MainGame(Options):
name = 'MainGame'
client: client.Client
server: server.Server
console: Console
main_config: Dict
logger: logging.Logger
mod_module: List["ModInfo"]
def init_logger(self) -> None:
...
def init_console(self) -> None:
self.console = Console()
self.console.start()
def init_mods(self) -> None:
"""验证/加载 mod"""
mods = []
mod_path = Path(DR_runtime.mod_path)
if not mod_path.exists():
self.logger.info(tr().main.mod.find.faild.no_mod_folder())
return
# 寻找有效 mod
paths = mod_path.iterdir()
sys.path.append(DR_runtime.mod_path)
for mod_path in paths:
try:
if mod_path.name == '__pycache__':
continue
self.logger.info(tr().main.mod.find.start().format(mod_path))
if mod_path.is_dir():
if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name)
else:
self.logger.warning(tr().main.mod.load.faild.info().format(mod_path.name, tr().main.mod.find.faild.no_spec()))
elif mod_path.suffix in ('.pyz', '.zip', '.pyd', '.py'):
if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name)
except ImportError as e:
self.logger.warning(tr().main.mod.find.faild().format(mod_path, e))
self.logger.info(tr().main.mod.find.done())
# 加载有效 mod
module = []
for mod in mods:
try:
self.logger.info(tr().main.mod.load.start().format(mod))
mod_module = importlib.import_module(mod)
if not hasattr(mod_module, "mod_class"):
self.logger.warning(tr().main.mod.load.faild.info().format(mod, tr().main.mod.load.faild.no_mod_class()))
del mod_module # 释放内存
continue
mod_class: type(ModInfo) = mod_module.mod_class
mod_class = mod_class()
module.append(mod_class)
self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version))
except ImportError as e:
self.logger.warning(tr().main.mod.load.faild.info().format(mod, e))
self.logger.info(tr().main.mod.load.done())
self.mod_module = module
mod_list = []
for mod in module:
mod_list.append((mod.mod_id, mod.version))
# 调用 on_load
self.dispatch_event('on_load', game=self)
DR_runtime.DR_Mod_List = mod_list
def dispatch_event(self, event_name: str, *args, **kwargs) -> None:
"""向 mod 分发事件"""
for mod in self.mod_module:
if hasattr(mod, event_name):
try:
getattr(mod, event_name)(*args, **kwargs)
except Exception as e:
self.logger.error(tr().main.mod.event.error().format(event_name, e, mod.mod_id))
def init(self, **kwargs) -> None:
...
def load_file(self) -> bool:
"""加载文件"""
self.init_logger()
self.init_mods()
return True

View File

@ -104,5 +104,6 @@ if TYPE_CHECKING:
class Console_rs: class Console_rs:
def __init__(self) -> None: ... def __init__(self) -> None: ...
def stop_console(self) -> None: ... def start(self) -> None: ...
def stop(self) -> bool: ...
def get_command(self) -> Optional[str]: ... def get_command(self) -> Optional[str]: ...

View File

@ -176,15 +176,21 @@ pub mod console {
#[pyo3(name = "Console_rs")] #[pyo3(name = "Console_rs")]
pub struct PyConsole { pub struct PyConsole {
/// 向子线程发送结束信号 /// 向子线程发送结束信号
pub stop_sender: std::sync::mpsc::Sender<()>, pub stop_sender: Option<std::sync::mpsc::Sender<()>>,
/// pub keyboard_input_receiver: Option<std::sync::mpsc::Receiver<String>>,
pub keyboard_input_receiver: std::sync::mpsc::Receiver<String>,
} }
#[pymethods] #[pymethods]
impl PyConsole { impl PyConsole {
#[new] #[new]
fn new() -> Self { fn new() -> Self {
Self {
stop_sender: None,
keyboard_input_receiver: None,
}
}
fn start(&mut self) {
let (stop_sender, stop_receiver) = std::sync::mpsc::channel(); let (stop_sender, stop_receiver) = std::sync::mpsc::channel();
let (keyboard_input_sender, keyboard_input_receiver) = std::sync::mpsc::channel(); let (keyboard_input_sender, keyboard_input_receiver) = std::sync::mpsc::channel();
std::thread::spawn(move || { std::thread::spawn(move || {
@ -194,27 +200,31 @@ pub mod console {
break; break;
} }
let mut input = String::new(); let mut input = String::new();
print!(">>");
let _ = std_in.read_line(&mut input); let _ = std_in.read_line(&mut input);
if !input.is_empty() { if !input.is_empty() {
keyboard_input_sender.send(input).unwrap(); keyboard_input_sender.send(input).unwrap();
} }
print!(">>");
} }
}); });
self.stop_sender = Some(stop_sender);
Self { self.keyboard_input_receiver = Some(keyboard_input_receiver);
stop_sender,
keyboard_input_receiver,
}
} }
fn stop_console(&self) { self.stop_sender.send(()).unwrap(); } fn stop(&self) -> bool {
if let (Some(sender)) = &self.stop_sender {
sender.send(()).unwrap();
return true;
}
false
}
fn get_command(&self) -> Option<String> { fn get_command(&self) -> Option<String> {
// 获取输入 // 获取输入
if let Ok(string) = self.keyboard_input_receiver.try_recv() { if let (Some(receiver)) = &self.keyboard_input_receiver {
println!("rust recv input: {}", string); if let Ok(string) = receiver.try_recv() {
return Some(string); return Some(string);
}
} }
None None
} }

View File

@ -9,9 +9,8 @@ import traceback
from typing import Optional from typing import Optional
from libs.MCDR.version import Version from libs.MCDR.version import Version
from Difficult_Rocket.main import Game from Difficult_Rocket.main import Game, Console
from Difficult_Rocket.api.mod import ModInfo from Difficult_Rocket.api.mod import ModInfo
from Difficult_Rocket.api.types import Options from Difficult_Rocket.api.types import Options
from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.client import ClientWindow
@ -68,6 +67,14 @@ class DR_mod(ModInfo):
def on_load(self, game: Game, old_self: Optional["DR_mod"] = None) -> bool: def on_load(self, game: Game, old_self: Optional["DR_mod"] = None) -> bool:
if not DR_mod_runtime.DR_rust_available: if not DR_mod_runtime.DR_rust_available:
return False return False
from .console import RustConsole
def init_console(self) -> None:
self.console = RustConsole()
self.console.start()
game.init_console = init_console # 替换掉原来的 init_console 函数
if old_self: if old_self:
game.client.window.add_sub_screen("SR1_ship", old_self.screen) game.client.window.add_sub_screen("SR1_ship", old_self.screen)
else: else:

24
mods/dr_game/console.py Normal file
View File

@ -0,0 +1,24 @@
from . import DR_mod_runtime
from Difficult_Rocket.main import Console
if DR_mod_runtime.use_DR_rust:
from .Difficult_Rocket_rs import Console_rs
class RustConsole(Console):
name = 'Rust stdin Console'
running: bool = False
console: Console_rs
def start(self):
self.console.start()
def stop(self):
return self.console.stop()
def init(self, **kwargs) -> None:
self.console = Console_rs()
def get_command(self) -> str:
return self.console.get_command()