characters can save kbm/gamepad configs
This commit is contained in:
		
							parent
							
								
									0b8aef3b8c
								
							
						
					
					
						commit
						b3e7d2b4b5
					
				| @ -2,8 +2,8 @@ use std::convert::{From, Into}; | ||||
| use std::collections::HashMap; | ||||
| use serde::{Serialize, Deserialize}; | ||||
| 
 | ||||
| use libpso::packet::ship::{UpdateConfig, WriteInfoboard, KeyboardConfig}; | ||||
| use libpso::character::character::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU, DEFAULT_KEYBOARD_CONFIG1}; | ||||
| use libpso::packet::ship::{UpdateConfig, WriteInfoboard, KeyboardConfig, GamepadConfig}; | ||||
| use libpso::character::settings::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU, DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG2, DEFAULT_KEYBOARD_CONFIG3, DEFAULT_KEYBOARD_CONFIG4, DEFAULT_GAMEPAD_CONFIG}; | ||||
| use crate::entity::item::tech::Technique; | ||||
| use crate::entity::account::UserAccountId; | ||||
| 
 | ||||
| @ -266,25 +266,71 @@ pub struct CharacterMaterials { | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct CharacterKeyboardConfig { | ||||
|     pub keyboard: [u8; 0x16C], | ||||
|     pub keyboard_config: [u8; 0x16C], | ||||
| } | ||||
| 
 | ||||
| impl CharacterKeyboardConfig { | ||||
|     fn new() -> CharacterKeyboardConfig { | ||||
|     fn new(preset: usize) -> CharacterKeyboardConfig { | ||||
|         match preset { | ||||
|             1 => { | ||||
|                 CharacterKeyboardConfig { | ||||
|             keyboard: DEFAULT_KEYBOARD_CONFIG1, | ||||
|                     keyboard_config: DEFAULT_KEYBOARD_CONFIG1, | ||||
|                 } | ||||
|             }, | ||||
|             2 => { | ||||
|                 CharacterKeyboardConfig { | ||||
|                     keyboard_config: DEFAULT_KEYBOARD_CONFIG2, | ||||
|                 } | ||||
|             }, | ||||
|             3 => { | ||||
|                 CharacterKeyboardConfig { | ||||
|                     keyboard_config: DEFAULT_KEYBOARD_CONFIG3, | ||||
|                 } | ||||
|             }, | ||||
|             4 => { | ||||
|                 CharacterKeyboardConfig { | ||||
|                     keyboard_config: DEFAULT_KEYBOARD_CONFIG4, | ||||
|                 } | ||||
|             }, | ||||
|             _ => { | ||||
|                 CharacterKeyboardConfig { | ||||
|                     keyboard_config: DEFAULT_KEYBOARD_CONFIG1, | ||||
|                 }        
 | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn update(&mut self, new_config: &KeyboardConfig) { | ||||
|         self.keyboard = new_config.keyboard_config; | ||||
|         self.keyboard_config = new_config.keyboard_config; | ||||
|     } | ||||
| 
 | ||||
|     pub fn as_bytes(&self) -> [u8; 0x16C] { | ||||
|         self.keyboard | ||||
|         self.keyboard_config | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct CharacterGamepadConfig { | ||||
|     pub gamepad_config: [u8; 56], | ||||
| } | ||||
| 
 | ||||
| impl Default for CharacterGamepadConfig { | ||||
|     fn default() -> CharacterGamepadConfig { | ||||
|         CharacterGamepadConfig { | ||||
|             gamepad_config: [0; 56], | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CharacterGamepadConfig { | ||||
|     pub fn update(&mut self, new_config: &GamepadConfig) { | ||||
|         self.gamepad_config = new_config.gamepad_config; | ||||
|     } | ||||
| 
 | ||||
|     pub fn as_bytes(&self) -> [u8; 56] { | ||||
|         self.gamepad_config | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Default, derive_more::Display)] | ||||
| pub struct CharacterEntityId(pub u32); | ||||
| @ -309,6 +355,8 @@ pub struct NewCharacterEntity { | ||||
| 
 | ||||
|     pub tech_menu: CharacterTechMenu, | ||||
|     pub option_flags: u32, | ||||
|     pub keyboard_config: CharacterKeyboardConfig, | ||||
|     pub gamepad_config: CharacterGamepadConfig, | ||||
| } | ||||
| 
 | ||||
| impl NewCharacterEntity { | ||||
| @ -328,6 +376,8 @@ impl NewCharacterEntity { | ||||
|             materials: CharacterMaterials::default(), | ||||
|             tech_menu: CharacterTechMenu::default(), | ||||
|             option_flags: 0, | ||||
|             keyboard_config: CharacterKeyboardConfig::new(1), | ||||
|             gamepad_config: CharacterGamepadConfig::default(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -353,4 +403,6 @@ pub struct CharacterEntity { | ||||
| 
 | ||||
|     pub tech_menu: CharacterTechMenu, | ||||
|     pub option_flags: u32, | ||||
|     pub keyboard_config: CharacterKeyboardConfig, | ||||
|     pub gamepad_config: CharacterGamepadConfig, | ||||
| } | ||||
|  | ||||
| @ -202,6 +202,8 @@ impl EntityGateway for InMemoryGateway { | ||||
|             materials: character.materials, | ||||
|             tech_menu: character.tech_menu, | ||||
|             option_flags: character.option_flags, | ||||
|             keyboard_config: character.keyboard_config, | ||||
|             gamepad_config: character.gamepad_config, | ||||
|         }; | ||||
|         characters.insert(new_character.id, new_character.clone()); | ||||
|         Ok(new_character) | ||||
|  | ||||
| @ -49,8 +49,8 @@ pub struct PgUserSettings { | ||||
|     id: i32, | ||||
|     user_account: i32, | ||||
|     blocked_users: Vec<u8>, //[u32; 0x1E],
 | ||||
|     key_config: Vec<u8>, //[u8; 0x16C],
 | ||||
|     joystick_config: Vec<u8>, //[u8; 0x38],
 | ||||
|     keyboard_config: Vec<u8>, //[u8; 0x16C],
 | ||||
|     gamepad_config: Vec<u8>, //[u8; 0x38],
 | ||||
|     option_flags: i32, | ||||
|     shortcuts: Vec<u8>, //[u8; 0xA40],
 | ||||
|     symbol_chats: Vec<u8>, //[u8; 0x4E0],
 | ||||
| @ -64,8 +64,8 @@ impl From<PgUserSettings> for UserSettingsEntity { | ||||
|             user_id: UserAccountId(other.user_account as u32), | ||||
|             settings: settings::UserSettings { | ||||
|                 blocked_users: vec_to_array(other.blocked_users.chunks(4).map(|b| u32::from_le_bytes([b[0], b[1], b[2], b[3]])).collect()), | ||||
|                 key_config: vec_to_array(other.key_config), | ||||
|                 joystick_config: vec_to_array(other.joystick_config), | ||||
|                 keyboard_config: vec_to_array(other.keyboard_config), | ||||
|                 gamepad_config: vec_to_array(other.gamepad_config), | ||||
|                 option_flags: other.option_flags as u32, | ||||
|                 shortcuts: vec_to_array(other.shortcuts), | ||||
|                 symbol_chats: vec_to_array(other.symbol_chats), | ||||
| @ -217,6 +217,8 @@ pub struct PgCharacter { | ||||
|     tp: i16, | ||||
| 
 | ||||
|     tech_menu: Vec<u8>, | ||||
|     keyboard_config: Vec<u8>, | ||||
|     gamepad_config: Vec<u8>, | ||||
| } | ||||
| 
 | ||||
| impl From<PgCharacter> for CharacterEntity { | ||||
| @ -266,6 +268,12 @@ impl From<PgCharacter> for CharacterEntity { | ||||
|             tech_menu: CharacterTechMenu { | ||||
|                 tech_menu: vec_to_array(other.tech_menu) | ||||
|             }, | ||||
|             keyboard_config: CharacterKeyboardConfig { | ||||
|                 keyboard_config: vec_to_array(other.keyboard_config) | ||||
|             }, | ||||
|             gamepad_config: CharacterGamepadConfig { | ||||
|                 gamepad_config: vec_to_array(other.gamepad_config) | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -144,12 +144,12 @@ impl EntityGateway for PostgresGateway { | ||||
|     } | ||||
| 
 | ||||
|     async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Result<UserSettingsEntity, GatewayError> { | ||||
|         let new_settings = sqlx::query_as::<_, PgUserSettings>("insert into user_settings (user_account, blocked_users, key_config, joystick_config, option_flags, shortcuts, symbol_chats, team_name)
 | ||||
|         let new_settings = sqlx::query_as::<_, PgUserSettings>("insert into user_settings (user_account, blocked_users, key_config, gamepad_config, option_flags, shortcuts, symbol_chats, team_name)
 | ||||
|                                                                 values ($1, $2, $3, $4, $5, $6, $7, $8) returning *;")
 | ||||
|             .bind(settings.user_id.0) | ||||
|             .bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::<Vec<u8>>()) | ||||
|             .bind(settings.settings.key_config.to_vec()) | ||||
|             .bind(settings.settings.joystick_config.to_vec()) | ||||
|             .bind(settings.settings.keyboard_config.to_vec()) | ||||
|             .bind(settings.settings.gamepad_config.to_vec()) | ||||
|             .bind(settings.settings.option_flags as i32) | ||||
|             .bind(settings.settings.shortcuts.to_vec()) | ||||
|             .bind(settings.settings.symbol_chats.to_vec()) | ||||
| @ -166,10 +166,10 @@ impl EntityGateway for PostgresGateway { | ||||
|     } | ||||
| 
 | ||||
|     async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> { | ||||
|         sqlx::query("update user_settings set blocked_users=$1, key_config=$2, joystick_config=$3, option_flags=$4, shortcuts=$5, symbol_chats=$6, team_name=$7 where id=$8") | ||||
|         sqlx::query("update user_settings set blocked_users=$1, key_config=$2, gamepad_config=$3, option_flags=$4, shortcuts=$5, symbol_chats=$6, team_name=$7 where id=$8") | ||||
|             .bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::<Vec<u8>>()) | ||||
|             .bind(&settings.settings.key_config.to_vec()) | ||||
|             .bind(&settings.settings.joystick_config.to_vec()) | ||||
|             .bind(&settings.settings.keyboard_config.to_vec()) | ||||
|             .bind(&settings.settings.gamepad_config.to_vec()) | ||||
|             .bind(&settings.settings.option_flags) | ||||
|             .bind(&settings.settings.shortcuts.to_vec()) | ||||
|             .bind(&settings.settings.symbol_chats.to_vec()) | ||||
|  | ||||
| @ -385,8 +385,8 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         let pkt = SendKeyAndTeamSettings::new(settings.settings.key_config, | ||||
|                                               settings.settings.joystick_config, 0, 0); | ||||
|         let pkt = SendKeyAndTeamSettings::new(settings.settings.keyboard_config, | ||||
|                                               settings.settings.gamepad_config, 0, 0); | ||||
|         let pkt = SendCharacterPacket::SendKeyAndTeamSettings(Box::new(pkt)); | ||||
| 
 | ||||
|         Ok(vec![pkt]) | ||||
|  | ||||
| @ -91,13 +91,31 @@ pub struct FullCharacterBytesBuilder<'a> { | ||||
|     meseta: Option<Meseta>, | ||||
|     inventory: Option<&'a CharacterInventory>, | ||||
|     bank: Option<&'a CharacterBank>, | ||||
|     key_config: Option<&'a [u8; 0x16C]>, | ||||
|     joystick_config: Option<&'a [u8; 0x38]>, | ||||
|     keyboard_config: Option<&'a [u8; 0x16C]>, | ||||
|     gamepad_config: Option<&'a [u8; 0x38]>, | ||||
|     symbol_chat: Option<&'a [u8; 1248]>, | ||||
|     tech_menu: Option<&'a [u8; 40]>, | ||||
|     option_flags: Option<u32>, | ||||
| } | ||||
| 
 | ||||
| impl<'a> Default for FullCharacterBytesBuilder<'a> { | ||||
|     fn default() -> FullCharacterBytesBuilder<'a> { | ||||
|         FullCharacterBytesBuilder { | ||||
|             character: None, | ||||
|             stats: None, | ||||
|             level: None, | ||||
|             inventory: None, | ||||
|             bank: None, | ||||
|             keyboard_config: None, | ||||
|             gamepad_config: None, | ||||
|             symbol_chat: None, | ||||
|             tech_menu: None, | ||||
|             option_flags: None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| impl<'a> FullCharacterBytesBuilder<'a> { | ||||
|     #[must_use] | ||||
|     pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> { | ||||
| @ -148,17 +166,17 @@ impl<'a> FullCharacterBytesBuilder<'a> { | ||||
|     } | ||||
| 
 | ||||
|     #[must_use] | ||||
|     pub fn key_config(self, key_config: &'a [u8; 0x16C]) -> FullCharacterBytesBuilder<'a> { | ||||
|     pub fn keyboard_config(self, keyboard_config: &'a [u8; 0x16C]) -> FullCharacterBytesBuilder<'a> { | ||||
|         FullCharacterBytesBuilder { | ||||
|             key_config: Some(key_config), | ||||
|             keyboard_config: Some(keyboard_config), | ||||
|             ..self | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[must_use] | ||||
|     pub fn joystick_config(self, joystick_config: &'a [u8; 0x38]) -> FullCharacterBytesBuilder<'a> { | ||||
|     pub fn joystick_config(self, gamepad_config: &'a [u8; 0x38]) -> FullCharacterBytesBuilder<'a> { | ||||
|         FullCharacterBytesBuilder { | ||||
|             joystick_config: Some(joystick_config), | ||||
|             gamepad_config: Some(gamepad_config), | ||||
|             ..self | ||||
|         } | ||||
|     } | ||||
| @ -194,8 +212,8 @@ impl<'a> FullCharacterBytesBuilder<'a> { | ||||
|         let meseta = self.meseta.unwrap(); | ||||
|         let inventory = self.inventory.unwrap(); | ||||
|         let bank = self.bank.unwrap(); | ||||
|         let key_config = self.key_config.unwrap(); | ||||
|         let joystick_config = self.joystick_config.unwrap(); | ||||
|         let keyboard_config = self.keyboard_config.unwrap(); | ||||
|         let gamepad_config = self.gamepad_config.unwrap(); | ||||
|         let symbol_chat = self.symbol_chat.unwrap(); | ||||
|         let tech_menu = self.tech_menu.unwrap(); | ||||
|         let option_flags = self.option_flags.unwrap(); | ||||
| @ -222,8 +240,8 @@ impl<'a> FullCharacterBytesBuilder<'a> { | ||||
|                 ..character::Inventory::default() | ||||
|             }, | ||||
|             key_team_config: character::KeyTeamConfig { | ||||
|                 key_config: *key_config, | ||||
|                 joystick_config: *joystick_config, | ||||
|                 keyboard_config: *keyboard_config, | ||||
|                 gamepad_config: *gamepad_config, | ||||
|                 ..character::KeyTeamConfig::default() | ||||
|             }, | ||||
|             info_board: character.info_board.as_bytes(), | ||||
|  | ||||
| @ -32,8 +32,10 @@ pub fn block_selected(id: ClientId, | ||||
|         .meseta(*meseta) | ||||
|         .inventory(inventory) | ||||
|         .bank(bank) | ||||
|         .key_config(&client.settings.settings.key_config) | ||||
|         .joystick_config(&client.settings.settings.joystick_config) | ||||
|         // .keyboard_config(&client.settings.settings.keyboard_config)
 | ||||
|         // .joystick_config(&client.settings.settings.joystick_config)
 | ||||
|         .keyboard_config(&client.character.keyboard_config.as_bytes()) | ||||
|         .joystick_config(&client.character.gamepad_config.as_bytes()) | ||||
|         .symbol_chat(&client.settings.settings.symbol_chats) | ||||
|         .tech_menu(&client.character.tech_menu.as_bytes()) | ||||
|         .option_flags(client.character.option_flags) | ||||
|  | ||||
| @ -26,13 +26,24 @@ pub async fn save_options<EG: EntityGateway>(id: ClientId, | ||||
|     Box::new(None.into_iter()) | ||||
| } | ||||
| 
 | ||||
| // pub async fn keyboard_config<EG: EntityGateway>(id: ClientId,
 | ||||
| //                                                 keyboard_config: &KeyboardConfig,
 | ||||
| //                                                 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();
 | ||||
| //     client.character.option_flags = save_options.options;
 | ||||
| //     entity_gateway.save_character(&client.character).await.unwrap();
 | ||||
| //     Box::new(None.into_iter())
 | ||||
| // }
 | ||||
| pub async fn keyboard_config<EG: EntityGateway>(id: ClientId, | ||||
|                                                 keyboard_config: &KeyboardConfig, | ||||
|                                                 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(); | ||||
|     client.character.keyboard_config.update(keyboard_config); | ||||
|     entity_gateway.save_character(&client.character).await.unwrap(); | ||||
|     Box::new(None.into_iter()) | ||||
| } | ||||
| 
 | ||||
| pub async fn gamepad_config<EG: EntityGateway>(id: ClientId, | ||||
|                                                 gamepad_config: &GamepadConfig, | ||||
|                                                 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(); | ||||
|     client.character.gamepad_config.update(gamepad_config); | ||||
|     entity_gateway.save_character(&client.character).await.unwrap(); | ||||
|     Box::new(None.into_iter()) | ||||
| } | ||||
| @ -93,7 +93,6 @@ pub enum RecvShipPacket { | ||||
|     PlayerChat(PlayerChat), | ||||
|     CreateRoom(CreateRoom), | ||||
|     RoomNameRequest(RoomNameRequest), | ||||
|     UpdateConfig(UpdateConfig), | ||||
|     ViewInfoboardRequest(ViewInfoboardRequest), | ||||
|     WriteInfoboard(WriteInfoboard), | ||||
|     RoomListRequest(RoomListRequest), | ||||
| @ -116,6 +115,8 @@ pub enum RecvShipPacket { | ||||
|     ItemsToTrade(ItemsToTrade), | ||||
|     TradeConfirmed(TradeConfirmed), | ||||
|     KeyboardConfig(KeyboardConfig), | ||||
|     GamepadConfig(GamepadConfig), | ||||
|     UpdateConfig(UpdateConfig), | ||||
| } | ||||
| 
 | ||||
| impl RecvServerPacket for RecvShipPacket { | ||||
| @ -140,7 +141,6 @@ impl RecvServerPacket for RecvShipPacket { | ||||
|             0x06 => Ok(RecvShipPacket::PlayerChat(PlayerChat::from_bytes(data)?)), | ||||
|             0xC1 => Ok(RecvShipPacket::CreateRoom(CreateRoom::from_bytes(data)?)), | ||||
|             0x8A => Ok(RecvShipPacket::RoomNameRequest(RoomNameRequest::from_bytes(data)?)), | ||||
|             0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)), | ||||
|             0xD8 => Ok(RecvShipPacket::ViewInfoboardRequest(ViewInfoboardRequest::from_bytes(data)?)), | ||||
|             0xD9 => Ok(RecvShipPacket::WriteInfoboard(WriteInfoboard::from_bytes(data)?)), | ||||
|             0x08 => Ok(RecvShipPacket::RoomListRequest(RoomListRequest::from_bytes(data)?)), | ||||
| @ -158,6 +158,8 @@ impl RecvServerPacket for RecvShipPacket { | ||||
|             0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))), | ||||
|             0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)), | ||||
|             0x4ED => Ok(RecvShipPacket::KeyboardConfig(KeyboardConfig::from_bytes(data)?)), | ||||
|             0x5ED => Ok(RecvShipPacket::GamepadConfig(GamepadConfig::from_bytes(data)?)), | ||||
|             0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)), | ||||
|             _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) | ||||
|         } | ||||
|     } | ||||
| @ -744,6 +746,12 @@ 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::KeyboardConfig(keyboard_config) => { | ||||
|                 handler::settings::keyboard_config(id, keyboard_config, &mut self.clients, &mut self.entity_gateway).await | ||||
|             }, | ||||
|             RecvShipPacket::GamepadConfig(gamepad_config) => { | ||||
|                 handler::settings::gamepad_config(id, gamepad_config, &mut self.clients, &mut self.entity_gateway).await | ||||
|             }, | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user