use rlbot_flat::flat::{
BallPrediction, ConnectionSettings, ControllableTeamInfo, CoreMessage, FieldInfo, GamePacket,
InitComplete, MatchComm, MatchConfiguration, PingResponse, RenderingStatus,
};
use crate::{RLBotConnection, StartingInfo, util::PacketQueue};
use super::AgentError;
#[allow(unused_variables)]
pub trait HivemindAgent {
fn new(
controllable_team_info: ControllableTeamInfo,
match_configuration: MatchConfiguration,
field_info: FieldInfo,
packet_queue: &mut PacketQueue,
) -> Self;
fn tick(&mut self, game_packet: GamePacket, packet_queue: &mut PacketQueue);
fn on_match_comm(&mut self, match_comm: MatchComm, packet_queue: &mut PacketQueue) {}
fn on_ball_prediction(
&mut self,
ball_prediction: BallPrediction,
packet_queue: &mut PacketQueue,
) {
}
fn on_rendering_status(
&mut self,
rendering_status: RenderingStatus,
packet_queue: &mut PacketQueue,
) {
}
fn on_ping_response(&mut self, ping: PingResponse, packet_queue: &mut PacketQueue) {}
}
pub fn run_hivemind_agent<T: HivemindAgent>(
agent_id: String,
wants_ball_predictions: bool,
wants_comms: bool,
mut connection: RLBotConnection,
) -> Result<(), AgentError> {
connection.send_packet(ConnectionSettings {
agent_id,
wants_ball_predictions,
wants_comms,
close_between_matches: true,
})?;
let StartingInfo {
controllable_team_info,
match_configuration,
field_info,
} = connection.get_starting_info()?;
let mut outgoing_queue = PacketQueue::default();
let mut agent = T::new(
controllable_team_info,
match_configuration,
field_info,
&mut outgoing_queue,
);
outgoing_queue.push(InitComplete {});
connection.send_packets_enum(outgoing_queue.empty().into_iter())?;
while let Ok(packet) = connection.recv_packet() {
match packet {
CoreMessage::DisconnectSignal(_) => break,
CoreMessage::GamePacket(x) => {
agent.tick(*x, &mut outgoing_queue);
}
CoreMessage::MatchComm(x) => {
agent.on_match_comm(*x, &mut outgoing_queue);
}
CoreMessage::BallPrediction(x) => {
agent.on_ball_prediction(*x, &mut outgoing_queue);
}
CoreMessage::RenderingStatus(x) => {
agent.on_rendering_status(*x, &mut outgoing_queue);
}
CoreMessage::PingResponse(x) => {
agent.on_ping_response(*x, &mut outgoing_queue);
}
CoreMessage::PingRequest(x) => {
outgoing_queue.push(PingResponse { cookie: x.cookie });
}
CoreMessage::FieldInfo(_)
| CoreMessage::MatchConfiguration(_)
| CoreMessage::ControllableTeamInfo(_) => {
unreachable!("Unexpected packet; should not be able to receive this packet type.")
}
}
connection.send_packets_enum(outgoing_queue.empty().into_iter())?;
}
Ok(())
}