5_bot_core/
5_bot_core.rs

1extern crate dcss_api;
2
3use dcss_api::Webtile;
4use dcss_api::{BlockingError, Error as APIError};
5use serde_json::Value;
6use std::process;
7
8fn main() {
9    // Connect to DCSS Webtile
10    let mut webtile =
11        Webtile::connect("ws://localhost:8080/socket", 100).expect("Failed to connect");
12
13    // Log in (to a user called "Username", with a password "Password")
14    let gameid = webtile
15        .login_with_credentials("Username", "Password")
16        .expect("Failed to login");
17
18    // Empty message queue;
19    while webtile.get_message().is_some() {}
20
21    // Start a random game on 'dcss-web-trunk', for Minotaur berserker with a mace.
22    webtile
23        .start_game_seeded(&gameid[0], "1", false, "b", "f", "b")
24        .expect("Failed to start game");
25
26    // Process the messages
27    while let Some(message) = webtile.get_message() {
28        processor(&message);
29    }
30
31    // Depending on what is found in the "map" data, a move up may make sense (up to the
32    // bot to decide this) -- note this may if a north wall exists (no bot intelligence here).
33    write_key_bot(&mut webtile, "key_dir_n", "player").expect("Failed");
34    write_key_bot(&mut webtile, "key_dir_s", "player").expect("Failed");
35
36    // Quit game (same as dying)
37    webtile.quit_game().expect("Failed to quit");
38
39    // Disconnect from webtile
40    webtile.disconnect().expect("Failed to disconnect");
41}
42
43fn write_key_bot(
44    webtile: &mut Webtile,
45    to_send: &str,
46    to_receive: &str,
47) -> Result<(), Box<APIError>> {
48    println!("SEND: {}", to_send);
49
50    webtile.write_key(to_send)?;
51
52    // Make sure you verify for blocking errors;
53    if let Err(e) = webtile.read_until(to_receive, None, None) {
54        match *e {
55            APIError::Blocking(BlockingError::More) => webtile.write_key(" ")?,
56            APIError::Blocking(BlockingError::TextInput) => {
57                println!("ERROR: Likely level up choice");
58            }
59            APIError::Blocking(BlockingError::Pickup) => println!("ERROR: Pickup"),
60            APIError::Blocking(BlockingError::Acquirement(_)) => println!("ERROR: Acquirement"),
61            APIError::Blocking(BlockingError::Identify(_)) => println!("ERROR: Identify"),
62            APIError::Blocking(BlockingError::EnchantWeapon(_)) => println!("ERROR: EnchantWeapon"),
63            APIError::Blocking(BlockingError::EnchantItem(_)) => println!("ERROR: EnchantItem"),
64            APIError::Blocking(BlockingError::BrandWeapon(_)) => println!("ERROR: BrandWeapon"),
65            APIError::Blocking(BlockingError::Skill) => println!("ERROR: Skill"),
66            APIError::Blocking(BlockingError::Died) => {
67                println!("ERROR: Died");
68                process::exit(0);
69            }
70            _ => Err(e)?,
71        }
72    }
73
74    // Process the data based on what was done (e.g. new map revealed, health of player...)
75    while let Some(message) = webtile.get_message() {
76        processor(&message);
77    }
78
79    Ok(())
80}
81
82fn processor(message: &Value) {
83    let msg = message["msg"].as_str().unwrap();
84
85    match msg {
86        // Ignore
87        "ping" => (),
88        "lobby_clear" => (),
89        "go_lobby" => (),
90        "html" => (),
91        "set_game_links" => (),
92        "game_client" => (),
93        "chat" => (),
94        "version" => (),
95        "options" => (),
96        "layout" => (),
97        "ui-state-sync" => (),
98        "text_cursor" => (),
99        "cursor" => (),
100        "ui_state" => (),
101        "flash" => (),
102        "ui-stack" => (),
103        "ui-state" => (),
104        "update_menu_items" => (),
105        "close_all_menus" => (),
106        "delay" => (),
107        "menu_scroll" => (),
108        "ui-scroller-scroll" => (),
109        "ui_cutoff" => (),
110        "lobby_complete" => (),
111        "login_success" => (),
112        "game_started" => (),
113
114        // Input & blocking
115        "input_mode" => println!("PROCESS: input_mode"),
116
117        // Messages
118        "msgs" => println!("PROCESS: game log"),
119
120        // Lobby
121        "update_spectators" => println!("PROCESS: number of spectators"),
122
123        // Player
124        "player" => println!("PROCESS: player data"),
125
126        // Dungeon
127        "map" => println!("PROCESS: map data"),
128
129        // Menu
130        "menu" => println!("PROCESS: menu data"),
131        "update_menu" => println!("PROCESS: menu data"),
132        "close_menu" => println!("PROCESS: menu data"),
133        "ui-push" => println!("PROCESS: menu data"),
134        "ui-pop" => println!("PROCESS: menu data"),
135
136        _ => {
137            unreachable!();
138        }
139    };
140}