1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pub mod store;

use self::store::Store;
use crate::{packet::Packet, RELAY_CHANNEL_START_INDEX};
use classicube_helpers::{events::net::PluginMessageReceivedEventHandler, tick};
use classicube_sys::EventAPIVersion;
use std::{
    cell::RefCell,
    io::{Cursor, Write},
    rc::Rc,
};
use tracing::error;

pub type CallbackFn = Box<dyn Fn(u8, &[u8])>;

#[derive(Debug, thiserror::Error)]
pub enum PartialStreamError {
    #[error("{0} < RELAY_CHANNEL_START_INDEX")]
    StartIndex(u8),

    #[error(transparent)]
    Io(#[from] std::io::Error),

    #[error("EventAPIVersion == 0")]
    EventAPIVersion,
}
type Result<T> = std::result::Result<T, PartialStreamError>;

#[derive(Debug)]
struct PartialStream {
    player_id: u8,
    data_length: u16,
    data_buffer: Vec<u8>,
}

impl PartialStream {
    pub fn is_finished(&self) -> bool {
        self.data_buffer.len() == self.data_length as usize
    }

    pub fn write_part(&mut self, data_part: Vec<u8>) -> Result<()> {
        let len = data_part
            .len()
            .min(self.data_length as usize - self.data_buffer.len());
        self.data_buffer.write_all(&data_part[..len])?;

        Ok(())
    }
}

pub struct RelayListener {
    pub channel: u8,
    store: Rc<RefCell<Store>>,
    _plugin_message_handler: PluginMessageReceivedEventHandler,
    _tick_handler: tick::TickEventHandler,
}

impl RelayListener {
    pub fn new(channel: u8) -> Result<Self> {
        if channel < RELAY_CHANNEL_START_INDEX {
            return Err(PartialStreamError::StartIndex(channel));
        }

        if unsafe { EventAPIVersion } == 0 {
            return Err(PartialStreamError::EventAPIVersion);
        }

        let store: Rc<RefCell<Store>> = Default::default();

        let mut plugin_message_handler = PluginMessageReceivedEventHandler::new();
        {
            let store = Rc::downgrade(&store);
            plugin_message_handler.on(move |event| {
                if channel != event.channel {
                    return;
                }

                if let Some(store) = store.upgrade() {
                    let mut store = store.borrow_mut();
                    let store = &mut *store;
                    match Packet::decode(&mut Cursor::new(&event.data)) {
                        Ok(packet) => {
                            if let Err(e) = store.process_packet(packet) {
                                error!("processing packet: {:#?}", e);
                            }
                        }

                        Err(e) => {
                            error!("decoding packet: {:#?}", e);
                        }
                    }
                }
            });
        }
        let mut tick_handler = tick::TickEventHandler::new();
        {
            let store = Rc::downgrade(&store);
            tick_handler.on(move |_event| {
                if let Some(store) = store.upgrade() {
                    let mut store = store.borrow_mut();
                    let store = &mut *store;
                    store.tick();
                }
            });
        }

        Ok(Self {
            channel,
            store,
            _plugin_message_handler: plugin_message_handler,
            _tick_handler: tick_handler,
        })
    }

    pub fn on<F>(&mut self, callback: F)
    where
        F: Fn(u8, &[u8]),
        F: 'static,
    {
        let mut store = self.store.borrow_mut();
        store.event_handlers.push(Box::new(callback));
    }
}