|
@ -190,7 +190,7 @@ pub struct CharacterServerState<EG: EntityGateway> { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) {
|
|
|
|
|
|
|
|
|
async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) {
|
|
|
//let mut character = entity_gateway.new_character_by_user(&user);
|
|
|
//let mut character = entity_gateway.new_character_by_user(&user);
|
|
|
//new_character_from_preview(&mut char, preview);
|
|
|
//new_character_from_preview(&mut char, preview);
|
|
|
let mut character = new_character_from_preview(user, preview);
|
|
|
let mut character = new_character_from_preview(user, preview);
|
|
@ -201,7 +201,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE |
|
|
|
|
|
|
|
|
character.meseta = 300;
|
|
|
character.meseta = 300;
|
|
|
|
|
|
|
|
|
let character = entity_gateway.create_character(character).unwrap();
|
|
|
|
|
|
|
|
|
let character = entity_gateway.create_character(character).await.unwrap();
|
|
|
|
|
|
|
|
|
let new_weapon = match character.char_class {
|
|
|
let new_weapon = match character.char_class {
|
|
|
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber,
|
|
|
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber,
|
|
@ -224,7 +224,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE |
|
|
character_id: character.id,
|
|
|
character_id: character.id,
|
|
|
slot: 0,
|
|
|
slot: 0,
|
|
|
equipped: true,
|
|
|
equipped: true,
|
|
|
}});
|
|
|
|
|
|
|
|
|
}}).await;
|
|
|
|
|
|
|
|
|
entity_gateway.create_item(
|
|
|
entity_gateway.create_item(
|
|
|
NewItemEntity {
|
|
|
NewItemEntity {
|
|
@ -239,7 +239,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE |
|
|
character_id: character.id,
|
|
|
character_id: character.id,
|
|
|
slot: 1,
|
|
|
slot: 1,
|
|
|
equipped: true,
|
|
|
equipped: true,
|
|
|
}});
|
|
|
|
|
|
|
|
|
}}).await;
|
|
|
|
|
|
|
|
|
entity_gateway.create_item(
|
|
|
entity_gateway.create_item(
|
|
|
NewItemEntity {
|
|
|
NewItemEntity {
|
|
@ -259,7 +259,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE |
|
|
character_id: character.id,
|
|
|
character_id: character.id,
|
|
|
slot: 2,
|
|
|
slot: 2,
|
|
|
equipped: true,
|
|
|
equipped: true,
|
|
|
}});
|
|
|
|
|
|
|
|
|
}}).await;
|
|
|
|
|
|
|
|
|
for _ in 0..4 {
|
|
|
for _ in 0..4 {
|
|
|
entity_gateway.create_item(
|
|
|
entity_gateway.create_item(
|
|
@ -272,7 +272,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE |
|
|
character_id: character.id,
|
|
|
character_id: character.id,
|
|
|
slot: 3,
|
|
|
slot: 3,
|
|
|
equipped: false,
|
|
|
equipped: false,
|
|
|
}});
|
|
|
|
|
|
|
|
|
}}).await;
|
|
|
entity_gateway.create_item(
|
|
|
entity_gateway.create_item(
|
|
|
NewItemEntity {
|
|
|
NewItemEntity {
|
|
|
item: ItemDetail::Tool (
|
|
|
item: ItemDetail::Tool (
|
|
@ -283,7 +283,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE |
|
|
character_id: character.id,
|
|
|
character_id: character.id,
|
|
|
slot: 4,
|
|
|
slot: 4,
|
|
|
equipped: false,
|
|
|
equipped: false,
|
|
|
}});
|
|
|
|
|
|
|
|
|
}}).await;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@ -307,9 +307,9 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
|
|
|
async fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
Ok(match get_login_status(&self.entity_gateway, pkt) {
|
|
|
|
|
|
|
|
|
Ok(match get_login_status(&self.entity_gateway, pkt).await {
|
|
|
Ok(user) => {
|
|
|
Ok(user) => {
|
|
|
let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new());
|
|
|
let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new());
|
|
|
response.guildcard = user.guildcard;
|
|
|
response.guildcard = user.guildcard;
|
|
@ -337,16 +337,16 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
])
|
|
|
])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn get_settings(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
|
|
|
async fn get_settings(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let user = client.user.as_ref().unwrap();
|
|
|
let user = client.user.as_ref().unwrap();
|
|
|
|
|
|
|
|
|
// TODO: this should error (data should be added on account creation, why did I copy this silly sylv logic?)
|
|
|
// TODO: this should error (data should be added on account creation, why did I copy this silly sylv logic?)
|
|
|
let settings = match self.entity_gateway.get_user_settings_by_user(&user) {
|
|
|
|
|
|
|
|
|
let settings = match self.entity_gateway.get_user_settings_by_user(&user).await {
|
|
|
Some(settings) => settings,
|
|
|
Some(settings) => settings,
|
|
|
None => {
|
|
|
None => {
|
|
|
let user_settings = NewUserSettingsEntity::new(user.id);
|
|
|
let user_settings = NewUserSettingsEntity::new(user.id);
|
|
|
self.entity_gateway.create_user_settings(user_settings).unwrap()
|
|
|
|
|
|
|
|
|
self.entity_gateway.create_user_settings(user_settings).await.unwrap()
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
};
|
|
|
|
|
|
|
|
@ -357,10 +357,10 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
Ok(vec![pkt])
|
|
|
Ok(vec![pkt])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
|
|
|
async fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
if client.characters.is_none() {
|
|
|
if client.characters.is_none() {
|
|
|
client.characters = Some(self.entity_gateway.get_characters_by_user(client.user.as_ref().unwrap()));
|
|
|
|
|
|
|
|
|
client.characters = Some(self.entity_gateway.get_characters_by_user(client.user.as_ref().unwrap()).await);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if select.reason == 0 {
|
|
|
if select.reason == 0 {
|
|
@ -403,9 +403,9 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
})]
|
|
|
})]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
|
|
|
async fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let guildcard_data = self.entity_gateway.get_guild_card_data_by_user(client.user.as_ref().unwrap());
|
|
|
|
|
|
|
|
|
let guildcard_data = self.entity_gateway.get_guild_card_data_by_user(client.user.as_ref().unwrap()).await;
|
|
|
|
|
|
|
|
|
let bytes = guildcard_data.guildcard.as_bytes();
|
|
|
let bytes = guildcard_data.guildcard.as_bytes();
|
|
|
let mut crc = crc32::Digest::new(crc32::IEEE);
|
|
|
let mut crc = crc32::Digest::new(crc32::IEEE);
|
|
@ -431,11 +431,11 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
})
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result<std::option::IntoIter<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
|
|
|
async fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result<std::option::IntoIter<SendCharacterPacket>, CharacterError> {
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let mut user = client.user.as_mut().unwrap();
|
|
|
let mut user = client.user.as_mut().unwrap();
|
|
|
user.flags = setflag.flags;
|
|
|
user.flags = setflag.flags;
|
|
|
self.entity_gateway.save_user(&user);
|
|
|
|
|
|
|
|
|
self.entity_gateway.save_user(&user).await;
|
|
|
Ok(None.into_iter())
|
|
|
Ok(None.into_iter())
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@ -460,11 +460,11 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: move USERFLAGS over to SessionAction
|
|
|
// TODO: move USERFLAGS over to SessionAction
|
|
|
fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
|
|
|
|
|
|
async fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
|
|
|
let mut user = client.user.as_mut().unwrap();
|
|
|
let mut user = client.user.as_mut().unwrap();
|
|
|
if user.flags == USERFLAG_NEWCHAR {
|
|
|
if user.flags == USERFLAG_NEWCHAR {
|
|
|
new_character(&mut self.entity_gateway, &user, preview)
|
|
|
|
|
|
|
|
|
new_character(&mut self.entity_gateway, &user, preview).await
|
|
|
}
|
|
|
}
|
|
|
if user.flags == USERFLAG_DRESSINGROOM {
|
|
|
if user.flags == USERFLAG_DRESSINGROOM {
|
|
|
// TODO: dressing room stuff
|
|
|
// TODO: dressing room stuff
|
|
@ -473,7 +473,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
client.session.action = SessionAction::SelectCharacter;
|
|
|
client.session.action = SessionAction::SelectCharacter;
|
|
|
client.session.character_slot = preview.slot as u8;
|
|
|
client.session.character_slot = preview.slot as u8;
|
|
|
user.flags = 0;
|
|
|
user.flags = 0;
|
|
|
self.entity_gateway.save_user(&user);
|
|
|
|
|
|
|
|
|
self.entity_gateway.save_user(&user).await;
|
|
|
Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard,
|
|
|
Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard,
|
|
|
user.team_id.unwrap_or(1),
|
|
|
user.team_id.unwrap_or(1),
|
|
|
client.session)),
|
|
|
client.session)),
|
|
@ -495,6 +495,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
|
|
|
impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
|
|
|
type SendPacket = SendCharacterPacket;
|
|
|
type SendPacket = SendCharacterPacket;
|
|
|
type RecvPacket = RecvCharacterPacket;
|
|
|
type RecvPacket = RecvCharacterPacket;
|
|
@ -516,7 +517,7 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { |
|
|
]
|
|
|
]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn handle(&mut self, id: ClientId, pkt: &RecvCharacterPacket)
|
|
|
|
|
|
|
|
|
async fn handle(&mut self, id: ClientId, pkt: &RecvCharacterPacket)
|
|
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendCharacterPacket)> + Send>, CharacterError> {
|
|
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendCharacterPacket)> + Send>, CharacterError> {
|
|
|
Ok(match pkt {
|
|
|
Ok(match pkt {
|
|
|
RecvCharacterPacket::Login(login) => {
|
|
|
RecvCharacterPacket::Login(login) => {
|
|
@ -524,20 +525,20 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { |
|
|
Box::new(self.send_ship_list(id, login)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
Box::new(self.send_ship_list(id, login)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
else {
|
|
|
Box::new(self.validate_login(id, login)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
|
|
|
|
|
|
Box::new(self.validate_login(id, login).await?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::RequestSettings(_req) => {
|
|
|
RecvCharacterPacket::RequestSettings(_req) => {
|
|
|
Box::new(self.get_settings(id)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
|
|
|
|
|
|
Box::new(self.get_settings(id).await?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::CharSelect(sel) => {
|
|
|
RecvCharacterPacket::CharSelect(sel) => {
|
|
|
Box::new(self.char_select(id, sel)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
|
|
|
|
|
|
Box::new(self.char_select(id, sel).await?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::Checksum(_checksum) => {
|
|
|
RecvCharacterPacket::Checksum(_checksum) => {
|
|
|
Box::new(self.validate_checksum().into_iter().map(move |pkt| (id, pkt)))
|
|
|
Box::new(self.validate_checksum().into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::GuildcardDataRequest(_request) => {
|
|
|
RecvCharacterPacket::GuildcardDataRequest(_request) => {
|
|
|
Box::new(self.guildcard_data_header(id)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
|
|
|
|
|
|
Box::new(self.guildcard_data_header(id).await?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::GuildcardDataChunkRequest(request) => {
|
|
|
RecvCharacterPacket::GuildcardDataChunkRequest(request) => {
|
|
|
Box::new(self.guildcard_data_chunk(id, request.chunk, request.again)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
Box::new(self.guildcard_data_chunk(id, request.chunk, request.again)?.into_iter().map(move |pkt| (id, pkt)))
|
|
@ -546,13 +547,13 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { |
|
|
Box::new(vec![SendCharacterPacket::ParamDataHeader(self.param_header.clone())].into_iter().map(move |pkt| (id, pkt)))
|
|
|
Box::new(vec![SendCharacterPacket::ParamDataHeader(self.param_header.clone())].into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::SetFlag(flag) => {
|
|
|
RecvCharacterPacket::SetFlag(flag) => {
|
|
|
Box::new(self.set_flag(id, flag)?.map(move |pkt| (id, pkt)))
|
|
|
|
|
|
|
|
|
Box::new(self.set_flag(id, flag).await?.map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::ParamDataChunkRequest(request) => {
|
|
|
RecvCharacterPacket::ParamDataChunkRequest(request) => {
|
|
|
Box::new(self.param_data_chunk_request(id, request)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
Box::new(self.param_data_chunk_request(id, request)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::CharacterPreview(preview) => {
|
|
|
RecvCharacterPacket::CharacterPreview(preview) => {
|
|
|
Box::new(self.character_preview(id, preview)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
|
|
|
|
|
|
Box::new(self.character_preview(id, preview).await?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
},
|
|
|
},
|
|
|
RecvCharacterPacket::MenuSelect(menuselect) => {
|
|
|
RecvCharacterPacket::MenuSelect(menuselect) => {
|
|
|
Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|
Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt)))
|
|
|