|
@ -19,9 +19,11 @@ use crate::entity::character::Character; |
|
|
use crate::login::login::get_login_status;
|
|
|
use crate::login::login::get_login_status;
|
|
|
|
|
|
|
|
|
pub const CHARACTER_PORT: u16 = 12001;
|
|
|
pub const CHARACTER_PORT: u16 = 12001;
|
|
|
|
|
|
const SHIP_MENU_ID: u32 = 1;
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
#[derive(Debug)]
|
|
|
pub enum CharacterError {
|
|
|
pub enum CharacterError {
|
|
|
|
|
|
InvalidMenuSelection(u32, u32),
|
|
|
ClientNotFound(ClientId),
|
|
|
ClientNotFound(ClientId),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@ -36,7 +38,8 @@ pub enum RecvCharacterPacket { |
|
|
ParamDataRequest(ParamDataRequest),
|
|
|
ParamDataRequest(ParamDataRequest),
|
|
|
ParamDataChunkRequest(ParamDataChunkRequest),
|
|
|
ParamDataChunkRequest(ParamDataChunkRequest),
|
|
|
CharacterPreview(CharacterPreview),
|
|
|
CharacterPreview(CharacterPreview),
|
|
|
SetFlag(SetFlag)
|
|
|
|
|
|
|
|
|
SetFlag(SetFlag),
|
|
|
|
|
|
MenuSelect(MenuSelect),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl RecvServerPacket for RecvCharacterPacket {
|
|
|
impl RecvServerPacket for RecvCharacterPacket {
|
|
@ -52,6 +55,7 @@ impl RecvServerPacket for RecvCharacterPacket { |
|
|
0x3EB => Ok(RecvCharacterPacket::ParamDataChunkRequest(ParamDataChunkRequest::from_bytes(data)?)),
|
|
|
0x3EB => Ok(RecvCharacterPacket::ParamDataChunkRequest(ParamDataChunkRequest::from_bytes(data)?)),
|
|
|
0xE5 => Ok(RecvCharacterPacket::CharacterPreview(CharacterPreview::from_bytes(data)?)),
|
|
|
0xE5 => Ok(RecvCharacterPacket::CharacterPreview(CharacterPreview::from_bytes(data)?)),
|
|
|
0xEC => Ok(RecvCharacterPacket::SetFlag(SetFlag::from_bytes(data)?)),
|
|
|
0xEC => Ok(RecvCharacterPacket::SetFlag(SetFlag::from_bytes(data)?)),
|
|
|
|
|
|
0x10 => Ok(RecvCharacterPacket::MenuSelect(MenuSelect::from_bytes(data)?)),
|
|
|
_ => Err(PacketParseError::WrongPacketForServerType)
|
|
|
_ => Err(PacketParseError::WrongPacketForServerType)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@ -71,7 +75,8 @@ pub enum SendCharacterPacket { |
|
|
ParamDataHeader(ParamDataHeader),
|
|
|
ParamDataHeader(ParamDataHeader),
|
|
|
ParamDataChunk(ParamDataChunk),
|
|
|
ParamDataChunk(ParamDataChunk),
|
|
|
Timestamp(Timestamp),
|
|
|
Timestamp(Timestamp),
|
|
|
ShipList(ShipList)
|
|
|
|
|
|
|
|
|
ShipList(ShipList),
|
|
|
|
|
|
RedirectClient(RedirectClient),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl SendServerPacket for SendCharacterPacket {
|
|
|
impl SendServerPacket for SendCharacterPacket {
|
|
@ -89,7 +94,7 @@ impl SendServerPacket for SendCharacterPacket { |
|
|
SendCharacterPacket::ParamDataChunk(pkt) => pkt.as_bytes(),
|
|
|
SendCharacterPacket::ParamDataChunk(pkt) => pkt.as_bytes(),
|
|
|
SendCharacterPacket::Timestamp(pkt) => pkt.as_bytes(),
|
|
|
SendCharacterPacket::Timestamp(pkt) => pkt.as_bytes(),
|
|
|
SendCharacterPacket::ShipList(pkt) => pkt.as_bytes(),
|
|
|
SendCharacterPacket::ShipList(pkt) => pkt.as_bytes(),
|
|
|
//SendLoginPacket::RedirectClient(pkt) => pkt.as_bytes(),
|
|
|
|
|
|
|
|
|
SendCharacterPacket::RedirectClient(pkt) => pkt.as_bytes(),
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@ -180,7 +185,6 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
Ship::new("Thalarion", [127,0,0,1], 23425),
|
|
|
Ship::new("Thalarion", [127,0,0,1], 23425),
|
|
|
];
|
|
|
];
|
|
|
CharacterServerState {
|
|
|
CharacterServerState {
|
|
|
//shared_state: shared_state,
|
|
|
|
|
|
entity_gateway: entity_gateway,
|
|
|
entity_gateway: entity_gateway,
|
|
|
param_header: param_header,
|
|
|
param_header: param_header,
|
|
|
param_data: param_data,
|
|
|
param_data: param_data,
|
|
@ -212,7 +216,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
flag: 0,
|
|
|
flag: 0,
|
|
|
ships: self.ships.iter().enumerate().map(|(i, s)| {
|
|
|
ships: self.ships.iter().enumerate().map(|(i, s)| {
|
|
|
ShipListEntry {
|
|
|
ShipListEntry {
|
|
|
menu: 0,
|
|
|
|
|
|
|
|
|
menu: SHIP_MENU_ID,
|
|
|
item: i as u32,
|
|
|
item: i as u32,
|
|
|
flags: 0,
|
|
|
flags: 0,
|
|
|
name: utf8_to_utf16_array!(s.name, 0x11)
|
|
|
name: utf8_to_utf16_array!(s.name, 0x11)
|
|
@ -313,6 +317,15 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
})
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn select_ship(&mut self, menuselect: &MenuSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
if menuselect.menu != SHIP_MENU_ID {
|
|
|
|
|
|
return Err(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let ship = self.ships.get(menuselect.item as usize)
|
|
|
|
|
|
.ok_or(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item))?;
|
|
|
|
|
|
Ok(vec![SendCharacterPacket::RedirectClient(RedirectClient::new(u32::from_le_bytes(ship.ip), ship.port))])
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
|
|
|
impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
|
|
@ -424,6 +437,9 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { |
|
|
code: 0
|
|
|
code: 0
|
|
|
})
|
|
|
})
|
|
|
].into_iter().map(move |pkt| (id, pkt)))
|
|
|
].into_iter().map(move |pkt| (id, pkt)))
|
|
|
|
|
|
},
|
|
|
|
|
|
RecvCharacterPacket::MenuSelect(menuselect) => {
|
|
|
|
|
|
Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|