generated from PlexSheep/rs-base
docs: api docs for the challenges
cargo devel CI / cargo CI (push) Successful in 1m29s
Details
cargo devel CI / cargo CI (push) Successful in 1m29s
Details
This commit is contained in:
parent
bfa532cbd2
commit
a841f301f5
|
@ -1,3 +1,8 @@
|
|||
//! The first challenge, in which the contestant only needs to connect by TCP to be sent the secret.
|
||||
//!
|
||||
//! This challenge is designed to be simple and straightforward, requiring the contestant to only
|
||||
//! establish a TCP connection to the server to receive the secret.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use libpt::log::{info, warn};
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
@ -8,13 +13,12 @@ use crate::config::Config;
|
|||
use crate::has_won;
|
||||
use crate::vault::VaultRef;
|
||||
|
||||
/// This struct holds the configuration and vault for the challenge.
|
||||
pub struct C1 {
|
||||
config: Config,
|
||||
vault: VaultRef,
|
||||
}
|
||||
|
||||
impl C1 {}
|
||||
|
||||
#[async_trait]
|
||||
impl Challenge for C1 {
|
||||
fn new(config: Config, vault: VaultRef) -> Self {
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
//! The second challenge, in which the contestant needs to connect by TCP and write a the [u16]
|
||||
//! `1337` to win.
|
||||
//!
|
||||
//! This challenge is designed to be simple and straightforward, but still requires some thinkering
|
||||
//! for newbies, especially those that sill only think in text.
|
||||
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use libpt::log::{info, warn};
|
||||
|
@ -9,12 +15,18 @@ use crate::config::Config;
|
|||
use crate::has_won;
|
||||
use crate::vault::VaultRef;
|
||||
|
||||
/// This struct holds the configuration and vault for the challenge.
|
||||
pub struct C2 {
|
||||
config: Config,
|
||||
vault: VaultRef,
|
||||
}
|
||||
|
||||
impl C2 {
|
||||
/// Trigger the winning mechanism.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will error when writing or shutting down the [TcpStream] fails.
|
||||
async fn win(
|
||||
vault: &VaultRef,
|
||||
stream: &mut TcpStream,
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
//! The third challenge, in which the contestant must answer a series of math questions within a time limit.
|
||||
//!
|
||||
//! This challenge requires the contestant to establish a TCP connection to the server and answer a
|
||||
//! series of math questions that are randomly generated by the server. The contestant must answer
|
||||
//! [NEEDED_CORRECT] questions correctly within a time limit of [MILLIS_PER_QUESTION] milliseconds
|
||||
//! per question. If the contestant fails to answer a question correctly or runs out of time, their
|
||||
//! counter of correct answers will reset.
|
||||
//!
|
||||
//! The math questions are generated randomly and have the form "What is x [op] y?", where [op] is one
|
||||
//! of the four basic arithmetic operations (+, -, *, /) and x and y are random integers between
|
||||
//! 0 and 2^16-1.
|
||||
//!
|
||||
//! The contestant must send their answers as bytes (not text) over the TCP connection.
|
||||
//!
|
||||
//! It is expected that no human can calculate the questions fast enough, so scripting a math
|
||||
//! solver is needed.
|
||||
//!
|
||||
//! See the [sample solution for c3](https://git.cscherr.de/PlexSheep/wooly-vault/src/branch/master/solutions/3.py)
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
|
@ -16,7 +35,9 @@ use crate::has_won;
|
|||
use crate::vault::VaultRef;
|
||||
|
||||
const NEEDED_CORRECT: usize = 16;
|
||||
const MILLIS_PER_QUESTION: u128 = 200;
|
||||
|
||||
/// Signifies the operations that the randomizer can come up with.
|
||||
#[derive(Copy, Clone)]
|
||||
enum Operation {
|
||||
Add,
|
||||
|
@ -26,7 +47,10 @@ enum Operation {
|
|||
}
|
||||
|
||||
impl Operation {
|
||||
pub(crate) fn calc(self, a: i32, b: i32) -> i32 {
|
||||
/// Calculate the result of two [i32] with this [Operation].
|
||||
///
|
||||
/// This will not error from overflows.
|
||||
pub fn calc(self, a: i32, b: i32) -> i32 {
|
||||
match self {
|
||||
Self::Add => a.overflowing_add(b).0,
|
||||
Self::Sub => a.overflowing_sub(b).0,
|
||||
|
@ -63,13 +87,26 @@ impl Distribution<Operation> for Standard {
|
|||
}
|
||||
}
|
||||
|
||||
/// This struct holds the configuration and vault for the challenge.
|
||||
pub struct C3 {
|
||||
config: Config,
|
||||
vault: VaultRef,
|
||||
}
|
||||
|
||||
impl C3 {
|
||||
fn mk_question() -> (String, String) {
|
||||
/// Create a new randomized math question.
|
||||
///
|
||||
/// Questions will always have the same structure:
|
||||
///
|
||||
/// * "What is x y?"
|
||||
///
|
||||
/// $x$ and $y$ will always be a random integer between 0 and 2^16-1.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// This function returns both the question and the solution to that question as a tuple. The
|
||||
/// first is the question and the second is the solution.
|
||||
pub fn mk_question() -> (String, String) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let a: i32 = rng.gen_range(0i32..i16::MAX as i32);
|
||||
let b: i32 = rng.gen_range(0i32..i16::MAX as i32);
|
||||
|
@ -81,7 +118,20 @@ impl C3 {
|
|||
(question, solution)
|
||||
}
|
||||
|
||||
async fn handler(peer: (TcpStream, SocketAddr), vault: &VaultRef) -> Result<()> {
|
||||
/// Handle a singular contestant
|
||||
///
|
||||
/// Messages sent by Wooly Vault [C3] will always be terminated with a newline. [C3] will
|
||||
/// [randomlly generate questions](Self::mk_question) that the contestant needs to solve in
|
||||
/// a given time limit. If the contestant fails to correctly answer [NEEDED_CORRECT] questions
|
||||
/// in the given time limit, their counter of correct answer will reset.
|
||||
///
|
||||
/// The time limit is [the amount of required correct answers](NEEDED_CORRECT) times [the
|
||||
/// milliseconds per question](MILLIS_PER_QUESTION).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if using the [TcpStream] fails.
|
||||
pub async fn handler(peer: (TcpStream, SocketAddr), vault: &VaultRef) -> Result<()> {
|
||||
let mut stream = peer.0;
|
||||
let addr = peer.1;
|
||||
let mut correct: usize = 0;
|
||||
|
@ -98,7 +148,7 @@ impl C3 {
|
|||
Self::win(vault, &mut stream, &addr).await?;
|
||||
break;
|
||||
}
|
||||
if last_reset.elapsed().as_millis() > NEEDED_CORRECT as u128 * 200 {
|
||||
if last_reset.elapsed().as_millis() > NEEDED_CORRECT as u128 * MILLIS_PER_QUESTION {
|
||||
correct = 0;
|
||||
debug!("{addr} was too slow, resetting");
|
||||
stream_write
|
||||
|
|
|
@ -58,6 +58,10 @@ where
|
|||
/// # Returns
|
||||
///
|
||||
/// A result indicating whether the challenge was successful ended.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will error when the challenge errors, for example when the network adress cannot be bound.
|
||||
async fn serve(self) -> anyhow::Result<()>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue