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]]
|
[[package]]
|
||||||
name = "libpso"
|
name = "libpso"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+http://git.sharnoth.com/jake/libpso#892d2ed220369f0ff7b7530fa734e722c2b21c2c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"psopacket",
|
"psopacket",
|
||||||
@ -1401,7 +1400,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "psopacket"
|
name = "psopacket"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "git+http://git.sharnoth.com/jake/libpso#892d2ed220369f0ff7b7530fa734e722c2b21c2c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use libpso::character::settings;
|
use libpso::character::settings;
|
||||||
use libpso::character::guildcard;
|
use libpso::character::guildcard;
|
||||||
|
use libpso::packet::ship::{GuildcardAccept};
|
||||||
|
|
||||||
pub const USERFLAG_NEWCHAR: u32 = 0x00000001;
|
pub const USERFLAG_NEWCHAR: u32 = 0x00000001;
|
||||||
pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002;
|
pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002;
|
||||||
@ -9,9 +10,14 @@ pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002;
|
|||||||
pub struct UserAccountId(pub u32);
|
pub struct UserAccountId(pub u32);
|
||||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct UserSettingsId(pub u32);
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct NewUserAccountEntity {
|
pub struct NewUserAccountEntity {
|
||||||
@ -125,19 +131,28 @@ impl NewGuildCardDataEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement this properly
|
// TODO: implement this properly
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct GuildCardDataEntity {
|
pub struct GuildCardDataEntity {
|
||||||
pub id: GuildCardDataId,
|
|
||||||
pub user_id: UserAccountId,
|
pub user_id: UserAccountId,
|
||||||
pub guildcard: guildcard::GuildCardData,
|
pub guildcard_data: Box<guildcard::GuildCardData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuildCardDataEntity {
|
impl GuildCardDataEntity {
|
||||||
pub fn new(user_id: UserAccountId) -> GuildCardDataEntity {
|
pub fn new(user_id: UserAccountId) -> GuildCardDataEntity {
|
||||||
GuildCardDataEntity {
|
GuildCardDataEntity {
|
||||||
id: GuildCardDataId(0),
|
|
||||||
user_id,
|
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!();
|
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> {
|
async fn create_item(&mut self, _item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ pub struct InMemoryGateway {
|
|||||||
equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
|
equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
|
||||||
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
|
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
|
||||||
weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>,
|
weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>,
|
||||||
|
guildcard_entities: Arc<Mutex<BTreeMap<UserAccountId, GuildCardDataEntity>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InMemoryGateway {
|
impl Default for InMemoryGateway {
|
||||||
@ -37,6 +38,7 @@ impl Default for InMemoryGateway {
|
|||||||
equips: Arc::new(Mutex::new(BTreeMap::new())),
|
equips: Arc::new(Mutex::new(BTreeMap::new())),
|
||||||
mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||||
weapon_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 {
|
impl EntityGateway for InMemoryGateway {
|
||||||
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
|
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
|
||||||
let mut users = self.users.lock().unwrap();
|
let mut users = self.users.lock().unwrap();
|
||||||
|
let mut guildcards = self.guildcard_entities.lock().unwrap();
|
||||||
let id = users
|
let id = users
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
|
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
|
||||||
@ -109,7 +112,7 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
id: UserAccountId(id),
|
id: UserAccountId(id),
|
||||||
username: user.username,
|
username: user.username,
|
||||||
password: user.password,
|
password: user.password,
|
||||||
guildcard: user.guildcard,
|
guildcard: id,
|
||||||
team_id: user.team_id,
|
team_id: user.team_id,
|
||||||
banned_until: user.banned_until,
|
banned_until: user.banned_until,
|
||||||
muted_until: user.muted_until,
|
muted_until: user.muted_until,
|
||||||
@ -120,7 +123,11 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
at_character: false,
|
at_character: false,
|
||||||
at_ship: false,
|
at_ship: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let guildcard = GuildCardDataEntity::new(UserAccountId(id)); // TODO: NewGuildcardDataEntity ?
|
||||||
users.insert(user.id, user.clone());
|
users.insert(user.id, user.clone());
|
||||||
|
guildcards.insert(user.id, guildcard.clone());
|
||||||
|
|
||||||
Ok(user)
|
Ok(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,8 +220,14 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: ok_or a real error ?
|
||||||
async fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
|
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> {
|
async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
|
||||||
@ -347,4 +360,10 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
Err(GatewayError::Error)
|
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> {
|
async fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
|
||||||
Ok(GuildCardDataEntity {
|
Ok(GuildCardDataEntity {
|
||||||
id: GuildCardDataId(0),
|
|
||||||
user_id: user.id,
|
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> {
|
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 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 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_data.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);
|
||||||
crc.write(&bytes[..]);
|
crc.write(&bytes[..]);
|
||||||
client.guildcard_data_buffer = Some(bytes.to_vec());
|
client.guildcard_data_buffer = Some(bytes.to_vec());
|
||||||
|
|
||||||
Ok(vec![SendCharacterPacket::GuildcardDataHeader(GuildcardDataHeader::new(bytes.len(), crc.sum32()))])
|
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();
|
entity_gateway.save_character(&client.character).await.unwrap();
|
||||||
Box::new(None.into_iter())
|
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),
|
RequestShipBlockList(RequestShipBlockList),
|
||||||
ItemsToTrade(ItemsToTrade),
|
ItemsToTrade(ItemsToTrade),
|
||||||
TradeConfirmed(TradeConfirmed),
|
TradeConfirmed(TradeConfirmed),
|
||||||
|
GuildcardAccept(GuildcardAccept),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecvServerPacket for RecvShipPacket {
|
impl RecvServerPacket for RecvShipPacket {
|
||||||
@ -155,6 +156,7 @@ impl RecvServerPacket for RecvShipPacket {
|
|||||||
0xD2 => Ok(RecvShipPacket::TradeConfirmed(TradeConfirmed::from_bytes(data)?)),
|
0xD2 => Ok(RecvShipPacket::TradeConfirmed(TradeConfirmed::from_bytes(data)?)),
|
||||||
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
|
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
|
||||||
0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::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()))
|
_ => 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)?;
|
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?
|
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