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 {
|
||||
CharacterKeyboardConfig {
|
||||
keyboard: DEFAULT_KEYBOARD_CONFIG1,
|
||||
fn new(preset: usize) -> CharacterKeyboardConfig {
|
||||
match preset {
|
||||
1 => {
|
||||
CharacterKeyboardConfig {
|
||||
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