mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-25 00:17:45 +00:00
Fix CharaMake structure, derive City-State from class picked in creation
This commit is contained in:
parent
c4b65f5ecd
commit
15ed586fd0
5 changed files with 58 additions and 22 deletions
|
@ -1,8 +1,9 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use kawari::common::custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType};
|
||||
use kawari::common::get_world_name;
|
||||
use kawari::common::{get_citystate, get_world_name};
|
||||
use kawari::config::get_config;
|
||||
use kawari::lobby::CharaMake;
|
||||
use kawari::oodle::OodleNetwork;
|
||||
use kawari::packet::{
|
||||
CompressionType, ConnectionType, PacketSegment, PacketState, SegmentType, send_keep_alive,
|
||||
|
@ -260,7 +261,7 @@ async fn main() {
|
|||
.chara_make
|
||||
.customize
|
||||
.subrace,
|
||||
city_state: chara_details.chara_make.unk6 as u8, // TODO: probably wrong
|
||||
city_state: chara_details.city_state,
|
||||
nameday_month: chara_details
|
||||
.chara_make
|
||||
.birth_month
|
||||
|
@ -721,8 +722,16 @@ async fn main() {
|
|||
"creating character from: {name} {chara_make_json}"
|
||||
);
|
||||
|
||||
let (content_id, actor_id) =
|
||||
database.create_player_data(name, chara_make_json);
|
||||
let chara_make = CharaMake::from_json(&chara_make_json);
|
||||
|
||||
let city_state =
|
||||
get_citystate(chara_make.classjob_id as u16);
|
||||
|
||||
let (content_id, actor_id) = database.create_player_data(
|
||||
name,
|
||||
chara_make_json,
|
||||
city_state,
|
||||
);
|
||||
|
||||
tracing::info!(
|
||||
"Created new player: {content_id} {actor_id}"
|
||||
|
|
|
@ -63,3 +63,23 @@ pub fn get_world_name(world_id: u16) -> String {
|
|||
|
||||
name.clone()
|
||||
}
|
||||
|
||||
/// Gets the starting city-state from a given class/job id.
|
||||
pub fn get_citystate(classjob_id: u16) -> u8 {
|
||||
let config = get_config();
|
||||
|
||||
let mut game_data = GameData::from_existing(Platform::Win32, &config.game_location).unwrap();
|
||||
|
||||
let exh = game_data.read_excel_sheet_header("ClassJob").unwrap();
|
||||
let exd = game_data
|
||||
.read_excel_sheet("ClassJob", &exh, Language::English, 0)
|
||||
.unwrap();
|
||||
|
||||
let world_row = &exd.read_row(&exh, classjob_id as u32).unwrap()[0];
|
||||
|
||||
let physis::exd::ColumnData::UInt8(town_id) = &world_row.data[33] else {
|
||||
panic!("Unexpected type!");
|
||||
};
|
||||
|
||||
*town_id
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ use crate::common::CustomizeData;
|
|||
#[derive(Debug)]
|
||||
pub struct CharaMake {
|
||||
pub customize: CustomizeData,
|
||||
pub unk1: i32, // always 1?
|
||||
pub unk1: i32,
|
||||
pub guardian: i32,
|
||||
pub birth_month: i32,
|
||||
pub classjob: i32,
|
||||
pub birth_day: i32,
|
||||
pub unk6: i32, // always 1?
|
||||
pub classjob_id: i32,
|
||||
pub unk2: i32,
|
||||
}
|
||||
|
||||
impl CharaMake {
|
||||
|
@ -23,9 +23,9 @@ impl CharaMake {
|
|||
unk1: content[1].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
guardian: content[2].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
birth_month: content[3].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
classjob: content[4].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
birth_day: content[5].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
unk6: content[6].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
birth_day: content[4].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
classjob_id: content[5].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
unk2: content[6].as_str().unwrap().parse::<i32>().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,9 @@ impl CharaMake {
|
|||
self.unk1,
|
||||
self.guardian,
|
||||
self.birth_month,
|
||||
self.classjob,
|
||||
self.birth_day,
|
||||
self.unk6,
|
||||
self.classjob_id,
|
||||
self.unk2,
|
||||
]);
|
||||
|
||||
let obj = json!({
|
||||
|
@ -60,7 +60,7 @@ mod tests {
|
|||
|
||||
let chara_make = CharaMake::from_json(json);
|
||||
assert_eq!(chara_make.customize.gender, 0);
|
||||
assert_eq!(chara_make.classjob, 1);
|
||||
assert_eq!(chara_make.unk1, 1);
|
||||
|
||||
// TODO: add more asserts
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
|||
get_world_name, timestamp_secs,
|
||||
},
|
||||
config::get_config,
|
||||
lobby::CharaMake,
|
||||
oodle::OodleNetwork,
|
||||
packet::{
|
||||
CompressionType, ConnectionType, PacketSegment, PacketState, SegmentType,
|
||||
|
@ -207,8 +208,6 @@ impl LobbyConnection {
|
|||
|
||||
let mut characters = characters.to_vec();
|
||||
|
||||
dbg!(&characters);
|
||||
|
||||
for i in 0..4 {
|
||||
let mut characters_in_packet = Vec::new();
|
||||
for _ in 0..min(characters.len(), 2) {
|
||||
|
@ -429,6 +428,8 @@ impl LobbyConnection {
|
|||
let our_actor_id;
|
||||
let our_content_id;
|
||||
|
||||
dbg!(CharaMake::from_json(&character_action.json));
|
||||
|
||||
// tell the world server to create this character
|
||||
{
|
||||
let ipc_segment = CustomIpcSegment {
|
||||
|
|
|
@ -16,6 +16,7 @@ pub struct WorldDatabase {
|
|||
pub struct CharacterData {
|
||||
pub name: String,
|
||||
pub chara_make: CharaMake, // probably not the ideal way to store this?
|
||||
pub city_state: u8,
|
||||
}
|
||||
|
||||
impl WorldDatabase {
|
||||
|
@ -30,7 +31,7 @@ impl WorldDatabase {
|
|||
|
||||
// Create characters data table
|
||||
{
|
||||
let query = "CREATE TABLE IF NOT EXISTS character_data (content_id INTEGER PRIMARY KEY, name STRING, chara_make STRING);";
|
||||
let query = "CREATE TABLE IF NOT EXISTS character_data (content_id INTEGER PRIMARY KEY, name STRING, chara_make STRING, city_state INTEGER);";
|
||||
connection.execute(query, ()).unwrap();
|
||||
}
|
||||
|
||||
|
@ -165,7 +166,7 @@ impl WorldDatabase {
|
|||
}
|
||||
|
||||
/// Gives (content_id, actor_id)
|
||||
pub fn create_player_data(&self, name: &str, chara_make: &str) -> (u64, u32) {
|
||||
pub fn create_player_data(&self, name: &str, chara_make: &str, city_state: u8) -> (u64, u32) {
|
||||
let content_id = Self::generate_content_id();
|
||||
let actor_id = Self::generate_actor_id();
|
||||
|
||||
|
@ -182,8 +183,8 @@ impl WorldDatabase {
|
|||
// insert char data
|
||||
connection
|
||||
.execute(
|
||||
"INSERT INTO character_data VALUES (?1, ?2, ?3);",
|
||||
(content_id, name, chara_make),
|
||||
"INSERT INTO character_data VALUES (?1, ?2, ?3, ?4);",
|
||||
(content_id, name, chara_make, city_state),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -205,15 +206,20 @@ impl WorldDatabase {
|
|||
let connection = self.connection.lock().unwrap();
|
||||
|
||||
let mut stmt = connection
|
||||
.prepare("SELECT name, chara_make FROM character_data WHERE content_id = ?1")
|
||||
.prepare(
|
||||
"SELECT name, chara_make, city_state FROM character_data WHERE content_id = ?1",
|
||||
)
|
||||
.unwrap();
|
||||
let (name, chara_make_json): (String, String) = stmt
|
||||
.query_row((content_id,), |row| Ok((row.get(0)?, row.get(1)?)))
|
||||
let (name, chara_make_json, city_state): (String, String, u8) = stmt
|
||||
.query_row((content_id,), |row| {
|
||||
Ok((row.get(0)?, row.get(1)?, row.get(2)?))
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
CharacterData {
|
||||
name,
|
||||
chara_make: CharaMake::from_json(&chara_make_json),
|
||||
city_state,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue