mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-27 17:07:46 +00:00
Remove hardcoded world id & name, make it configurable
Now the world isn't hardcoded to Gilgamesh, and is configurable. It's also now the "Dev" server listed in the excel sheet which makes a more sensible default.
This commit is contained in:
parent
3f27d2b3df
commit
a91c59aaaa
8 changed files with 72 additions and 33 deletions
|
@ -1,6 +1,8 @@
|
|||
use kawari::CONTENT_ID;
|
||||
use kawari::common::custom_ipc::CustomIpcData;
|
||||
use kawari::common::custom_ipc::CustomIpcSegment;
|
||||
use kawari::common::custom_ipc::CustomIpcType;
|
||||
use kawari::common::get_world_name;
|
||||
use kawari::config::get_config;
|
||||
use kawari::lobby::LobbyConnection;
|
||||
use kawari::lobby::ipc::{
|
||||
|
@ -11,7 +13,6 @@ use kawari::lobby::send_custom_world_packet;
|
|||
use kawari::oodle::OodleNetwork;
|
||||
use kawari::packet::ConnectionType;
|
||||
use kawari::packet::{PacketSegment, PacketState, SegmentType, send_keep_alive};
|
||||
use kawari::{CONTENT_ID, WORLD_NAME};
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
|
@ -27,6 +28,8 @@ async fn main() {
|
|||
|
||||
tracing::info!("Lobby server started on {addr}");
|
||||
|
||||
let world_name = get_world_name(config.world.world_id);
|
||||
|
||||
loop {
|
||||
let (socket, _) = listener.accept().await.unwrap();
|
||||
|
||||
|
@ -43,6 +46,8 @@ async fn main() {
|
|||
stored_character_creation_name: String::new(),
|
||||
};
|
||||
|
||||
let world_name = world_name.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut buf = [0; 2056];
|
||||
loop {
|
||||
|
@ -136,10 +141,8 @@ async fn main() {
|
|||
character_name: character_action
|
||||
.name
|
||||
.clone(),
|
||||
origin_server_name: WORLD_NAME
|
||||
.to_string(),
|
||||
current_server_name: WORLD_NAME
|
||||
.to_string(),
|
||||
origin_server_name: world_name.clone(),
|
||||
current_server_name: world_name.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
|
@ -241,10 +244,8 @@ async fn main() {
|
|||
character_name: character_action
|
||||
.name
|
||||
.clone(),
|
||||
origin_server_name: WORLD_NAME
|
||||
.to_string(),
|
||||
current_server_name: WORLD_NAME
|
||||
.to_string(),
|
||||
origin_server_name: world_name.clone(),
|
||||
current_server_name: world_name.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use kawari::common::custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType};
|
||||
use kawari::common::get_world_name;
|
||||
use kawari::config::get_config;
|
||||
use kawari::oodle::OodleNetwork;
|
||||
use kawari::packet::{
|
||||
|
@ -19,7 +20,7 @@ use kawari::world::{
|
|||
},
|
||||
};
|
||||
use kawari::world::{PlayerData, WorldDatabase};
|
||||
use kawari::{CHAR_NAME, CITY_STATE, CONTENT_ID, WORLD_ID, ZONE_ID, common::timestamp_secs};
|
||||
use kawari::{CHAR_NAME, CITY_STATE, CONTENT_ID, ZONE_ID, common::timestamp_secs};
|
||||
use physis::common::{Language, Platform};
|
||||
use physis::gamedata::GameData;
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
@ -320,8 +321,8 @@ async fn main() {
|
|||
data: ServerZoneIpcData::PlayerSpawn(PlayerSpawn {
|
||||
content_id: CONTENT_ID,
|
||||
common: CommonSpawn {
|
||||
current_world_id: WORLD_ID,
|
||||
home_world_id: WORLD_ID,
|
||||
current_world_id: config.world.world_id,
|
||||
home_world_id: config.world.world_id,
|
||||
title: 1,
|
||||
class_job: 35,
|
||||
name: chara_details.name,
|
||||
|
@ -802,8 +803,13 @@ async fn main() {
|
|||
}
|
||||
}
|
||||
CustomIpcData::RequestCharacterList { service_account_id } => {
|
||||
let characters =
|
||||
database.get_character_list(*service_account_id);
|
||||
let config = get_config();
|
||||
|
||||
let characters = database.get_character_list(
|
||||
*service_account_id,
|
||||
config.world.world_id,
|
||||
&get_world_name(config.world.world_id),
|
||||
);
|
||||
|
||||
// send response
|
||||
{
|
||||
|
|
|
@ -5,6 +5,12 @@ use std::{
|
|||
|
||||
mod customize_data;
|
||||
pub use customize_data::CustomizeData;
|
||||
use physis::{
|
||||
common::{Language, Platform},
|
||||
gamedata::GameData,
|
||||
};
|
||||
|
||||
use crate::config::get_config;
|
||||
|
||||
pub mod custom_ipc;
|
||||
|
||||
|
@ -37,3 +43,23 @@ pub fn timestamp_msecs() -> u64 {
|
|||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Gets the world name from an id into the World Excel sheet.
|
||||
pub fn get_world_name(world_id: u16) -> String {
|
||||
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("World").unwrap();
|
||||
let exd = game_data
|
||||
.read_excel_sheet("World", &exh, Language::None, 0)
|
||||
.unwrap();
|
||||
|
||||
let world_row = &exd.read_row(&exh, world_id as u32).unwrap()[0];
|
||||
|
||||
let physis::exd::ColumnData::String(name) = &world_row.data[1] else {
|
||||
panic!("Unexpected type!");
|
||||
};
|
||||
|
||||
name.clone()
|
||||
}
|
||||
|
|
|
@ -170,6 +170,8 @@ impl WebConfig {
|
|||
pub struct WorldConfig {
|
||||
pub port: u16,
|
||||
pub listen_address: String,
|
||||
/// See the World Excel sheet.
|
||||
pub world_id: u16,
|
||||
}
|
||||
|
||||
impl Default for WorldConfig {
|
||||
|
@ -177,6 +179,7 @@ impl Default for WorldConfig {
|
|||
Self {
|
||||
port: 7100,
|
||||
listen_address: "127.0.0.1".to_string(),
|
||||
world_id: 1, // Dev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,6 @@ pub mod packet;
|
|||
/// Logic server-specific code.
|
||||
pub mod login;
|
||||
|
||||
// TODO: make this configurable
|
||||
/// The world ID and name for the lobby.
|
||||
/// See <https://ffxiv.consolegameswiki.com/wiki/Servers> for a list of possible IDs.
|
||||
pub const WORLD_ID: u16 = 63;
|
||||
pub const WORLD_NAME: &str = "KAWARI";
|
||||
|
||||
/// The zone ID you initially spawn in.
|
||||
/// See the TerritoryType excel sheet for a list of possible IDs.
|
||||
pub const ZONE_ID: u16 = 132;
|
||||
|
|
|
@ -3,11 +3,10 @@ use std::cmp::min;
|
|||
use tokio::{io::AsyncReadExt, net::TcpStream};
|
||||
|
||||
use crate::{
|
||||
WORLD_ID, WORLD_NAME,
|
||||
blowfish::Blowfish,
|
||||
common::{
|
||||
custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType},
|
||||
timestamp_secs,
|
||||
get_world_name, timestamp_secs,
|
||||
},
|
||||
config::get_config,
|
||||
oodle::OodleNetwork,
|
||||
|
@ -114,12 +113,14 @@ impl LobbyConnection {
|
|||
let mut packets = Vec::new();
|
||||
// send them the server list
|
||||
{
|
||||
let config = get_config();
|
||||
|
||||
let mut servers = [Server {
|
||||
id: WORLD_ID,
|
||||
id: config.world.world_id,
|
||||
index: 0,
|
||||
flags: 0,
|
||||
icon: 0,
|
||||
name: WORLD_NAME.to_string(),
|
||||
name: get_world_name(config.world.world_id),
|
||||
}]
|
||||
.to_vec();
|
||||
// add any empty boys
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
CHAR_NAME, CUSTOMIZE_DATA, INVALID_OBJECT_ID, WORLD_ID,
|
||||
CHAR_NAME, CUSTOMIZE_DATA, INVALID_OBJECT_ID,
|
||||
common::timestamp_secs,
|
||||
config::get_config,
|
||||
packet::{PacketSegment, SegmentType},
|
||||
world::ipc::{
|
||||
ActorControl, ActorControlCategory, CommonSpawn, NpcSpawn, ObjectKind, PlayerSpawn,
|
||||
|
@ -66,6 +67,8 @@ impl ChatHandler {
|
|||
.await;
|
||||
}
|
||||
|
||||
let config = get_config();
|
||||
|
||||
// send player spawn
|
||||
{
|
||||
let ipc = ServerZoneIpcSegment {
|
||||
|
@ -78,8 +81,8 @@ impl ChatHandler {
|
|||
some_unique_id: 1,
|
||||
content_id: 1,
|
||||
common: CommonSpawn {
|
||||
current_world_id: WORLD_ID,
|
||||
home_world_id: WORLD_ID,
|
||||
current_world_id: config.world.world_id,
|
||||
home_world_id: config.world.world_id,
|
||||
title: 1,
|
||||
class_job: 35,
|
||||
name: CHAR_NAME.to_string(),
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Mutex;
|
|||
use rusqlite::Connection;
|
||||
|
||||
use crate::{
|
||||
WORLD_ID, WORLD_NAME, ZONE_ID,
|
||||
ZONE_ID,
|
||||
lobby::{CharaMake, ClientSelectData, ipc::CharacterDetails},
|
||||
};
|
||||
|
||||
|
@ -68,7 +68,12 @@ impl WorldDatabase {
|
|||
stmt.query_row((content_id,), |row| row.get(0)).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_character_list(&self, service_account_id: u32) -> Vec<CharacterDetails> {
|
||||
pub fn get_character_list(
|
||||
&self,
|
||||
service_account_id: u32,
|
||||
world_id: u16,
|
||||
world_name: &str,
|
||||
) -> Vec<CharacterDetails> {
|
||||
let connection = self.connection.lock().unwrap();
|
||||
|
||||
let content_actor_ids: Vec<(u32, u32)>;
|
||||
|
@ -137,11 +142,11 @@ impl WorldDatabase {
|
|||
content_id: *content_id as u64,
|
||||
index: index as u32,
|
||||
unk1: [0; 16],
|
||||
origin_server_id: WORLD_ID,
|
||||
current_server_id: WORLD_ID,
|
||||
origin_server_id: world_id,
|
||||
current_server_id: world_id,
|
||||
character_name: name.clone(),
|
||||
origin_server_name: WORLD_NAME.to_string(),
|
||||
current_server_name: WORLD_NAME.to_string(),
|
||||
origin_server_name: world_name.to_string(),
|
||||
current_server_name: world_name.to_string(),
|
||||
character_detail_json: select_data.to_json(),
|
||||
unk2: [0; 20],
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue