f is for friends who do stuff together
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
19bcb20b49
commit
24fdd705c5
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1001,7 +1001,6 @@ checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef"
|
||||
[[package]]
|
||||
name = "libpso"
|
||||
version = "0.1.0"
|
||||
source = "git+http://git.sharnoth.com/jake/libpso#892d2ed220369f0ff7b7530fa734e722c2b21c2c"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"psopacket",
|
||||
@ -1401,7 +1400,6 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "psopacket"
|
||||
version = "1.0.0"
|
||||
source = "git+http://git.sharnoth.com/jake/libpso#892d2ed220369f0ff7b7530fa734e722c2b21c2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1,6 +1,7 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use libpso::character::settings;
|
||||
use libpso::character::guildcard;
|
||||
use libpso::packet::ship::{GuildcardAccept};
|
||||
|
||||
pub const USERFLAG_NEWCHAR: u32 = 0x00000001;
|
||||
pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002;
|
||||
@ -9,9 +10,14 @@ pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002;
|
||||
pub struct UserAccountId(pub u32);
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct UserSettingsId(pub u32);
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct GuildCardDataId(pub u32);
|
||||
|
||||
// TODO: use these
|
||||
#[derive(Debug)]
|
||||
pub enum GuildcardError {
|
||||
GuildcardAlreadyFriend(u32),
|
||||
GuildcardAlreadyBlocked(u32),
|
||||
GuildcardListFull,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NewUserAccountEntity {
|
||||
@ -125,19 +131,28 @@ impl NewGuildCardDataEntity {
|
||||
}
|
||||
|
||||
// TODO: implement this properly
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GuildCardDataEntity {
|
||||
pub id: GuildCardDataId,
|
||||
pub user_id: UserAccountId,
|
||||
pub guildcard: guildcard::GuildCardData,
|
||||
pub guildcard_data: Box<guildcard::GuildCardData>,
|
||||
}
|
||||
|
||||
impl GuildCardDataEntity {
|
||||
pub fn new(user_id: UserAccountId) -> GuildCardDataEntity {
|
||||
GuildCardDataEntity {
|
||||
id: GuildCardDataId(0),
|
||||
user_id,
|
||||
guildcard: guildcard::GuildCardData::default(),
|
||||
guildcard_data: Box::new(guildcard::GuildCardData::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_friend(&mut self, new_friend: &GuildcardAccept) -> Result<(), GuildcardError> {
|
||||
let next_open_spot = self.guildcard_data.friends
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_i, g)| g.id == 0)
|
||||
.ok_or(GuildcardError::GuildcardListFull)?
|
||||
.0;
|
||||
self.guildcard_data.friends[next_open_spot] = guildcard::GuildCard::from(new_friend);
|
||||
Ok(()) // TODO: implement a real error
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,10 @@ pub trait EntityGateway: Send + Sync + Clone {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn set_guild_card(&mut self, _id: UserAccountId, _gc_data: GuildCardDataEntity) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn create_item(&mut self, _item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ pub struct InMemoryGateway {
|
||||
equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
|
||||
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
|
||||
weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>,
|
||||
guildcard_entities: Arc<Mutex<BTreeMap<UserAccountId, GuildCardDataEntity>>>,
|
||||
}
|
||||
|
||||
impl Default for InMemoryGateway {
|
||||
@ -37,6 +38,7 @@ impl Default for InMemoryGateway {
|
||||
equips: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
weapon_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
guildcard_entities: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,6 +103,7 @@ impl InMemoryGateway {
|
||||
impl EntityGateway for InMemoryGateway {
|
||||
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
|
||||
let mut users = self.users.lock().unwrap();
|
||||
let mut guildcards = self.guildcard_entities.lock().unwrap();
|
||||
let id = users
|
||||
.iter()
|
||||
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
|
||||
@ -109,7 +112,7 @@ impl EntityGateway for InMemoryGateway {
|
||||
id: UserAccountId(id),
|
||||
username: user.username,
|
||||
password: user.password,
|
||||
guildcard: user.guildcard,
|
||||
guildcard: id,
|
||||
team_id: user.team_id,
|
||||
banned_until: user.banned_until,
|
||||
muted_until: user.muted_until,
|
||||
@ -120,7 +123,11 @@ impl EntityGateway for InMemoryGateway {
|
||||
at_character: false,
|
||||
at_ship: false,
|
||||
};
|
||||
|
||||
let guildcard = GuildCardDataEntity::new(UserAccountId(id)); // TODO: NewGuildcardDataEntity ?
|
||||
users.insert(user.id, user.clone());
|
||||
guildcards.insert(user.id, guildcard.clone());
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
@ -213,8 +220,14 @@ impl EntityGateway for InMemoryGateway {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: ok_or a real error ?
|
||||
async fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
|
||||
Ok(GuildCardDataEntity::new(user.id))
|
||||
let guildcards = self.guildcard_entities.lock().unwrap();
|
||||
guildcards
|
||||
.iter()
|
||||
.find(|(_, g)| g.user_id == user.id)
|
||||
.map(|(_, g)| g.clone())
|
||||
.ok_or(GatewayError::Error)
|
||||
}
|
||||
|
||||
async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
|
||||
@ -347,4 +360,10 @@ impl EntityGateway for InMemoryGateway {
|
||||
Err(GatewayError::Error)
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_guild_card(&mut self, id: UserAccountId, gc_data: GuildCardDataEntity) -> Result<(), GatewayError> {
|
||||
let mut guildcard = self.guildcard_entities.lock().unwrap();
|
||||
guildcard.insert(id, gc_data);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -278,9 +278,8 @@ impl EntityGateway for PostgresGateway {
|
||||
|
||||
async fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
|
||||
Ok(GuildCardDataEntity {
|
||||
id: GuildCardDataId(0),
|
||||
user_id: user.id,
|
||||
guildcard: guildcard::GuildCardData::default(),
|
||||
guildcard_data: Box::new(guildcard::GuildCardData::default()),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -441,12 +441,10 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
|
||||
async fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, anyhow::Error> {
|
||||
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()).await.map_err(|_| CharacterError::CouldNotLoadGuildcard)?;
|
||||
|
||||
let bytes = guildcard_data.guildcard.as_bytes();
|
||||
let bytes = guildcard_data.guildcard_data.as_bytes();
|
||||
let mut crc = crc32::Digest::new(crc32::IEEE);
|
||||
crc.write(&bytes[..]);
|
||||
client.guildcard_data_buffer = Some(bytes.to_vec());
|
||||
|
||||
Ok(vec![SendCharacterPacket::GuildcardDataHeader(GuildcardDataHeader::new(bytes.len(), crc.sum32()))])
|
||||
}
|
||||
|
||||
|
@ -45,3 +45,17 @@ pub async fn write_infoboard<EG: EntityGateway>(id: ClientId,
|
||||
entity_gateway.save_character(&client.character).await.unwrap();
|
||||
Box::new(None.into_iter())
|
||||
}
|
||||
|
||||
// TODO: return Result<Box<...>> so ship can do await? and catch errors?
|
||||
pub async fn accept_guildcard<EG: EntityGateway>(id: ClientId,
|
||||
accepted_card: &GuildcardAccept,
|
||||
clients: &mut Clients,
|
||||
entity_gateway: &mut EG)
|
||||
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
|
||||
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
|
||||
|
||||
let mut gc_data = entity_gateway.get_guild_card_data_by_user(&client.user).await.unwrap();
|
||||
gc_data.add_friend(accepted_card).unwrap();
|
||||
entity_gateway.set_guild_card(client.user.id, gc_data).await.unwrap();
|
||||
Box::new(None.into_iter()) // TODO: does the server need to return anything to any client? everything seems to work fine like this...
|
||||
}
|
@ -114,6 +114,7 @@ pub enum RecvShipPacket {
|
||||
RequestShipBlockList(RequestShipBlockList),
|
||||
ItemsToTrade(ItemsToTrade),
|
||||
TradeConfirmed(TradeConfirmed),
|
||||
GuildcardAccept(GuildcardAccept),
|
||||
}
|
||||
|
||||
impl RecvServerPacket for RecvShipPacket {
|
||||
@ -155,6 +156,7 @@ impl RecvServerPacket for RecvShipPacket {
|
||||
0xD2 => Ok(RecvShipPacket::TradeConfirmed(TradeConfirmed::from_bytes(data)?)),
|
||||
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
|
||||
0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)),
|
||||
0x4E8 => Ok(RecvShipPacket::GuildcardAccept(GuildcardAccept::from_bytes(data)?)),
|
||||
_ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec()))
|
||||
}
|
||||
}
|
||||
@ -743,6 +745,9 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
||||
let block = self.blocks.with_client(id, &self.clients)?;
|
||||
handler::trade::trade_confirmed(id, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager, &mut self.trades).await?
|
||||
},
|
||||
RecvShipPacket::GuildcardAccept(guildcard_accept) => {
|
||||
handler::communication::accept_guildcard(id, guildcard_accept, &mut self.clients, &mut self.entity_gateway).await
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user