Made server and client 1

This commit is contained in:
2026-05-08 23:24:42 +01:00
parent 7db9406ced
commit 7e5874ffbb
14 changed files with 52 additions and 1 deletions
+164
View File
@@ -0,0 +1,164 @@
use std::collections::HashMap;
mod strings;
use crate::
{
// Internal code
character,
api,
// Libraries
mpsc::Receiver,
Arc,
Mutex,
info,
debug,
warn,
};
// Parse the tokens in a file
// Returns success or an error string
pub async fn token_parse(
tokens: &Vec<&str>,
characters: Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: Arc<Mutex<api::DataToSend>>,
rx: &Receiver<(bool,usize)>,
) -> Result<(),String>
{
let mut index: usize = 0;
// Run an infinite loop
loop
{
// If the client hasn't responded then continue (after a short pause)
if rx.recv().is_err()
{
continue
}
// Get the next token
let token = tokens
.get(index)
.ok_or_else(|| "File reached termination point".to_string())?;
// The instructions are related to characters
if token.starts_with('@')
{
let character_name: String = token.chars().skip(1).collect();
info!("Doing something with a character: {}", character_name);
// The index is incremented to after the character's instructions
index += match character_parse(index+1, &tokens, character_name, &characters, &data_to_send).await
{
Ok(increment) => increment,
Err(error) => return Err(error),
};
continue
}
// Miscelleneous instructions
match token.to_lowercase().as_str()
{
"end" =>
{
info!("END command, exiting");
return Ok(()) // quit
},
"choice" =>
{
let (_,jump_points) = match choice_parse(index+1, &tokens, &data_to_send).await
{
Ok((increment,jump_point)) => (increment,jump_point),
Err(error) => return Err(error),
};
if rx.recv().is_err() { warn!("Error sending choices to client"); };
let (_, choice) = rx.recv().unwrap(); // TODO eh
index = jump_points[choice];
debug!("{:?} {} {}",jump_points, choice, index);
continue
}
_ =>
{
warn!("Invalid command: {}", token);
}
}
index += 1;
}
}
// TODO underdev
async fn choice_parse
(
index: usize,
tokens: &Vec<&str>,
data_to_send: &Arc<Mutex<api::DataToSend>>,
) -> Result<(usize, Vec<usize>), String>
{
let mut sum_index: usize = index;
let mut choices: Vec<String> = Vec::new();
let mut choice_indeces: Vec<usize> = Vec::new();
// Ensure the index is valid (the index is not beyond the vector)
let (choice_string, counter) = strings::extract_quoted(&tokens[sum_index..])
.ok_or_else(|| "No choice string".to_string())?;
sum_index += counter;
choices.push(choice_string);
choice_indeces.push(sum_index+1);
sum_index += strings::closing_char(&tokens[sum_index..], '{','}').unwrap() + 1; //TODO eh
while tokens[sum_index].to_lowercase() == "or"
{
let (choice_string, counter) = strings::extract_quoted(&tokens[sum_index+1..])
.ok_or_else(|| "No choice string".to_string())?;
sum_index += counter;
choices.push(choice_string);
choice_indeces.push(sum_index+2);
sum_index += strings::closing_char(&tokens[sum_index..], '{','}').unwrap() + 1; //TODO eh
}
debug!("{:?}", choices);
let mut data = data_to_send.lock().unwrap();
data.action_type = String::from("choice");
data.content = "".to_string();
data.character = "".to_string();
data.choices = choices; //TODO
Ok((sum_index + 1, choice_indeces))
}
// Parsing character related instructions
async fn character_parse
(
index: usize,
tokens: &Vec<&str>,
character_name: String,
characters: &Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: &Arc<Mutex<api::DataToSend>>,
) -> Result<usize,String>
{
let mut sum_index: usize = index;
// Ensure the index is valid (the index is not beyond the vector)
let token = tokens
.get(sum_index)
.ok_or_else(|| "File reached termination point".to_string())?;
match token.to_lowercase().as_str()
{
// The character is saying something, so grab the text and pass it
// to the client
"says" =>
{
info!("SAYS command with character {}", character_name);
match strings::extract_quoted(&tokens[sum_index+1..]) // TODO increment to after the string
{
Some((output_string, counter)) =>
{
debug!("{}", output_string);
sum_index += counter;
let mut data = data_to_send.lock().unwrap();
data.action_type = String::from("output");
data.content = output_string;
data.character = character_name.clone();
data.choices = vec![];
},
None => return Err(String::from("Unable to read string")),
}
},
// Catch all condition, if the instruction is unrecognised as a
// character command
_ => return Err(String::from(format!("Invalid command: {}", token))),
}
sum_index += 1;
Ok(sum_index)
}