Browse Source

shared banks wow

pull/130/head
jake 1 year ago
parent
commit
fc5d318ac3
  1. 4
      Cargo.lock
  2. 66
      src/entity/gateway/postgres/postgres.rs
  3. 78
      src/ship/chatcommand.rs
  4. 2
      src/ship/client.rs
  5. 6
      src/ship/items/actions.rs
  6. 11
      src/ship/ship.rs

4
Cargo.lock

@ -1040,7 +1040,7 @@ checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef"
[[package]]
name = "libpso"
version = "0.1.0"
source = "git+http://git.sharnoth.com/jake/libpso#e71b435ea3dde01a44abf0492bfab12236b1ec06"
source = "git+http://git.sharnoth.com/jake/libpso#05222bbf9fe402675447bc163b45e07a327cdb1a"
dependencies = [
"chrono",
"psopacket",
@ -1399,7 +1399,7 @@ dependencies = [
[[package]]
name = "psopacket"
version = "1.0.0"
source = "git+http://git.sharnoth.com/jake/libpso#e71b435ea3dde01a44abf0492bfab12236b1ec06"
source = "git+http://git.sharnoth.com/jake/libpso#05222bbf9fe402675447bc163b45e07a327cdb1a"
dependencies = [
"proc-macro2",
"quote",

66
src/entity/gateway/postgres/postgres.rs

@ -418,8 +418,7 @@ async fn add_weapon_modifier(conn: &mut sqlx::PgConnection, item_id: &ItemEntity
async fn get_character_inventory(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError>
{
// this is some degen shit
let conn = Arc::new(Mutex::new(conn.begin().await?));
let conn = Arc::new(Mutex::new(conn.begin().await?)); // this is some degen shit
let inventory = sqlx::query_as::<_, PgInventoryEntity>("select * from inventory where pchar = $1")
.bind(char_id.0)
.fetch_one(&mut **conn.lock().await).await?;
@ -442,8 +441,7 @@ async fn get_character_inventory(conn: &mut sqlx::PgConnection, char_id: &Charac
async fn get_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<BankEntity, GatewayError>
{
// this is some degen shit
let conn = Arc::new(Mutex::new(conn.begin().await?));
let conn = Arc::new(Mutex::new(conn.begin().await?)); // this is some degen shit
let bank = match bank_identifier {
BankIdentifier::Character => {
sqlx::query_as::<_, PgInventoryEntity>("select * from bank where pchar = $1")
@ -451,15 +449,17 @@ async fn get_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn
.fetch_one(&mut **conn.lock().await).await?
},
BankIdentifier::Shared(bank_name) => {
todo!();
/*
sqlx::query_as::<_, PgInventoryEntity>("select shared_bank.* from shared_bank
left join player_character on shared_bank.user = player_character.user
where player_character.id = $1 and bank.name = $2")
sqlx::query_as::<_, PgInventoryEntity>("select player_character.id as pchar, shared_bank.items as items from shared_bank
join player_character on shared_bank.user_account = player_character.user_account
where player_character.id = $1 and shared_bank.name = $2")
.bind(char_id.0)
.bind(&bank_name.0)
.fetch_one(&mut **conn.lock().await).await?
*/
.fetch_optional(&mut **conn.lock().await)
.await?
.unwrap_or_else(|| PgInventoryEntity {
pchar: char_id.0 as i32,
items: sqlx::types::Json::default(),
})
}
};
@ -519,21 +519,22 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn
match bank_identifier {
BankIdentifier::Character => {
sqlx::query("insert into bank (pchar, items) values ($1, $2) on conflict (pchar, name) do update set items = $2")
sqlx::query("insert into bank (pchar, items, name) values ($1, $2, '') on conflict (pchar, name) do update set items = $2")
.bind(char_id.0)
.bind(sqlx::types::Json(bank))
.execute(conn)
.await?;
},
BankIdentifier::Shared(bank_name) => {
// TODO!
/*
sqlx::query("insert into shared_bank (pchar, items) values ($1, $2) on conflict (pchar, name) do update set items = $2")
sqlx::query("insert into shared_bank (user_account, items, name)
select player_character.user_account, $2, $3 from player_character
where player_character.id = $1
on conflict (user_account, name) do update set items = $2;")
.bind(char_id.0)
.bind(sqlx::types::Json(bank))
.bind(&bank_name.0)
.execute(conn)
.await?;
*/
}
}
Ok(())
@ -569,7 +570,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character
async fn set_character_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError>
{
sqlx::query("insert into character_meseta values ($1, '', $2) on conflict (pchar) do update set meseta = $2")
sqlx::query("insert into character_meseta values ($1, $2) on conflict (pchar) do update set meseta = $2")
.bind(char_id.0)
.bind(meseta.0 as i32)
.execute(conn)
@ -592,14 +593,22 @@ async fn set_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit
{
match bank_identifier {
BankIdentifier::Character => {
sqlx::query("insert into bank_meseta values ($1, '', $2) on conflict pchar do update set meseta = $2")
sqlx::query("insert into bank_meseta values ($1, '', $2) on conflict (pchar, bank) do update set meseta = $2")
.bind(char_id.0)
.bind(meseta.0 as i32)
.execute(conn)
.await?;
},
BankIdentifier::Shared(bank_name) => {
todo!();
sqlx::query("insert into shared_bank_meseta (user_account, name, meseta)
select player_character.user_account, $2, $3 from player_character
where player_character.id = $1
on conflict (user_account, name) do update set meseta = $3")
.bind(char_id.0)
.bind(&bank_name.0)
.bind(meseta.0 as i32)
.execute(conn)
.await?;
}
}
@ -611,18 +620,25 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit
#[derive(sqlx::FromRow)]
struct PgMeseta(i32);
match bank_identifier {
let meseta = match bank_identifier {
BankIdentifier::Character => {
let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from bank_meseta where pchar = $1"#)
sqlx::query_as::<_, PgMeseta>(r#"select meseta from bank_meseta where pchar = $1"#)
.bind(char_id.0)
.fetch_one(conn)
.await?;
Ok(Meseta(meseta.0 as u32))
.await?
},
BankIdentifier::Shared(bank_name) => {
todo!();
sqlx::query_as::<_, PgMeseta>(r#"select shared_bank_meseta.meseta from shared_bank_meseta
join player_character on shared_bank_meseta.user_account = player_character.user_account
where player_character.id = $1 and shared_bank_meseta.name = $2"#)
.bind(char_id.0)
.bind(&bank_name.0)
.fetch_optional(conn)
.await?
.unwrap_or_else(|| PgMeseta(0))
}
}
};
Ok(Meseta(meseta.0 as u32))
}
async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError>

78
src/ship/chatcommand.rs

@ -1,19 +1,89 @@
use libpso::packet::ship::PlayerChat;
use crate::entity::gateway::EntityGateway;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{ShipServerState, SendShipPacket};
use crate::ship::client::Clients;
use crate::ship::items::state::ItemState;
use crate::entity::item::{BankName, BankIdentifier};
use crate::ship::packet::builder::message::bank_item_list;
async fn default_bank<'a, EG, T>(id: ClientId,
tokens: T,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, String>
where
EG: EntityGateway + Clone + 'static,
T: Iterator<Item = &'a str> + 'a,
{
let bank = clients
.with_mut(id, |client| {
let mut item_state = item_state.clone();
let mut entity_gateway = entity_gateway.clone();
Box::pin(async move {
item_state.load_character_bank(&mut entity_gateway, &client.character, BankIdentifier::Character).await?;
item_state.get_character_bank(&client.character).await
})
})
.await
.map_err(|err| format!("an error occured\n{:?}", err))?
.map_err(|err| format!("an error occured\n{:?}", err))?;
let bank_items_pkt = bank_item_list(&bank);
Ok(vec![(id, SendShipPacket::BankItemList(bank_items_pkt))])
}
async fn switch_bank<'a, EG, T>(id: ClientId,
mut tokens: T,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, String>
where
EG: EntityGateway + Clone + 'static,
T: Iterator<Item = &'a str> + 'a,
{
let bank_name = BankName(tokens.next().unwrap_or(&"").into());
let bank = clients
.with_mut(id, |client| {
let mut item_state = item_state.clone();
let mut entity_gateway = entity_gateway.clone();
Box::pin(async move {
item_state.load_character_bank(&mut entity_gateway, &client.character, BankIdentifier::Shared(bank_name)).await?;
item_state.get_character_bank(&client.character).await
})
})
.await
.map_err(|err| format!("an error occured\n{:?}", err))?
.map_err(|err| format!("an error occured\n{:?}", err))?;
let bank_items_pkt = bank_item_list(&bank);
Ok(vec![(id, SendShipPacket::BankItemList(bank_items_pkt))])
}
pub async fn handle_chat_command<EG>(id: ClientId,
message: PlayerChat,
state: &mut ShipServerState<EG>)
-> Option<Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>>
-> Option<Result<Vec<(ClientId, SendShipPacket)>, String>>
where
EG: EntityGateway + Clone + 'static,
{
let mut tokens = message.message
.trim_start_matches("\tJ")
.trim_start_matches("\tE")
.trim_end_matches("\0")
.split_whitespace();
let cmd = tokens.next()?;
match cmd {
"/bank" => Some(default_bank(id, tokens, &mut state.entity_gateway, &state.clients, &mut state.item_state).await),
"/sbank" => Some(switch_bank(id, tokens, &mut state.entity_gateway, &state.clients, &mut state.item_state).await),
_ => None,
}
None
}

2
src/ship/client.rs

@ -137,7 +137,6 @@ pub struct ClientState {
pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>,
pub character_playtime: chrono::Duration,
pub log_on_time: chrono::DateTime<chrono::Utc>,
pub current_bank: item::BankIdentifier,
}
impl ClientState {
@ -161,7 +160,6 @@ impl ClientState {
tek: None,
character_playtime,
log_on_time: chrono::Utc::now(),
current_bank: item::BankIdentifier::Character,
}
}

6
src/ship/items/actions.rs

@ -614,7 +614,8 @@ where
tool,
})
};
inventory.add_item(inventory_item)?.1
inventory.add_item(inventory_item.clone())
.with_context(|| format!("inventory {inventory:?}\nitem {inventory_item:?}"))?.1
},
item_detail => {
let item_entity = transaction.gateway().create_item(NewItemEntity {
@ -631,7 +632,8 @@ where
item: item_detail,
})
};
inventory.add_item(inventory_item)?.1
inventory.add_item(inventory_item.clone())
.with_context(|| format!("inventory {inventory:?}\nitem {inventory_item:?}"))?.1
},
};

11
src/ship/ship.rs

@ -291,6 +291,7 @@ pub enum SendShipPacket {
CancelTrade(CancelTrade),
TradeSuccessful(TradeSuccessful),
LobbyEvent(LobbyEvent),
LargeDialog(LargeDialog),
}
impl SendServerPacket for SendShipPacket {
@ -334,6 +335,7 @@ impl SendServerPacket for SendShipPacket {
SendShipPacket::CancelTrade(pkt) => pkt.as_bytes(),
SendShipPacket::TradeSuccessful(pkt) => pkt.as_bytes(),
SendShipPacket::LobbyEvent(pkt) => pkt.as_bytes(),
SendShipPacket::LargeDialog(pkt) => pkt.as_bytes(),
}
}
}
@ -496,10 +498,10 @@ impl Blocks {
#[derive(Clone)]
pub struct ShipServerState<EG: EntityGateway + Clone + 'static> {
entity_gateway: EG,
pub(crate) entity_gateway: EG,
pub clients: Clients,
name: String,
item_state: items::state::ItemState,
pub(crate) item_state: items::state::ItemState,
shops: ItemShops,
pub blocks: Blocks,
event: ShipEvent,
@ -736,7 +738,10 @@ impl<EG: EntityGateway + Clone> ServerState for ShipServerState<EG> {
RecvShipPacket::PlayerChat(msg) => {
match chatcommand::handle_chat_command(id, msg.clone(), &mut self).await {
Some(ccmd) => {
ccmd?
match ccmd {
Ok(pkts) => pkts,
Err(msg) => vec![(id, SendShipPacket::LargeDialog(LargeDialog::new(msg)))]
}
},
None => {
let block = self.blocks.get_from_client(id, &self.clients).await?;

Loading…
Cancel
Save