Compare commits
10 commits
edb33ebeec
...
1485cf975d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1485cf975d | ||
|
|
75779c6fe9 | ||
|
|
ae432d79e9 | ||
|
|
4f202c8ade | ||
|
|
f835beef10 | ||
|
|
9ff3aad199 | ||
|
|
958a6718eb | ||
|
|
72a0cf8c69 | ||
|
|
2ddd24fc82 | ||
|
|
db3e0f846e |
11 changed files with 272 additions and 32 deletions
|
|
@ -1,30 +1,6 @@
|
|||
use std::{fmt::Display, io::{self, Read, Write}, net::{TcpStream, ToSocketAddrs}};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
enum PacketType {
|
||||
Login = 3,
|
||||
Command = 2,
|
||||
Response = 0
|
||||
}
|
||||
|
||||
impl PacketType {
|
||||
fn to_le_bytes(self) -> [u8; 4] {
|
||||
(self as i32).to_le_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<i32> for PacketType {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
x if x == Self::Login as i32 => Ok(Self::Login),
|
||||
x if x == Self::Command as i32 => Ok(Self::Command),
|
||||
x if x == Self::Response as i32 => Ok(Self::Response),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
mod packet_type;
|
||||
use packet_type::PacketType;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RconError {
|
||||
25
src/client/packet_type.rs
Normal file
25
src/client/packet_type.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum PacketType {
|
||||
Login = 3,
|
||||
Command = 2,
|
||||
Response = 0
|
||||
}
|
||||
|
||||
impl PacketType {
|
||||
pub fn to_le_bytes(self) -> [u8; 4] {
|
||||
(self as i32).to_le_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<i32> for PacketType {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
x if x == Self::Login as i32 => Ok(Self::Login),
|
||||
x if x == Self::Command as i32 => Ok(Self::Command),
|
||||
x if x == Self::Response as i32 => Ok(Self::Response),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/command/ban.rs
Normal file
33
src/command/ban.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#[derive(Default)]
|
||||
pub struct BanCommand {
|
||||
target: Option<super::Selector>,
|
||||
reason: Option<String>,
|
||||
ip: Option<bool>
|
||||
}
|
||||
|
||||
impl BanCommand {
|
||||
pub fn target(mut self, target: super::Selector) -> Self {
|
||||
self.target = Some(target);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn reason(mut self, reason: impl Into<String>) -> Self {
|
||||
self.reason = Some(reason.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ip(mut self) -> Self {
|
||||
self.ip = Some(true);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
let target = self.target.unwrap_or(super::Selector::Player("nonexistent".to_string()));
|
||||
let ip = self.ip.unwrap_or(false);
|
||||
let mut s = if ip { format!("ban-ip {target}") } else { format!("ban {target}") };
|
||||
if let Some(reason) = self.reason {
|
||||
s.push_str(&format!(" {reason}"));
|
||||
};
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
40
src/command/banlist.rs
Normal file
40
src/command/banlist.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BanlistCommand<State> {
|
||||
state: PhantomData<State>
|
||||
}
|
||||
|
||||
pub struct NoFilter;
|
||||
pub struct Ips;
|
||||
pub struct Players;
|
||||
|
||||
impl BanlistCommand<NoFilter> {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { state: PhantomData }
|
||||
}
|
||||
|
||||
pub fn players(self) -> BanlistCommand<Players> {
|
||||
BanlistCommand { state: PhantomData }
|
||||
}
|
||||
|
||||
pub fn ips(self) -> BanlistCommand<Ips> {
|
||||
BanlistCommand { state: PhantomData }
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
super::Command::raw("banlist")
|
||||
}
|
||||
}
|
||||
|
||||
impl BanlistCommand<Players> {
|
||||
pub fn build(self) -> super::Command {
|
||||
super::Command::raw("banlist players")
|
||||
}
|
||||
}
|
||||
|
||||
impl BanlistCommand<Ips> {
|
||||
pub fn build(self) -> super::Command {
|
||||
super::Command::raw("banlist ips")
|
||||
}
|
||||
}
|
||||
17
src/command/defaultgamemode.rs
Normal file
17
src/command/defaultgamemode.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#[derive(Default)]
|
||||
pub struct DefaultGamemodeCommand {
|
||||
gamemode: Option<super::Gamemode>
|
||||
}
|
||||
|
||||
impl DefaultGamemodeCommand {
|
||||
pub fn gamemode(mut self, gamemode: super::Gamemode) -> Self {
|
||||
self.gamemode = Some(gamemode);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
let gamemode = self.gamemode.unwrap_or(super::Gamemode::Survival);
|
||||
let s = format!("defaultgamemode {gamemode}");
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
17
src/command/deop.rs
Normal file
17
src/command/deop.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#[derive(Default)]
|
||||
pub struct DeopCommand {
|
||||
target: Option<super::Selector>
|
||||
}
|
||||
|
||||
impl DeopCommand {
|
||||
pub fn target(mut self, target: super::Selector) -> Self {
|
||||
self.target = Some(target);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
let target = self.target.unwrap_or(super::Selector::Executor);
|
||||
let s = format!("deop {target}");
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
19
src/command/difficulty.rs
Normal file
19
src/command/difficulty.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#[derive(Default)]
|
||||
pub struct DifficultyCommand {
|
||||
difficulty: Option<super::Difficulty>
|
||||
}
|
||||
|
||||
impl DifficultyCommand {
|
||||
pub fn difficulty(mut self, difficulty: super::Difficulty) -> Self {
|
||||
self.difficulty = Some(difficulty);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
let mut s = format!("difficulty");
|
||||
if let Some(difficulty) = self.difficulty {
|
||||
s.push_str(&format!(" {difficulty}"))
|
||||
};
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
26
src/command/gamemode.rs
Normal file
26
src/command/gamemode.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#[derive(Default)]
|
||||
pub struct GamemodeCommand {
|
||||
gamemode: Option<super::Gamemode>,
|
||||
target: Option<super::Selector>
|
||||
}
|
||||
|
||||
impl GamemodeCommand {
|
||||
pub fn gamemode(mut self, gamemode: super::Gamemode) -> Self {
|
||||
self.gamemode = Some(gamemode);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn target(mut self, target: super::Selector) -> Self {
|
||||
self.target = Some(target);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
let gamemode = self.gamemode.unwrap_or(super::Gamemode::Survival);
|
||||
let mut s = format!("defaultgamemode {gamemode}");
|
||||
if let Some(target) = self.target {
|
||||
s.push_str(&format!(" {target}"))
|
||||
}
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
|
|
@ -11,10 +11,7 @@ impl ListCommand {
|
|||
|
||||
pub fn build(self) -> super::Command {
|
||||
let uuids = self.uuids.unwrap_or(false);
|
||||
let mut s = format!("list");
|
||||
if uuids {
|
||||
s.push_str(" uuids");
|
||||
}
|
||||
let s = format!("list {}", if uuids { "uuids" } else {""} );
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,8 @@ pub enum Selector {
|
|||
AllPlayers, // @a
|
||||
AllEntities, // @e
|
||||
Executor, // @s
|
||||
NearestEntity // @n
|
||||
NearestEntity, // @n,
|
||||
Player(String)
|
||||
}
|
||||
|
||||
impl Display for Selector {
|
||||
|
|
@ -19,7 +20,44 @@ impl Display for Selector {
|
|||
Self::AllPlayers => write!(f, "@a"),
|
||||
Self::AllEntities => write!(f, "@e"),
|
||||
Self::Executor => write!(f, "@s"),
|
||||
Self::NearestEntity => write!(f, "@n")
|
||||
Self::NearestEntity => write!(f, "@n"),
|
||||
Self::Player(name) => write!(f, "{name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Gamemode {
|
||||
Survival,
|
||||
Creative,
|
||||
Adventure,
|
||||
Spectator
|
||||
}
|
||||
|
||||
impl Display for Gamemode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Survival => write!(f, "survival"),
|
||||
Self::Creative => write!(f, "creative"),
|
||||
Self::Adventure => write!(f, "adventure"),
|
||||
Self::Spectator => write!(f, "spectator")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Difficulty {
|
||||
Peaceful,
|
||||
Easy,
|
||||
Normal,
|
||||
Hard
|
||||
}
|
||||
|
||||
impl Display for Difficulty {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Peaceful => write!(f, "peaceful"),
|
||||
Self::Easy => write!(f, "easy"),
|
||||
Self::Normal => write!(f, "normal"),
|
||||
Self::Hard => write!(f, "hard")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +65,13 @@ impl Display for Selector {
|
|||
mod say;
|
||||
mod list;
|
||||
mod kill;
|
||||
mod ban;
|
||||
mod banlist;
|
||||
mod defaultgamemode;
|
||||
mod op;
|
||||
mod deop;
|
||||
mod difficulty;
|
||||
mod gamemode;
|
||||
|
||||
impl Command {
|
||||
pub fn raw(cmd: &str) -> Self {
|
||||
|
|
@ -48,4 +93,32 @@ impl Command {
|
|||
pub fn kill() -> kill::KillCommand {
|
||||
kill::KillCommand::default()
|
||||
}
|
||||
|
||||
pub fn ban() -> ban::BanCommand {
|
||||
ban::BanCommand::default()
|
||||
}
|
||||
|
||||
pub fn banlist() -> banlist::BanlistCommand<banlist::NoFilter> {
|
||||
banlist::BanlistCommand::new()
|
||||
}
|
||||
|
||||
pub fn defaultgamemode() -> defaultgamemode::DefaultGamemodeCommand {
|
||||
defaultgamemode::DefaultGamemodeCommand::default()
|
||||
}
|
||||
|
||||
pub fn op() -> op::OpCommand {
|
||||
op::OpCommand::default()
|
||||
}
|
||||
|
||||
pub fn deop() -> deop::DeopCommand {
|
||||
deop::DeopCommand::default()
|
||||
}
|
||||
|
||||
pub fn difficulty() -> difficulty::DifficultyCommand {
|
||||
difficulty::DifficultyCommand::default()
|
||||
}
|
||||
|
||||
pub fn gamemode() -> gamemode::GamemodeCommand {
|
||||
gamemode::GamemodeCommand::default()
|
||||
}
|
||||
}
|
||||
17
src/command/op.rs
Normal file
17
src/command/op.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#[derive(Default)]
|
||||
pub struct OpCommand {
|
||||
target: Option<super::Selector>
|
||||
}
|
||||
|
||||
impl OpCommand {
|
||||
pub fn target(mut self, target: super::Selector) -> Self {
|
||||
self.target = Some(target);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> super::Command {
|
||||
let target = self.target.unwrap_or(super::Selector::Executor);
|
||||
let s = format!("op {target}");
|
||||
super::Command(s)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue