commit 5afb293534aa413ab66702c809dd6e574a0bd555 Author: Andrew Pamment Date: Wed Nov 15 16:38:56 2023 +1000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a7cdc13 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,114 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bbslist" +version = "0.1.0" +dependencies = [ + "doorlib", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "doorlib" +version = "0.1.0" +source = "git+https://gitlab.com/apamment/doorlib#97009dee9311929362be2075cf0becfa4370ddf8" +dependencies = [ + "termios", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termios" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +dependencies = [ + "libc", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7c9d718 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "bbslist" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +doorlib = { git = "https://gitlab.com/apamment/doorlib" } +serde = "1.0.136" +serde_derive = "1.0.136" +serde_json = "1.0.79" \ No newline at end of file diff --git a/bbslist.ans b/bbslist.ans new file mode 100644 index 0000000..eed79b8 --- /dev/null +++ b/bbslist.ans @@ -0,0 +1,25 @@ +  + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³³ + ³³ ÜÛTELNET ADDRESSÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ³³ Û + ³³ + ³³ ÜÛSSH ADDRESSÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ³³ Û + ³³ + ³³ ÜÛSOFTWAREÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ³³ Û + ³³ + ³³ ÜÛLOCATIONÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ³³ Û + ³³ + ³³ ÜÛSYSOPÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ³³ Û + ³³ + ³³ ÜÛDESCRIPTIONÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ³³ Û + ³³ Û + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +    Scroll Listings A Add an Entry Q Quit to BBS  +  + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..efde407 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,228 @@ +use doorlib::{door_clear_screen, door_display_file, door_init, door_read_string, esc, Conn, User}; +use serde_derive::{Deserialize, Serialize}; +use std::error::Error; +use std::fs::File; +use std::io::BufReader; + +#[derive(Deserialize, Serialize)] +struct BbsEntry { + name: String, + telnet: String, + ssh: String, + software: String, + location: String, + desc: String, + sysop: String, +} + +fn load_bbslist() -> Result, Box> { + let file = File::open("bbslist.json")?; + + let reader = BufReader::new(file); + + Ok(serde_json::from_reader(reader)?) +} + +fn door_main(mut u: User) -> Result<(), Box> { + let mut bbslist = load_bbslist().unwrap_or_default(); + + let mut index = 0; + let mut start = 0; + + door_clear_screen(&mut u)?; + door_display_file(&mut u, "bbslist.ans")?; + u.write_str( + format!( + "{}{} BBS List v2.0 - There are {} BBSes in this list!{}{}", + esc!("[1;1H"), + esc!("[0;30;46m"), + bbslist.len(), + esc!("[K"), + esc!("[0m") + ) + .as_str(), + )?; + loop { + for i in start..start + 19 { + let p = format!("\x1b[{};3H", (i - start) + 3); + if i < bbslist.len() { + if i == index { + u.write_ln( + format!( + "{}{}{:<35}{}", + p, + esc!("[1;37;45m"), + bbslist[i].name, + esc!("[0m") + ) + .as_str(), + )?; + + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[2;41H"), + esc!("[1;32m"), + bbslist[i].name, + esc! {"[0m"} + ) + .as_str(), + )?; + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[5;42H"), + esc!("[1;33m"), + bbslist[i].telnet, + esc! {"[0m"} + ) + .as_str(), + )?; + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[8;42H"), + esc!("[1;33m"), + bbslist[i].ssh, + esc! {"[0m"} + ) + .as_str(), + )?; + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[11;42H"), + esc!("[1;33m"), + bbslist[i].software, + esc! {"[0m"} + ) + .as_str(), + )?; + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[14;42H"), + esc!("[1;33m"), + bbslist[i].location, + esc! {"[0m"} + ) + .as_str(), + )?; + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[17;42H"), + esc!("[1;33m"), + bbslist[i].sysop, + esc! {"[0m"} + ) + .as_str(), + )?; + u.write_ln( + format!( + "{}{}{:<35}{}", + esc!("[20;42H"), + esc!("[1;33m"), + bbslist[i].desc, + esc! {"[0m"} + ) + .as_str(), + )?; + } else { + u.write_ln( + format!( + "{}{}{:<37}{}", + p, + esc!("[1;37m"), + bbslist[i].name, + esc!("[0m") + ) + .as_str(), + )?; + } + } else { + u.write_ln(format!("{} ", p).as_str())?; + } + } + + let mut ch = u.read_byte()?; + + if ch == b'\x1b' { + ch = u.read_byte()?; + if ch == b'[' { + ch = u.read_byte()?; + if ch == b'A' { + // up + if index > 0 { + index -= 1; + if index < start { + start -= 19; + } + } + } else if ch == b'B' { + // down + + if !bbslist.is_empty() && index < bbslist.len() - 1 { + index += 1; + if index >= start + 19 { + start += 19; + } + } + } + } + } else if ch == b'q' || ch == b'Q' { + break; + } else if ch == b'a' || ch == b'A' { + door_clear_screen(&mut u)?; + + u.write_str(" Your BBS Name: ")?; + let name = door_read_string(&mut u, 35)?; + u.write_str("\r\n Telnet Address: ")?; + let telnet = door_read_string(&mut u, 37)?; + u.write_str("\r\n SSH Address: ")?; + let ssh = door_read_string(&mut u, 37)?; + u.write_str("\r\n BBS Software: ")?; + let software = door_read_string(&mut u, 37)?; + u.write_str("\r\n Location: ")?; + let location = door_read_string(&mut u, 37)?; + u.write_str("\r\n Sysop Name: ")?; + let sysop = door_read_string(&mut u, 37)?; + u.write_str("\r\nShort Description: ")?; + let desc = door_read_string(&mut u, 37)?; + + bbslist.push(BbsEntry { + name, + telnet, + ssh, + software, + location, + sysop, + desc, + }); + + let file = File::create("bbslist.json")?; + serde_json::to_writer_pretty(file, &bbslist)?; + + door_clear_screen(&mut u)?; + door_display_file(&mut u, "bbslist.ans")?; + u.write_str( + format!( + "{}{} BBS List v2.0 - There are {} BBSes in this list!{}{}", + esc!("[1;1H"), + esc!("[0;30;46m"), + bbslist.len(), + esc!("[K"), + esc!("[0m") + ) + .as_str(), + )?; + } + } + Ok(()) +} + +fn main() { + let u = door_init().unwrap(); + + let _ = door_main(u); +}