From 18ecddcb3cb51c19d6c9cab8798daf44f8f4e56b Mon Sep 17 00:00:00 2001 From: "1992414357@qq.com" <1992414357@qq.com> Date: Tue, 27 May 2025 10:31:24 +0800 Subject: 1. 将PadClient中的消息队列从Vec替换为VecDeque 2. 将convert_deque_to_vec方法移至nogamepads 3. 将server和client的运行时cli中的print宏换为log中的宏 4. 重命名debug_console.rs为console_utils.rs 5. 重命名logger.rs为logger_utils.rs 6. 将PadServer方法start_listening改为start_server 7. 编写了README.md 8. 优化了发布脚本 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cargo/scripts/release_project.bat | 19 ++--------- README.md | 14 ++++++++ console/src/bin/nogpads.rs | 4 +-- core/examples/start_server_console.rs | 7 ++-- core/src/pad_io/client.rs | 41 +++++++++++----------- core/src/pad_io/client_debug_cli.rs | 7 ++-- core/src/pad_io/server.rs | 25 ++++++-------- core/src/pad_io/server_debug_cli.rs | 16 ++++----- src/console_utils.rs | 64 +++++++++++++++++++++++++++++++++++ src/convert_utils.rs | 10 ++++++ src/debug_console.rs | 64 ----------------------------------- src/lib.rs | 5 +-- src/logger.rs | 22 ------------ src/logger_utils.rs | 22 ++++++++++++ 14 files changed, 164 insertions(+), 156 deletions(-) create mode 100644 src/console_utils.rs create mode 100644 src/convert_utils.rs delete mode 100644 src/debug_console.rs delete mode 100644 src/logger.rs create mode 100644 src/logger_utils.rs diff --git a/.cargo/scripts/release_project.bat b/.cargo/scripts/release_project.bat index 3979e9d..dbe9686 100644 --- a/.cargo/scripts/release_project.bat +++ b/.cargo/scripts/release_project.bat @@ -2,28 +2,13 @@ setlocal enabledelayedexpansion :: ================= 路径 ================= -:: 控制台程序的 CRATE -set "CONSOLE_CRATE_DIR=console" - -:: C动态链接库的 CRATE -set "DLL_CRATE_DIR=core_c" - :: 打包地址 set "RELEASE_DIR=release\dev" :: ================= 构建 ================= :: 控制台程序 -echo [INFO] Building console ... -pushd ".\%CONSOLE_CRATE_DIR%\" -cargo build --release -popd -echo -:: C动态链接库 -echo [INFO] Building dll ... -pushd ".\%DLL_CRATE_DIR%\" -cargo build --release -popd - +echo [INFO] Building ... +cargo build --workspace --release echo Done. echo diff --git a/README.md b/README.md index e69de29..74ccd4a 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,14 @@ +# No Gamepads + +## 前言 + +​ `No Gamepads` 项目正如其名,您再不必为游戏准备专门的手柄了!仅需安装好移动端,保证局域网或蓝牙连接通畅,然后扫描游戏内提供的二维码,您就获得了该游戏为您量身定做的控制器面版!您也可以叫上朋友,让他们也加入游戏! + +​ `No Gamepads` 不仅是一款远程手柄软件,它还是您的移动存档:从一台电脑到另一台电脑,您只需要把移动设备从这头连接到那头,存档就在您手里! + +​ `No Gamepads` 需要游戏专门为其适配,但不必担心!`No Gamepads` 提供了极为简单的接入流程,在我们提供的编辑器上设计出面板,将资源包导入游戏,再对接上程序接口,一切就搞定了! + +​ 若您要在不支持的游戏上运行,仅需在电脑上安装 `No Gamepads XBOX Interface`,即可将移动设备作为 XBOX 手柄运行! + +​ 这是一个长期的项目,我们的目的是拓展游戏的操作方式,在线下和朋友联机的时候也不必被手柄数量所局促。为大多主流游戏引擎设计接口的目的也是希望更多的人参与到我们的项目! + diff --git a/console/src/bin/nogpads.rs b/console/src/bin/nogpads.rs index 95f5ec7..7328b47 100644 --- a/console/src/bin/nogpads.rs +++ b/console/src/bin/nogpads.rs @@ -150,14 +150,14 @@ fn main () { .put_profile(config.profile) .enable_console() .build() - .start_listening(); + .start_server(); } else { println!("Server started!"); PadServer::default() .addr(IpAddr::from(Ipv4Addr::new(127, 0, 0, 1)), config.port) .put_profile(config.profile) .build() - .start_listening(); + .start_server(); } } } diff --git a/core/examples/start_server_console.rs b/core/examples/start_server_console.rs index e643390..4b34cdd 100644 --- a/core/examples/start_server_console.rs +++ b/core/examples/start_server_console.rs @@ -1,7 +1,7 @@ -use std::net::{IpAddr, Ipv4Addr}; -use nogamepads_core::DEFAULT_PORT; use nogamepads_core::pad_data::game_profile::game_profile::GameProfile; use nogamepads_core::pad_io::server::nogamepads_server::PadServer; +use nogamepads_core::DEFAULT_PORT; +use std::net::{IpAddr, Ipv4Addr}; fn main() { @@ -23,8 +23,9 @@ fn main() { .to_owned() ) .enable_console() + // .quiet() .build(); // 运行服务端 - server.start_listening(); + server.start_server(); } \ No newline at end of file diff --git a/core/src/pad_io/client.rs b/core/src/pad_io/client.rs index 2969742..bd8bc2c 100644 --- a/core/src/pad_io/client.rs +++ b/core/src/pad_io/client.rs @@ -1,4 +1,5 @@ pub mod nogamepads_client { + use std::collections::VecDeque; use crate::pad_data::pad_messages::nogamepads_message_transfer::{read_msg, send_msg}; use crate::pad_data::pad_messages::nogamepads_messages::{ConnectionCallbackMessage, ConnectionErrorType, ConnectionMessage, ControlMessage, GameMessage, LeaveReason}; use crate::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; @@ -13,15 +14,16 @@ pub mod nogamepads_client { use tokio::io::{AsyncReadExt, AsyncWriteExt, ReadHalf, WriteHalf}; use tokio::net::TcpStream; use tokio::{io, spawn}; - use nogamepads::debug_console::debug_console::read_cli; - use nogamepads::logger::logger_build; + use nogamepads::console_utils::debug_console::read_cli; + use nogamepads::convert_utils::convert_deque_to_vec; + use nogamepads::logger_utils::logger_build; use crate::pad_io::client_debug_cli::{process_debug_cmd, Pcc}; use crate::DEFAULT_PORT; use crate::pad_data::game_profile::game_profile::GameProfile; use crate::pad_data::pad_messages::nogamepads_message_encoder::NgpdMessageEncoder; - type WriteList = Arc>>; - type ReadList = Arc>>; + type WriteList = Arc>>; + type ReadList = Arc>>; pub struct PadClient { @@ -108,20 +110,16 @@ pub mod nogamepads_client { pub fn put_msg(&self, msg: ControlMessage) { - { - let mut guard = self.write_list.lock().unwrap(); - guard.push(msg); - } + let mut guard = self.write_list.lock().unwrap(); + guard.push_back(msg); } pub fn pop_a_msg(&self) -> Option { - { - let mut guard = self.read_list.lock().unwrap(); - if ! guard.is_empty() { - Some(guard.remove(0)) - } else { - None - } + let mut guard = self.read_list.lock().unwrap(); + if !guard.is_empty() { + guard.pop_front() + } else { + None } } @@ -132,7 +130,7 @@ pub mod nogamepads_client { pub fn list_received(&self) -> Vec { match self.read_list.lock() { Ok(guard) => { - guard.to_vec() + convert_deque_to_vec(&guard.to_owned()) } Err(_) => { Vec::new() } } @@ -143,7 +141,7 @@ pub mod nogamepads_client { impl PadClient { pub fn connect(self) { - + self.exit.store(false, SeqCst); // 构建 Logger @@ -238,7 +236,7 @@ pub mod nogamepads_client { } } - async fn check_server_profile (self: &Arc, buffer: &mut [u8], addr_str: String) -> Option { + async fn check_server_profile(self: &Arc, buffer: &mut [u8], addr_str: String) -> Option { match TcpStream::connect(&addr_str).await { Ok(mut stream) => { send_msg(&mut stream, ConnectionMessage::RequestProfile).await; @@ -363,7 +361,7 @@ pub mod nogamepads_client { } _ => { info!("{:?}", &msg); - guard.push(msg); + guard.push_back(msg); } } } @@ -388,9 +386,10 @@ pub mod nogamepads_client { match lock { Ok(mut guard) => { if ! guard.is_empty() { - msg = Some(guard.remove(0)); + msg = guard.pop_front(); + } else { + msg = None; } - else { msg = None; } } Err(_) => { msg = None; diff --git a/core/src/pad_io/client_debug_cli.rs b/core/src/pad_io/client_debug_cli.rs index c95fb94..b34bef5 100644 --- a/core/src/pad_io/client_debug_cli.rs +++ b/core/src/pad_io/client_debug_cli.rs @@ -2,6 +2,7 @@ use crate::pad_io::client::nogamepads_client::PadClient; use crate::pad_data::pad_messages::nogamepads_messages::{ControlMessage, GameMessage}; use clap::{Args, Parser, Subcommand}; use std::sync::Arc; +use log::info; /// NoGamePads Client - Cli #[derive(Parser, Debug)] @@ -68,15 +69,15 @@ pub fn process_debug_cmd (cmd: Pcc, client: Arc) { Commands::Received(args) => { if args.list { for msg in client.list_received() { - println!("{:?}", msg); + info!("{:?}", msg); } } else { - println!("Total {} messsage(s)!", client.list_received().iter().count()); + info!("Total {} messsage(s)!", client.list_received().iter().count()); } } Commands::Pop(_args) => { - println!("{:?}", client.pop_msg_or(GameMessage::Err)); + info!("{:?}", client.pop_msg_or(GameMessage::Err)); } Commands::Msg(args) => { diff --git a/core/src/pad_io/server.rs b/core/src/pad_io/server.rs index c530753..59241f1 100644 --- a/core/src/pad_io/server.rs +++ b/core/src/pad_io/server.rs @@ -15,8 +15,9 @@ pub mod nogamepads_server { use tokio::net::{TcpListener, TcpStream}; use tokio::{io, spawn}; use tokio::runtime::Runtime; - use nogamepads::debug_console::debug_console::read_cli; - use nogamepads::logger::logger_build; + use nogamepads::console_utils::debug_console::read_cli; + use nogamepads::convert_utils::convert_deque_to_vec; + use nogamepads::logger_utils::logger_build; use crate::DEFAULT_PORT; use crate::pad_data::game_profile::game_profile::GameProfile; use crate::pad_data::pad_messages::nogamepads_messages::ConnectionErrorType::{ContainSamePlayer, GameLocked, PlayerBanned, WhatTheHell}; @@ -219,7 +220,7 @@ pub mod nogamepads_server { match guard.get_key_value(player.account.player_hash.as_str()) { None => { Vec::new() } Some(result) => { - Self::convert_deque_to_vec(result.1) + convert_deque_to_vec(result.1) } } } @@ -301,27 +302,18 @@ pub mod nogamepads_server { Err(err) => Err(err) } } - - fn convert_deque_to_vec (deque: &VecDeque) -> Vec { - let vec_deque_ref = deque; - let mut vec = Vec::new(); - for item in vec_deque_ref { - vec.push(item.clone()) - } - vec - } } // 服务端状态控制 #[allow(dead_code)] impl PadServer { - pub fn stop_listening(&self) { + pub fn stop_server(&self) { self.put_msg_to_all(&Leave(ServerClosed)); self.stop.store(true, SeqCst); } - pub fn start_listening(self: Arc) { + pub fn start_server(self: Arc) { // 构建 Logger if ! self.quiet { @@ -476,6 +468,7 @@ pub mod nogamepads_server { self.set_player_online(&info, true); // 启动控制循环 + spawn(Self::long_connection(Arc::clone(&self), stream, info)); }, _ => { @@ -541,6 +534,7 @@ pub mod nogamepads_server { .entry(player_hash.clone()) .or_insert_with(VecDeque::new) .push_back(msg); + } Err(_) => { } @@ -549,6 +543,7 @@ pub mod nogamepads_server { } Err(e) => { warn!("Error reading from stream: {}", e); + self.set_player_online(&player_info, false); // 放入一条错误信息到队列,使 write_task 及时发现该玩家离开 @@ -594,6 +589,7 @@ pub mod nogamepads_server { let msg = msg.unwrap(); match &writer.write_all(NgpdMessageEncoder::en(&msg).as_slice()).await { Ok(_) => { + info!("Sent {:?} to {}", msg, &player_info.account.id); } Err(error) => { @@ -616,6 +612,7 @@ pub mod nogamepads_server { // 退出程序的监听 if self.stop.load(SeqCst) { tokio::time::sleep(Duration::from_secs(1)).await; + info!("Main thread exited."); exit(0); } diff --git a/core/src/pad_io/server_debug_cli.rs b/core/src/pad_io/server_debug_cli.rs index 76e331f..39e1868 100644 --- a/core/src/pad_io/server_debug_cli.rs +++ b/core/src/pad_io/server_debug_cli.rs @@ -4,6 +4,7 @@ use crate::pad_io::server::nogamepads_server::PadServer; use clap::{Args, Parser, Subcommand}; use std::ops::{Index}; use std::sync::{Arc, MutexGuard, PoisonError}; +use log::{error, info}; use crate::pad_data::pad_player_info::nogamepads_player_info::PlayerInfo; /// NoGamePads Server - Cli @@ -98,7 +99,7 @@ pub fn process_debug_cmd (cmd: Psc, server: Arc) { } Commands::Stop => { - server.stop_listening(); + server.stop_server(); } Commands::List => { @@ -114,21 +115,21 @@ pub fn process_debug_cmd (cmd: Psc, server: Arc) { let player = players.index(args.player.clamp(0, players.iter().count() -1)); if args.list { for msg in server.list_received(player) { - println!("{:?}", msg); + info!("{:?}", msg); } } else { - println!("Total {} messsage(s)!", server.list_received(player).iter().count()); + info!("Total {} messsage(s)!", server.list_received(player).iter().count()); } } Commands::Pop(args) => { match get_player_by_index(&server, args.index) { None => { - eprintln!("Pup message failed : Player index \"{}\" not found!", args.index); + error!("Pup message failed : Player index \"{}\" not found!", args.index); } Some(player) => { let message = server.pop_msg_or(&player, ControlMessage::Err); - println!("{:?}", message); + info!("{:?}", message); } } } @@ -166,7 +167,7 @@ pub fn process_debug_cmd (cmd: Psc, server: Arc) { fn put_to_list(server: Arc, player_index: usize, message: GameMessage) { match get_player_by_index(&server, player_index) { None => { - eprintln!("Put message failed : Player index \"{}\" not found!", player_index); + error!("Put message failed : Player index \"{}\" not found!", player_index); } Some(player) => { server.put_msg_to(message, &player); @@ -197,8 +198,7 @@ fn print_player_list(list: Result, PoisonError(prefix: &str, entry: String, cmd: Command) -> Option + where + Cmd: FromArgMatches, + { + let input: String = { + let mut buffer = String::new(); + let mut stdin = tokio::io::BufReader::new(tokio::io::stdin()); + let mut stdout = tokio::io::stdout(); + + stdout.write_all(prefix.as_bytes()).await.ok().unwrap(); + stdout.flush().await.ok().unwrap(); + + stdin.read_line(&mut buffer).await.ok().unwrap(); + buffer.trim().to_string() + }; + + process_debug_cli(entry, input, cmd).await + } + + async fn process_debug_cli(entry: String, input: String, cmd: Command) -> Option + where + Cmd: FromArgMatches + { + if input.trim().is_empty() { + return None; + } + + let cmd = cmd + .color(Auto) + .help_template( + "{subcommands}{options}" + ) + .disable_help_flag(true) + .disable_version_flag(true); + + let args = shell_words::split(input.as_str()).unwrap_or_else(|_e| { + ["".to_string()].to_vec() + }); + + let full_args = std::iter::once(entry.into()).chain(args); + + match cmd.try_get_matches_from(full_args) { + Ok(matches) => { + match Cmd::from_arg_matches(&matches) { + Ok(cmd) => { + Some(cmd) + } + Err(_err) => { + None + } + } + } + Err(err) => { + println!("{}", err); + None + } + } + } +} diff --git a/src/convert_utils.rs b/src/convert_utils.rs new file mode 100644 index 0000000..fccd01e --- /dev/null +++ b/src/convert_utils.rs @@ -0,0 +1,10 @@ +use std::collections::VecDeque; + +pub fn convert_deque_to_vec (deque: &VecDeque) -> Vec { + let vec_deque_ref = deque; + let mut vec = Vec::new(); + for item in vec_deque_ref { + vec.push(item.clone()) + } + vec +} \ No newline at end of file diff --git a/src/debug_console.rs b/src/debug_console.rs deleted file mode 100644 index 3e673fc..0000000 --- a/src/debug_console.rs +++ /dev/null @@ -1,64 +0,0 @@ -pub mod debug_console { - use clap::{Command, FromArgMatches}; - use clap::ColorChoice::Auto; - use tokio::io::{AsyncBufReadExt, AsyncWriteExt}; - - pub async fn read_cli(prefix: &str, entry: String, cmd: Command) -> Option - where - Cmd: FromArgMatches, - { - let input: String = { - let mut buffer = String::new(); - let mut stdin = tokio::io::BufReader::new(tokio::io::stdin()); - let mut stdout = tokio::io::stdout(); - - stdout.write_all(prefix.as_bytes()).await.ok().unwrap(); - stdout.flush().await.ok().unwrap(); - - stdin.read_line(&mut buffer).await.ok().unwrap(); - buffer.trim().to_string() - }; - - process_debug_cli(entry, input, cmd).await - } - - async fn process_debug_cli(entry: String, input: String, cmd: Command) -> Option - where - Cmd: FromArgMatches - { - if input.trim().is_empty() { - return None; - } - - let cmd = cmd - .color(Auto) - .help_template( - "{subcommands}{options}" - ) - .disable_help_flag(true) - .disable_version_flag(true); - - let args = shell_words::split(input.as_str()).unwrap_or_else(|_e| { - ["".to_string()].to_vec() - }); - - let full_args = std::iter::once(entry.into()).chain(args); - - match cmd.try_get_matches_from(full_args) { - Ok(matches) => { - match Cmd::from_arg_matches(&matches) { - Ok(cmd) => { - Some(cmd) - } - Err(_err) => { - None - } - } - } - Err(err) => { - println!("{}", err); - None - } - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 55ff0ec..5d6a463 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ -pub mod debug_console; -pub mod logger; \ No newline at end of file +pub mod console_utils; +pub mod logger_utils; +pub mod convert_utils; \ No newline at end of file diff --git a/src/logger.rs b/src/logger.rs deleted file mode 100644 index 77b136e..0000000 --- a/src/logger.rs +++ /dev/null @@ -1,22 +0,0 @@ -use env_logger::Builder; -use log::{info, LevelFilter}; - -pub fn logger_build () { - Builder::new() - .format(|buf, record| { - use std::io::Write; - let now = chrono::Local::now(); - let level_style = buf.default_level_style(record.level()); - writeln!( - buf, - "[{}] [{}] {}", - now.format("%Y-%m-%d %H:%M:%S"), - level_style.value(record.level()), - record.args() - ) - }) - .filter(None, LevelFilter::Info) - .init(); - info!("Logger Built.") -} - diff --git a/src/logger_utils.rs b/src/logger_utils.rs new file mode 100644 index 0000000..77b136e --- /dev/null +++ b/src/logger_utils.rs @@ -0,0 +1,22 @@ +use env_logger::Builder; +use log::{info, LevelFilter}; + +pub fn logger_build () { + Builder::new() + .format(|buf, record| { + use std::io::Write; + let now = chrono::Local::now(); + let level_style = buf.default_level_style(record.level()); + writeln!( + buf, + "[{}] [{}] {}", + now.format("%Y-%m-%d %H:%M:%S"), + level_style.value(record.level()), + record.args() + ) + }) + .filter(None, LevelFilter::Info) + .init(); + info!("Logger Built.") +} + -- cgit