rust/hedgewars-server/src/server/io.rs
author Wuzzy <Wuzzy2@mail.ru>
Thu, 11 Jul 2019 16:24:09 +0200
changeset 15231 c10e9261ab9c
parent 15120 febccab419b1
child 15532 f1205f33bf5b
permissions -rw-r--r--
Make lowest line of Splash image frames transparent to work around scaling issues The Splash image is scaled. Sometimes, the lowest line is repeated on the top, which caused some weird lines to appear above big splashes (e.g. piano). This has been done fully automated with a script. Only the alpha channel was changed. The color information is preserved.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15120
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     1
use std::{
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     2
    fs::{File, OpenOptions},
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     3
    io::{Error, ErrorKind, Read, Result, Write},
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     4
    sync::mpsc,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     5
    thread,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     6
};
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     7
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     8
use crate::{
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
     9
    handlers::{IoResult, IoTask},
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    10
    server::database::Database,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    11
};
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    12
use log::*;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    13
use mio::{Evented, Poll, PollOpt};
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    14
use mio_extras::channel;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    15
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    16
pub type RequestId = u32;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    17
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    18
pub struct IoThread {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    19
    core_tx: mpsc::Sender<(RequestId, IoTask)>,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    20
    core_rx: channel::Receiver<(RequestId, IoResult)>,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    21
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    22
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    23
impl IoThread {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    24
    pub fn new() -> Self {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    25
        let (core_tx, io_rx) = mpsc::channel();
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    26
        let (io_tx, core_rx) = channel::channel();
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    27
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    28
        let mut db = Database::new();
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    29
        db.connect("localhost");
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    30
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    31
        thread::spawn(move || {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    32
            while let Ok((request_id, task)) = io_rx.recv() {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    33
                let response = match task {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    34
                    IoTask::CheckRegistered { nick } => match db.is_registered(&nick) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    35
                        Ok(is_registered) => IoResult::AccountRegistered(is_registered),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    36
                        Err(e) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    37
                            warn!("Unable to check account's existence: {}", e);
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    38
                            IoResult::AccountRegistered(false)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    39
                        }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    40
                    },
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    41
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    42
                    IoTask::GetAccount {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    43
                        nick,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    44
                        protocol,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    45
                        password_hash,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    46
                        client_salt,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    47
                        server_salt,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    48
                    } => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    49
                        match db.get_account(
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    50
                            &nick,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    51
                            protocol,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    52
                            &password_hash,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    53
                            &client_salt,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    54
                            &server_salt,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    55
                        ) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    56
                            Ok(account) => IoResult::Account(account),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    57
                            Err(e) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    58
                                warn!("Unable to get account data: {}", e);
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    59
                                IoResult::Account(None)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    60
                            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    61
                        }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    62
                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    63
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    64
                    IoTask::GetReplay { id } => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    65
                        let result = match db.get_replay_name(id) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    66
                            Ok(Some(filename)) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    67
                                let filename = format!(
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    68
                                    "checked/{}",
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    69
                                    if filename.starts_with("replays/") {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    70
                                        &filename[8..]
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    71
                                    } else {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    72
                                        &filename
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    73
                                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    74
                                );
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    75
                                match load_file(&filename) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    76
                                    Ok(contents) => Some(unimplemented!()),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    77
                                    Err(e) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    78
                                        warn!(
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    79
                                            "Error while writing the room config file \"{}\": {}",
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    80
                                            filename, e
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    81
                                        );
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    82
                                        None
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    83
                                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    84
                                }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    85
                            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    86
                            Ok(None) => None,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    87
                            Err(e) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    88
                                warn!("Unable to get replay name: {}", e);
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    89
                                None
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    90
                            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    91
                        };
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    92
                        IoResult::Replay(result)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    93
                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    94
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    95
                    IoTask::SaveRoom {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    96
                        room_id,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    97
                        filename,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    98
                        contents,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
    99
                    } => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   100
                        let result = match save_file(&filename, &contents) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   101
                            Ok(()) => true,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   102
                            Err(e) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   103
                                warn!(
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   104
                                    "Error while writing the room config file \"{}\": {}",
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   105
                                    filename, e
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   106
                                );
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   107
                                false
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   108
                            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   109
                        };
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   110
                        IoResult::SaveRoom(room_id, result)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   111
                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   112
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   113
                    IoTask::LoadRoom { room_id, filename } => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   114
                        let result = match load_file(&filename) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   115
                            Ok(contents) => Some(contents),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   116
                            Err(e) => {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   117
                                warn!(
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   118
                                    "Error while writing the room config file \"{}\": {}",
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   119
                                    filename, e
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   120
                                );
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   121
                                None
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   122
                            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   123
                        };
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   124
                        IoResult::LoadRoom(room_id, result)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   125
                    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   126
                };
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   127
                io_tx.send((request_id, response));
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   128
            }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   129
        });
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   130
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   131
        Self { core_rx, core_tx }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   132
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   133
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   134
    pub fn send(&self, request_id: RequestId, task: IoTask) {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   135
        self.core_tx.send((request_id, task)).unwrap();
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   136
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   137
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   138
    pub fn try_recv(&self) -> Option<(RequestId, IoResult)> {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   139
        match self.core_rx.try_recv() {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   140
            Ok(result) => Some(result),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   141
            Err(mpsc::TryRecvError::Empty) => None,
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   142
            Err(mpsc::TryRecvError::Disconnected) => unreachable!(),
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   143
        }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   144
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   145
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   146
    pub fn register_rx(&self, poll: &mio::Poll, token: mio::Token) -> Result<()> {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   147
        self.core_rx
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   148
            .register(poll, token, mio::Ready::readable(), PollOpt::edge())
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   149
    }
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   150
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   151
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   152
fn save_file(filename: &str, contents: &str) -> Result<()> {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   153
    let mut writer = OpenOptions::new().create(true).write(true).open(filename)?;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   154
    writer.write_all(contents.as_bytes())
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   155
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   156
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   157
fn load_file(filename: &str) -> Result<String> {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   158
    let mut reader = File::open(filename)?;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   159
    let mut result = String::new();
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   160
    reader.read_to_string(&mut result)?;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   161
    Ok(result)
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 15103
diff changeset
   162
}