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