From 6f7322a2fc920b65c1d4727fb9a3575108c28ae9 Mon Sep 17 00:00:00 2001 From: Marenga Date: Fri, 25 Jul 2025 12:14:05 +0200 Subject: [PATCH 01/14] Clippy lints --- src/command/account.rs | 6 +++--- src/command/debug.rs | 2 +- src/command/mod.rs | 4 ++-- src/command/player.rs | 4 ++-- src/frontend.rs | 14 +++++++------- src/main.rs | 4 ++-- src/request.rs | 14 +++++++------- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/command/account.rs b/src/command/account.rs index 1a1a232..71efa3a 100644 --- a/src/command/account.rs +++ b/src/command/account.rs @@ -63,7 +63,7 @@ pub(crate) async fn account_create( } // TODO: Do some more input validation - let hashed_password = sha1_hash(&format!("{password}{}", HASH_CONST)); + let hashed_password = sha1_hash(&format!("{password}{HASH_CONST}")); let mut crypto_id = "0-".to_string(); for _ in 2..DEFAULT_CRYPTO_ID.len() { @@ -235,7 +235,7 @@ pub(crate) async fn account_delete( let id = char.pid; let pwhash = char.pw_hash; - let correct_full_hash = sha1_hash(&format!("{}{login_count}", pwhash)); + let correct_full_hash = sha1_hash(&format!("{pwhash}{login_count}")); if correct_full_hash != full_hash { return Err(ServerError::WrongPassword); } @@ -273,7 +273,7 @@ pub(crate) async fn account_login( let pid = info.pid; let pwhash = info.pw_hash; - let correct_full_hash = sha1_hash(&format!("{}{login_count}", pwhash)); + let correct_full_hash = sha1_hash(&format!("{pwhash}{login_count}")); if correct_full_hash != full_hash { Err(ServerError::WrongPassword)?; } diff --git a/src/command/debug.rs b/src/command/debug.rs index 81dac94..14648f6 100644 --- a/src/command/debug.rs +++ b/src/command/debug.rs @@ -71,7 +71,7 @@ pub(crate) async fn handle_cheat_command( .await?; } Command::SetPassword { new } => { - let hashed_password = sha1_hash(&format!("{new}{}", HASH_CONST)); + let hashed_password = sha1_hash(&format!("{new}{HASH_CONST}")); let mut tx = db.begin().await?; sqlx::query!( "UPDATE character as c diff --git a/src/command/mod.rs b/src/command/mod.rs index d2c5af9..f2015bb 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -50,7 +50,7 @@ pub(crate) async fn handle_command<'a>( session: Session, ) -> Result { if name != "Poll" { - debug!("Received: {name}: {:?}", args); + debug!("Received: {name}: {args:?}"); } if !session.can_request(name) { @@ -86,7 +86,7 @@ pub(crate) async fn handle_command<'a>( "UserSettingsUpdate" => Ok(ServerResponse::Success), // TODO: "getserverversion" => get_server_version(session, db).await, _ => { - error!("Unknown command: {name} - {:?}", args); + error!("Unknown command: {name} - {args:?}"); Err(ServerError::UnknownRequest(name.into())) } } diff --git a/src/command/player.rs b/src/command/player.rs index 9874df3..14b5d80 100644 --- a/src/command/player.rs +++ b/src/command/player.rs @@ -113,7 +113,7 @@ pub(crate) async fn player_whisper( use clap::Parser; let command = CheatCmd::try_parse_from(args.get_str(1, "args")?.split(' ')) .map_err(|e| { - error!("Error while parsing command: {:?}", e); + error!("Error while parsing command: {e:?}"); ServerError::BadRequest })?; handle_cheat_command(session, db, command).await @@ -567,7 +567,7 @@ pub(crate) async fn player_get_hof( "bg" )) .map_err(|e| { - error!("Error while writing format: {:?}", e); + error!("Error while writing format: {e:?}"); ServerError::Internal })?; } diff --git a/src/frontend.rs b/src/frontend.rs index b8119f9..c61e483 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -34,7 +34,7 @@ pub async fn forward(req: Request) -> Result { let client = get_client(); let get_text = |url: String| async { let resp = client.get(url).send().await.map_err(|e| { - error!("Error while sending request: {:?}", e); + error!("Error while sending request: {e:?}"); INTERNAL_ERR })?; let status = resp.status(); @@ -42,7 +42,7 @@ pub async fn forward(req: Request) -> Result { return Err(status); } resp.text().await.map_err(|e| { - error!("Error while reading response text: {:?}", e); + error!("Error while reading response text: {e:?}"); INTERNAL_ERR }) }; @@ -51,7 +51,7 @@ pub async fn forward(req: Request) -> Result { let text = get_text(sfgame_url()).await?; let mut json: HashMap = serde_json::from_str(&text) .map_err(|e| { - error!("Error while parsing JSON: {:?}", e); + error!("Error while parsing JSON: {e:?}"); INTERNAL_ERR })?; let fw = json.get_mut("frameworkUrl").ok_or(INTERNAL_ERR)?; @@ -66,7 +66,7 @@ pub async fn forward(req: Request) -> Result { .header(CONTENT_TYPE, "application/javascript") .body(axum::body::Body::from(fixed_framework)) .map_err(|e| { - error!("Error while building response body: {:?}", e); + error!("Error while building response body: {e:?}"); INTERNAL_ERR }) } else if uri == "/config.json" { @@ -74,7 +74,7 @@ pub async fn forward(req: Request) -> Result { let text = get_text(sfgame_url()).await?; let mut config: SFConfig = serde_json::from_str(&text).map_err(|e| { - error!("Error while parsing config JSON: {:?}", e); + error!("Error while parsing config JSON: {e:?}"); INTERNAL_ERR })?; @@ -86,7 +86,7 @@ pub async fn forward(req: Request) -> Result { .fetch_all(&db) .await .map_err(|e| { - error!("Database query error: {:?}", e); + error!("Database query error: {e:?}"); INTERNAL_ERR })?; @@ -124,7 +124,7 @@ pub async fn forward(req: Request) -> Result { builder .body(axum::body::Body::from_stream(resp.bytes_stream())) .map_err(|e| { - error!("Error while building response body: {:?}", e); + error!("Error while building response body: {e:?}"); INTERNAL_ERR }) } diff --git a/src/main.rs b/src/main.rs index da54e1c..7682722 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ async fn main() { .unwrap(); let addr = SocketAddr::from(([127, 0, 0, 1], HTTPS_PORT)); - info!("listening on https://{}", addr); + info!("listening on https://{addr}"); axum_server::bind_rustls(addr, config) .serve(app.into_make_service()) .await @@ -118,7 +118,7 @@ pub async fn get_db() -> Result, ServerError> { .connect(env!("DATABASE_URL")) .await .map_err(|e| { - error!("Database connection error: {:?}", e); + error!("Database connection error: {e:?}"); e.into() }) }) diff --git a/src/request.rs b/src/request.rs index 00a23d5..615aa0c 100644 --- a/src/request.rs +++ b/src/request.rs @@ -22,11 +22,11 @@ pub async fn handle_cmd( let command_args = base64::engine::general_purpose::URL_SAFE .decode(command_args) .map_err(|e| { - error!("Error while decoding command_args: {:?}", e); + error!("Error while decoding command_args: {e:?}"); ServerError::BadRequest })?; let command_args = String::from_utf8(command_args).map_err(|e| { - error!("Error while converting command_args to UTF-8: {:?}", e); + error!("Error while converting command_args to UTF-8: {e:?}"); ServerError::BadRequest })?; @@ -43,7 +43,7 @@ pub async fn handle_cmd( .fetch_one(&db) .await .map_err(|e| { - error!("Database error while fetching world_id: {:?}", e); + error!("Database error while fetching world_id: {e:?}"); ServerError::DBError(e) })?; @@ -63,7 +63,7 @@ pub async fn handle_cmd( .fetch_optional(&db) .await .map_err(|e| { - error!("Database error while fetching session: {:?}", e); + error!("Database error while fetching session: {e:?}"); ServerError::DBError(e) })?; @@ -119,7 +119,7 @@ pub async fn handle_req( .fetch_one(&db) .await .map_err(|e| { - error!("Database error while fetching world_id: {:?}", e); + error!("Database error while fetching world_id: {e:?}"); ServerError::DBError(e) })?; @@ -139,7 +139,7 @@ pub async fn handle_req( .fetch_optional(&db) .await .map_err(|e| { - error!("Database error while fetching session: {:?}", e); + error!("Database error while fetching session: {e:?}"); ServerError::DBError(e) })?; @@ -205,7 +205,7 @@ impl Session { || [ "AccountCreate", "AccountLogin", "AccountCheck", "AccountDelete", "PlayerHelpshiftAuthtoken", - "getserverversion", "PlayerWhisper", "PlayerTwitchAuthtoken" + "getserverversion", "PlayerWhisper", "PlayerTwitchAuthtoken", ] .contains(&command) } From e796f4904b64b26336f3c06462dc444ac86383c0 Mon Sep 17 00:00:00 2001 From: Marenga Date: Fri, 25 Jul 2025 12:16:08 +0200 Subject: [PATCH 02/14] 2024 edition --- Cargo.toml | 3 +-- src/command/item.rs | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c53558c..1c27a45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sf-server" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] async-once-cell = "0.5.4" @@ -23,7 +23,6 @@ reqwest = { version = "0.12.22", features = [ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sf-api = "0.2.1" - sha1 = "0.10.6" sqlx = { version = "0.8.6", features = ["runtime-tokio", "sqlite"] } strum = { version = "0.26.3", features = ["derive"] } diff --git a/src/command/item.rs b/src/command/item.rs index 3790384..8730c18 100644 --- a/src/command/item.rs +++ b/src/command/item.rs @@ -65,6 +65,7 @@ pub enum SubItemTyp { EpicItemBag = 10000, } +#[allow(unused)] #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum GemValue { Legendary = 4, From 1fb7ccf2bfbb92b309754db77a71775b7fabf066 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sat, 26 Jul 2025 17:51:39 +0200 Subject: [PATCH 03/14] Expedition selection --- migrations/20250725103139_expeditions.sql | 60 +++++++++++++++++++++ src/command/account.rs | 24 +++++++-- src/command/update.rs | 65 +++++++++++++---------- 3 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 migrations/20250725103139_expeditions.sql diff --git a/migrations/20250725103139_expeditions.sql b/migrations/20250725103139_expeditions.sql new file mode 100644 index 0000000..51f601c --- /dev/null +++ b/migrations/20250725103139_expeditions.sql @@ -0,0 +1,60 @@ +CREATE TABLE Expedition ( + id INTEGER PRIMARY KEY autoincrement NOT NULL, + pid INTEGER NOT NULL REFERENCES character (pid) ON DELETE cascade, + target INT NOT NULL, + alu_sec INT NOT NULL, + location_1 INT NOT NULL, + location_2 INT NOT NULL +); + +CREATE INDEX ExpeditionPlayer ON Expedition(pid); + +CREATE TABLE ActiveExpedition ( + pid INTEGER PRIMARY KEY NOT NULL REFERENCES character (pid) ON DELETE cascade, + -- ExpeditionThing + target INT NOT NULL, + + item1 INT DEFAULT NULL, + item2 INT DEFAULT NULL, + item3 INT DEFAULT NULL, + item4 INT DEFAULT NULL, + + target_current INT NOT NULL DEFAULT 0, + target_amount INT NOT NULL DEFAULT 0, + + current_floor INT NOT NULL DEFAULT 1, + heroism INT NOT NULL DEFAULT 0, + + floor_stage INT NOT NULL DEFAULT 0, + + encounter1 INT NOT NULL DEFAULT 0, + encounter2 INT NOT NULL DEFAULT 0, + encounter3 INT NOT NULL DEFAULT 0, + encounter4 INT NOT NULL DEFAULT 0, + + boss_id INT NOT NULL, + + reward1_type INT NOT NULL DEFAULT 0, + reward1_amount INT NOT NULL DEFAULT 0, + reward2_type INT NOT NULL DEFAULT 0, + reward2_amount INT NOT NULL DEFAULT 0, + reward3_type INT NOT NULL DEFAULT 0, + reward3_amount INT NOT NULL DEFAULT 0, + reward4_type INT NOT NULL DEFAULT 0, + reward4_amount INT NOT NULL DEFAULT 0 +); + +INSERT INTO Expedition (target, alu_sec, location_1, location_2, pid) +SELECT 33, 1500, 18, 12, pid FROM Character c; + +INSERT INTO Expedition (target, alu_sec, location_1, location_2, pid) +SELECT 93, 1500, 18, 12, pid FROM Character c; + +CREATE TABLE UserSetting ( + pid INTEGER PRIMARY KEY autoincrement NOT NULL REFERENCES character(pid), + lang TEXT NOT NULL, + quest_pref TEXT NOT NULL DEFAULT 'a' +); + +INSERT INTO UserSetting (pid, lang, quest_pref) +SELECT pid, 'en', 'a' FROM Character c; diff --git a/src/command/account.rs b/src/command/account.rs index 71efa3a..936beba 100644 --- a/src/command/account.rs +++ b/src/command/account.rs @@ -1,10 +1,13 @@ -use command::{poll, CommandArguments, Portrait}; +use command::{CommandArguments, Portrait, poll}; use fastrand::Rng; use num_traits::FromPrimitive; use request::Session; use sf_api::{ - gamestate::character::{Class, Gender, Race}, - misc::{sha1_hash, HASH_CONST}, + gamestate::{ + character::{Class, Gender, Race}, + tavern::{ExpeditionThing, Location}, + }, + misc::{HASH_CONST, sha1_hash}, }; use sqlx::Sqlite; @@ -110,6 +113,21 @@ pub(crate) async fn account_create( .fetch_one(&mut *tx) .await?; + for _ in 0..2 { + let alu = [5, 10, 15, 20][fastrand::usize(0..4)] * 60; + sqlx::query_scalar!( + "INSERT INTO Expedition + (target, alu_sec, location_1, location_2) + VALUES ($1, $2, $3, $4)", + ExpeditionThing::BrokenSword as i32, + alu, + Location::SprawlingJungle as i32, + Location::SkullIsland as i32 + ) + .execute(&mut *tx) + .await?; + } + sqlx::query_scalar!("INSERT INTO BAG (pid) VALUES ($1)", pid) .execute(&mut *tx) .await?; diff --git a/src/command/update.rs b/src/command/update.rs index 0e112d1..45424ce 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -1,14 +1,20 @@ use sf_api::{ - command::AttributeType, gamestate::items::EquipmentSlot, misc::to_sf_string, + command::AttributeType, + gamestate::{ + items::EquipmentSlot, + tavern::{ExpeditionThing, Location}, + }, + misc::to_sf_string, }; use sqlx::Sqlite; use strum::IntoEnumIterator; use super::{ - effective_mount, get_debug_value_default, in_seconds, item::add_debug_item, - now, xp_for_next_level, ResponseBuilder, ServerError, ServerResponse, + ResponseBuilder, ServerError, ServerResponse, effective_mount, + get_debug_value_default, in_seconds, item::add_debug_item, now, + xp_for_next_level, }; -use crate::{request::Session, SERVER_VERSION}; +use crate::{SERVER_VERSION, request::Session}; pub(crate) async fn poll( session: Session, @@ -453,15 +459,15 @@ pub(crate) async fn poll( resp.add_val(0); // 544 resp.add_val(0); // 545 resp.add_val(0); // 546 - // unit counts + // unit counts resp.add_val(0); // 547 resp.add_val(0); // 548 resp.add_val(0); // 549 - // upgrade_began + // upgrade_began resp.add_val(0); // 550 resp.add_val(0); // 551 resp.add_val(0); // 552 - // upgrade_finish + // upgrade_finish resp.add_val(0); // 553 resp.add_val(0); // 554 resp.add_val(0); // 555 @@ -477,11 +483,11 @@ pub(crate) async fn poll( resp.add_val(0); // 562 resp.add_val(0); // 563 resp.add_val(0); // 564 - // max_in_building + // max_in_building resp.add_val(0); // 565 resp.add_val(0); // 566 resp.add_val(0); // 567 - // max saved + // max saved resp.add_val(0); // 568 resp.add_val(0); // 569 resp.add_val(0); // 570 @@ -489,7 +495,7 @@ pub(crate) async fn poll( resp.add_val(0); // 571 building_upgraded resp.add_val(0); // 572 building_upgrade_finish resp.add_val(0); // 573 building_upgrade_began - // per hour + // per hour resp.add_val(0); // 574 resp.add_val(0); // 575 resp.add_val(0); // 576 @@ -696,7 +702,7 @@ pub(crate) async fn poll( resp.add_val(0); // metal resp.add_val(0); // arcane resp.add_val(0); // souls - // Fruits + // Fruits for _ in 0..5 { resp.add_val(0); } @@ -868,24 +874,27 @@ pub(crate) async fn poll( resp.skip_key(); + let expeditions = sqlx::query!( + "SELECT target, alu_sec, location_1, location_2 + FROM expedition + WHERE pid = $1", + session.player_id + ) + .fetch_all(db) + .await?; + resp.add_key("expeditions"); - resp.add_val(33); - resp.add_val(71); - resp.add_val(32); - resp.add_val(91); - resp.add_val(10); - resp.add_val(5); - resp.add_val(1500); - resp.add_val(0); - resp.add_val(124); - resp.add_val(44); - resp.add_val(91); - resp.add_val(71); - resp.add_val(16); - resp.add_val(5); - resp.add_val(6000); - resp.add_val(0); + for exp in expeditions { + resp.add_val(exp.target); // typ + resp.add_val(71); // ?? + resp.add_val(32); // ?? + resp.add_val(91); // ?? + resp.add_val(exp.location_1); // location 1 + resp.add_val(exp.location_2); // location 2 + resp.add_val(exp.alu_sec); // alu + resp.add_val(0); // 1 => egg, 2 => inc. daily task + } resp.add_key("expeditionevent"); resp.add_val(in_seconds(-60 * 60)); @@ -898,7 +907,7 @@ pub(crate) async fn poll( resp.add_val(0); resp.add_val(0); resp.add_val(0); - resp.add_str("0"); + resp.add_str("a"); resp.add_val(0); resp.add_key("mailinvoice"); From 0e93c9aec134a04a245d628be307f182d2270eb9 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sun, 3 Aug 2025 13:35:40 +0200 Subject: [PATCH 04/14] Some work on starting expeditions --- src/command/mod.rs | 5 +++-- src/command/player.rs | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/command/mod.rs b/src/command/mod.rs index f2015bb..6d3f1f9 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -7,7 +7,7 @@ use player::*; use sqlx::Sqlite; use update::poll; -use crate::{request::Session, response::*, SERVER_VERSION}; +use crate::{SERVER_VERSION, request::Session, response::*}; mod account; mod debug; @@ -60,7 +60,7 @@ pub(crate) async fn handle_command<'a>( } match name { - "PlayerTwitchAuthtoken" => Ok(ServerResponse::Success), + "PlayerTwitchAuthtoken" => Ok(ServerResponse::Success), // TODO: "AccountCheck" => account_check(db, args).await, "AccountCreate" => account_create(session, db, args).await, "AccountDelete" => account_delete(session, db, args).await, @@ -85,6 +85,7 @@ pub(crate) async fn handle_command<'a>( "Poll" => poll(session, "poll", db, Default::default()).await, "UserSettingsUpdate" => Ok(ServerResponse::Success), // TODO: "getserverversion" => get_server_version(session, db).await, + "ExpeditionStart" => player_start_expedition(session, db, args).await, _ => { error!("Unknown command: {name} - {args:?}"); Err(ServerError::UnknownRequest(name.into())) diff --git a/src/command/player.rs b/src/command/player.rs index 14b5d80..db37b30 100644 --- a/src/command/player.rs +++ b/src/command/player.rs @@ -10,9 +10,9 @@ use sf_api::{ use sqlx::Sqlite; use super::{ - debug::{handle_cheat_command, CheatCmd}, - effective_mount, in_seconds, now, poll, xp_for_next_level, CommandArguments, Portrait, ResponseBuilder, ServerError, ServerResponse, + debug::{CheatCmd, handle_cheat_command}, + effective_mount, in_seconds, now, poll, xp_for_next_level, }; use crate::request::Session; @@ -367,6 +367,40 @@ pub(crate) async fn player_finish_quest( poll(session, "", db, resp).await } +pub(crate) async fn player_start_expedition( + session: Session, + db: &sqlx::Pool, + args: CommandArguments<'_>, +) -> Result { + let mut tx = db.begin().await?; + + let existing = sqlx::query!( + "SELECT pid FROM ActiveExpedition WHERE pid = $1", session.player_id + ) + .fetch_optional(&mut *tx) + .await?; + + if existing.is_some() { + return Err(ServerError::StillBusy); + } + + let expedition = args.get_int(0, "expedition")?; + + let exp_data = sqlx::query!( + "SELECT target, alu_sec, location_1, location_2 + FROM Expedition WHERE pid = $1 ORDER BY id", + session.player_id + ) + .fetch_all(&mut *tx) + .await?; + + // INIT an expedition from the data + + + + todo!() +} + pub(crate) async fn player_start_quest( session: Session, db: &sqlx::Pool, @@ -894,7 +928,7 @@ pub(crate) async fn player_arena_fight( resp.add_val(0); resp.add_val(2); // rank pre resp.add_val(2); // rank post - // Item + // Item for _ in 0..12 { resp.add_val(0); } From 8489da0e218b98521f8d734a1a514a9852f053da Mon Sep 17 00:00:00 2001 From: Marenga Date: Mon, 4 Aug 2025 15:45:21 +0200 Subject: [PATCH 05/14] lints & fmt --- src/command/player.rs | 2 -- src/command/update.rs | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/command/player.rs b/src/command/player.rs index db37b30..1684b75 100644 --- a/src/command/player.rs +++ b/src/command/player.rs @@ -396,8 +396,6 @@ pub(crate) async fn player_start_expedition( // INIT an expedition from the data - - todo!() } diff --git a/src/command/update.rs b/src/command/update.rs index 3b6de40..fe08ce7 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -1,10 +1,5 @@ use sf_api::{ - command::AttributeType, - gamestate::{ - items::EquipmentSlot, - tavern::{ExpeditionThing, Location}, - }, - misc::to_sf_string, + command::AttributeType, gamestate::items::EquipmentSlot, misc::to_sf_string, }; use sqlx::Sqlite; use strum::IntoEnumIterator; From 1f5d66af68c93ea1ed7fcf7c48fd92b6210cb5ec Mon Sep 17 00:00:00 2001 From: Marenga Date: Tue, 5 Aug 2025 02:23:58 +0200 Subject: [PATCH 06/14] Start expeditions --- src/command/player.rs | 82 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/src/command/player.rs b/src/command/player.rs index 1684b75..a563f2a 100644 --- a/src/command/player.rs +++ b/src/command/player.rs @@ -374,29 +374,89 @@ pub(crate) async fn player_start_expedition( ) -> Result { let mut tx = db.begin().await?; - let existing = sqlx::query!( - "SELECT pid FROM ActiveExpedition WHERE pid = $1", session.player_id + let exp_val = args.get_int(0, "expedition")?; + let expedition = match exp_val { + 1 => 0, + 2 => 1, + _ => return Err(ServerError::MissingArgument("expedition")), + }; + + let char_data = sqlx::query!( + "SELECT typ, mount, mount_end, tfa, + target, alu_sec, location_1, location_2 + FROM character + NATURAL JOIN activity + NATURAL JOIN tavern + NATURAL JOIN expedition + WHERE pid = $1 + ORDER BY expedition.id + LIMIT 1 OFFSET $2", + session.player_id, + expedition ) .fetch_optional(&mut *tx) .await?; - if existing.is_some() { + let Some(char_data) = char_data else { + return Err(ServerError::Internal); + }; + + if char_data.typ != 0 { return Err(ServerError::StillBusy); } - let expedition = args.get_int(0, "expedition")?; + let mut mount = char_data.mount; + let mut mount_end = char_data.mount_end; + let mount_effect = effective_mount(&mut mount_end, &mut mount); - let exp_data = sqlx::query!( - "SELECT target, alu_sec, location_1, location_2 - FROM Expedition WHERE pid = $1 ORDER BY id", - session.player_id + let exp_length = char_data.alu_sec as f32 * mount_effect.ceil().max(0.0); + let exp_length = exp_length as i64; + + if char_data.tfa < exp_length { + return Err(ServerError::StillBusy); + } + + sqlx::query!( + "INSERT INTO ActiveExpedition + (pid, target, encounter1, encounter2, encounter3, encounter4, boss_id) + VALUES + ($1, $2, $3, $4, $5, $6, $7) + ", + session.player_id, + char_data.target, + 1, + 1, + 1, + 1, + 100 ) - .fetch_all(&mut *tx) + .execute(&mut *tx) .await?; - // INIT an expedition from the data + sqlx::query!( + "UPDATE activity set typ = 3, + sub_type = $2, + started = CURRENT_TIMESTAMP + WHERE pid = $1", + session.player_id, + exp_val + ) + .execute(&mut *tx) + .await?; + + sqlx::query!( + "UPDATE tavern + SET tfa = max(0, tfa - $2) + WHERE pid = $1", + session.player_id, + exp_length + ) + .execute(&mut *tx) + .await?; + + tx.commit().await?; - todo!() + poll(session, "", db, Default::default()).await } pub(crate) async fn player_start_quest( From 4a5dc839e327fc57cb2b808c9eac08100885335b Mon Sep 17 00:00:00 2001 From: Marenga Date: Tue, 5 Aug 2025 03:41:39 +0200 Subject: [PATCH 07/14] Show Expedition state --- src/command/account.rs | 6 +- src/command/guild.rs | 2 +- src/command/mod.rs | 18 ++-- src/command/player.rs | 46 +++++----- src/command/update.rs | 194 +++++++++++++++++++++++++---------------- src/response.rs | 2 +- 6 files changed, 157 insertions(+), 111 deletions(-) diff --git a/src/command/account.rs b/src/command/account.rs index 936beba..84a1348 100644 --- a/src/command/account.rs +++ b/src/command/account.rs @@ -31,9 +31,9 @@ pub(crate) async fn account_check( match count { 0 => ResponseBuilder::default() - .add_key("serverversion") + .start_section("serverversion") .add_val(SERVER_VERSION) - .add_key("preregister") + .start_section("preregister") .add_val(0) .add_val(0) .build(), @@ -216,7 +216,7 @@ pub(crate) async fn account_create( tx.commit().await?; ResponseBuilder::default() - .add_key("tracking.s") + .start_section("tracking.s") .add_str("signup") .build() } diff --git a/src/command/guild.rs b/src/command/guild.rs index ee086d3..08850bd 100644 --- a/src/command/guild.rs +++ b/src/command/guild.rs @@ -82,7 +82,7 @@ pub(crate) async fn group_get_hof( } ResponseBuilder::default() - .add_key("ranklistgroup.r") + .start_section("ranklistgroup.r") .add_str(&guilds) .build() } diff --git a/src/command/mod.rs b/src/command/mod.rs index 6d3f1f9..b149b32 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -100,20 +100,20 @@ async fn pending_reward_view( ) -> Result { let _id = args.get_int(0, "msg_id")?; let mut resp = ResponseBuilder::default(); - resp.add_key("pendingrewardressources"); + resp.start_section("pendingrewardressources"); for v in 1..=6 { let val = v; resp.add_val(val); resp.add_val(999); } - resp.add_key("pendingreward.item(0)"); + resp.start_section("pendingreward.item(0)"); resp.build() } fn player_helpshift_auth_token() -> Result { ResponseBuilder::default() - .add_key("helpshiftauthtoken") + .start_section("helpshiftauthtoken") .add_val("+eZGNZyCPfOiaufZXr/WpzaaCNHEKMmcT7GRJOGWJAU=") .build() } @@ -135,20 +135,20 @@ async fn get_server_version( .await?; ResponseBuilder::default() - .add_key("serverversion") + .start_section("serverversion") .add_val(SERVER_VERSION) - .add_key("preregister") + .start_section("preregister") .add_val(now()) .add_val(now()) .add_str("Europe") .add_str("Berlin") - .add_key("timestamp") + .start_section("timestamp") .add_val(now()) - .add_key("rankmaxplayer") + .start_section("rankmaxplayer") .add_val(res.charactercount) - .add_key("rankmaxgroup") + .start_section("rankmaxgroup") .add_val(res.guildcount) - .add_key("country") + .start_section("country") .add_val("DE") .build() } diff --git a/src/command/player.rs b/src/command/player.rs index a563f2a..d7c24b7 100644 --- a/src/command/player.rs +++ b/src/command/player.rs @@ -220,7 +220,7 @@ pub(crate) async fn player_finish_quest( let mut resp = ResponseBuilder::default(); - resp.add_key("fightresult.battlereward"); + resp.start_section("fightresult.battlereward"); resp.add_val(true as u8); // won resp.add_val(0); @@ -233,7 +233,7 @@ pub(crate) async fn player_finish_quest( resp.add_val(0); } - resp.add_key("fightheader.fighters"); + resp.start_section("fightheader.fighters"); let monster_id = -monster; let mut character_lvl = row.level; let starting_character_xp = row.experience; @@ -325,15 +325,15 @@ pub(crate) async fn player_finish_quest( resp.add_val(0); } - resp.add_key("fight.r"); + resp.start_section("fight.r"); resp.add_str(&format!("{},0,-1000", session.player_id)); // TODO: actually simulate fight - resp.add_key("winnerid"); + resp.start_section("winnerid"); resp.add_val(session.player_id); - resp.add_key("fightversion"); + resp.start_section("fightversion"); resp.add_val(1); sqlx::query!( @@ -418,9 +418,9 @@ pub(crate) async fn player_start_expedition( sqlx::query!( "INSERT INTO ActiveExpedition - (pid, target, encounter1, encounter2, encounter3, encounter4, boss_id) + (pid, target, encounter1, encounter2, encounter3, encounter4, boss_id, floor_stage) VALUES - ($1, $2, $3, $4, $5, $6, $7) + ($1, $2, $3, $4, $5, $6, $7, 1) ", session.player_id, char_data.target, @@ -584,7 +584,7 @@ pub(crate) async fn player_gamble_gold( tx.commit().await?; ResponseBuilder::default() - .add_key("gamblegoldvalue") + .start_section("gamblegoldvalue") .add_val(silver) .build() } @@ -665,7 +665,7 @@ pub(crate) async fn player_get_hof( } ResponseBuilder::default() - .add_key("Ranklistplayer.r") + .start_section("Ranklistplayer.r") .add_str(&characters) .build() } @@ -770,9 +770,9 @@ pub(crate) async fn player_look_at( .fetch_one(db) .await?; - resp.add_key("otherplayergroupname.r"); + resp.start_section("otherplayergroupname.r"); resp.add_val(""); - resp.add_key("otherplayer.playerlookat"); + resp.start_section("otherplayer.playerlookat"); resp.add_val(pid); resp.add_val(0); resp.add_val(info.level); @@ -836,27 +836,27 @@ pub(crate) async fn player_look_at( for _ in 0..53 { resp.add_val(0); } - resp.add_key("otherdescription.s"); + resp.start_section("otherdescription.s"); resp.add_str(&info.description); - resp.add_key("otherplayername.r"); + resp.start_section("otherplayername.r"); resp.add_val(info.name); - resp.add_key("otherplayerunitlevel(4)"); + resp.start_section("otherplayerunitlevel(4)"); resp.add_val(190); resp.add_val(140); resp.add_val(145); resp.add_val(145); - resp.add_key("otherplayerfriendstatus"); + resp.start_section("otherplayerfriendstatus"); resp.add_val(0); - resp.add_key("otherplayerfortressrank"); + resp.start_section("otherplayerfortressrank"); resp.add_val(0); - resp.add_key("otherplayerpetbonus.petbonus"); + resp.start_section("otherplayerpetbonus.petbonus"); resp.add_val(207011); resp.add_val(7); resp.add_val(6); resp.add_val(6); resp.add_val(6); resp.add_val(6); - resp.add_key("soldieradvice"); + resp.start_section("soldieradvice"); resp.add_val(18); resp.build() } @@ -875,10 +875,10 @@ pub(crate) async fn player_arena_fight( .await?; let mut resp = ResponseBuilder::default(); - resp.add_key("fightversion"); + resp.start_section("fightversion"); resp.add_val(2); - resp.add_key("fightheader.fighters"); + resp.start_section("fightheader.fighters"); resp.add_val(0); resp.add_val(0); resp.add_val(0); @@ -944,7 +944,7 @@ pub(crate) async fn player_arena_fight( } } - resp.add_key("fight.r"); + resp.start_section("fight.r"); let mut player_a_hp = starting_hp; let mut player_b_hp = starting_hp; @@ -970,13 +970,13 @@ pub(crate) async fn player_arena_fight( break; } } - resp.add_key("winnerid"); + resp.start_section("winnerid"); resp.add_val(if player_a_hp > 0 { fighters[0] } else { fighters[1] }); - resp.add_key("fightresult.battlereward"); + resp.start_section("fightresult.battlereward"); resp.add_val((player_a_hp > 0) as i32); // have we won? resp.add_val(1); resp.add_val(0); // silver diff --git a/src/command/update.rs b/src/command/update.rs index fe08ce7..88e658d 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -18,13 +18,15 @@ pub(crate) async fn poll( mut builder: ResponseBuilder, ) -> Result { let resp = builder - .add_key("serverversion") + .start_section("serverversion") .add_val(SERVER_VERSION) - .add_key("preregister") + .start_section("preregister") .add_val(0) // TODO: This has values .add_val(0) .skip_key(); + let mut tx = db.begin().await?; + let char = sqlx::query!( "SELECT character.pid, --0 @@ -97,7 +99,6 @@ pub(crate) async fn poll( character.name, portrait.influencer, - ( SELECT count(*) FROM CHARACTER AS x @@ -122,78 +123,78 @@ pub(crate) async fn poll( WHERE character.pid = $1", session.player_id ) - .fetch_one(db) + .fetch_one(&mut *tx) .await?; let calendar_info = "12/1/8/1/3/1/25/1/5/1/2/1/3/2/1/1/24/1/18/5/6/1/22/1/\ 7/1/6/2/8/2/22/2/5/2/2/2/3/3/21/1"; - resp.add_key("messagelist.r"); + resp.start_section("messagelist.r"); resp.add_str(";"); - resp.add_key("combatloglist.s"); + resp.start_section("combatloglist.s"); resp.add_str(";"); - resp.add_key("friendlist.r"); + resp.start_section("friendlist.r"); resp.add_str(";"); - resp.add_key("login count"); + resp.start_section("login count"); resp.add_val(session.login_count); resp.skip_key(); - resp.add_key("sessionid"); + resp.start_section("sessionid"); resp.add_str(&session.session_id); - resp.add_key("languagecodelist"); + resp.start_section("languagecodelist"); resp.add_str( "ru,20;fi,8;ar,1;tr,23;nl,16; \ ,0;ja,14;it,13;sk,21;fr,9;ko,15;pl,17;cs,2;el,5;da,3;en,6;hr,10;de,4;\ zh,24;sv,22;hu,11;pt,12;es,7;pt-br,18;ro,19;", ); - resp.add_key("languagecodelist.r"); + resp.start_section("languagecodelist.r"); - resp.add_key("maxpetlevel"); + resp.start_section("maxpetlevel"); resp.add_val(100); - resp.add_key("calenderinfo"); + resp.start_section("calenderinfo"); resp.add_val(calendar_info); resp.skip_key(); - resp.add_key("tavernspecial"); + resp.start_section("tavernspecial"); resp.add_val(0); // 100 if event active - resp.add_key("tavernspecialsub"); + resp.start_section("tavernspecialsub"); resp.add_val(0); // 1 << Event - resp.add_key("tavernspecialend"); + resp.start_section("tavernspecialend"); resp.add_val(in_seconds(600)); - resp.add_key("attbonus1(3)"); + resp.start_section("attbonus1(3)"); resp.add_str("0/0/0/0"); - resp.add_key("attbonus2(3)"); + resp.start_section("attbonus2(3)"); resp.add_str("0/0/0/0"); - resp.add_key("attbonus3(3)"); + resp.start_section("attbonus3(3)"); resp.add_str("0/0/0/0"); - resp.add_key("attbonus4(3)"); + resp.start_section("attbonus4(3)"); resp.add_str("0/0/0/0"); - resp.add_key("attbonus5(3)"); + resp.start_section("attbonus5(3)"); resp.add_str("0/0/0/0"); - resp.add_key("stoneperhournextlevel"); + resp.start_section("stoneperhournextlevel"); resp.add_val(50); - resp.add_key("woodperhournextlevel"); + resp.start_section("woodperhournextlevel"); resp.add_val(150); - resp.add_key("fortresswalllevel"); + resp.start_section("fortresswalllevel"); resp.add_val(5); - resp.add_key("inboxcapacity"); + resp.start_section("inboxcapacity"); resp.add_val(100); - resp.add_key("ownplayersave.playerSave"); + resp.start_section("ownplayersave.playerSave"); resp.add_val(403127023); // What is this? resp.add_val(session.player_id); resp.add_val(0); @@ -683,7 +684,7 @@ pub(crate) async fn poll( resp.add_val(0); // 757 resp.add_str(""); // 758 - resp.add_key("resources"); + resp.start_section("resources"); resp.add_val(session.player_id); // pid resp.add_val(char.mushrooms); // mushrooms resp.add_val(char.silver); // silver @@ -701,31 +702,31 @@ pub(crate) async fn poll( resp.add_val(0); } - resp.add_key("owndescription.s"); + resp.start_section("owndescription.s"); resp.add_str(&to_sf_string(&char.description)); - resp.add_key("ownplayername.r"); + resp.start_section("ownplayername.r"); resp.add_str(&char.name); let maxrank = char.maxrank; - resp.add_key("maxrank"); + resp.start_section("maxrank"); resp.add_val(maxrank); - resp.add_key("skipallow"); + resp.start_section("skipallow"); resp.add_val(0); - resp.add_key("skipvideo"); + resp.start_section("skipvideo"); resp.add_val(0); - resp.add_key("fortresspricereroll"); + resp.start_section("fortresspricereroll"); resp.add_val(18); - resp.add_key("timestamp"); + resp.start_section("timestamp"); resp.add_val(now()); - resp.add_key("fortressprice.fortressPrice(13)"); + resp.start_section("fortressprice.fortressPrice(13)"); resp.add_str( "900/1000/0/0/900/500/35/12/900/200/0/0/900/300/22/0/900/1500/50/17/\ 900/700/7/9/900/500/41/7/900/400/20/14/900/600/61/20/900/2500/40/13/\ @@ -734,57 +735,57 @@ pub(crate) async fn poll( resp.skip_key(); - resp.add_key("unitprice.fortressPrice(3)"); + resp.start_section("unitprice.fortressPrice(3)"); resp.add_str("600/0/15/5/600/0/11/6/300/0/19/3/"); - resp.add_key("upgradeprice.upgradePrice(3)"); + resp.start_section("upgradeprice.upgradePrice(3)"); resp.add_val("28/270/210/28/720/60/28/360/180/"); - resp.add_key("unitlevel(4)"); + resp.start_section("unitlevel(4)"); resp.add_val("5/25/25/25/"); resp.skip_key(); resp.skip_key(); - resp.add_key("petsdefensetype"); + resp.start_section("petsdefensetype"); resp.add_val(3); - resp.add_key("singleportalenemylevel"); + resp.start_section("singleportalenemylevel"); resp.add_val(0); resp.skip_key(); - resp.add_key("wagesperhour"); + resp.start_section("wagesperhour"); resp.add_val(10); resp.skip_key(); - resp.add_key("dragongoldbonus"); + resp.start_section("dragongoldbonus"); resp.add_val(30); - resp.add_key("toilettfull"); + resp.start_section("toilettfull"); resp.add_val(0); - resp.add_key("maxupgradelevel"); + resp.start_section("maxupgradelevel"); resp.add_val(20); - resp.add_key("cidstring"); + resp.start_section("cidstring"); resp.add_str("no_cid"); if !tracking.is_empty() { - resp.add_key("tracking.s"); + resp.start_section("tracking.s"); resp.add_str(tracking); } - resp.add_key("calenderinfo"); + resp.start_section("calenderinfo"); resp.add_str(calendar_info); resp.skip_key(); - resp.add_key("iadungeontime"); + resp.start_section("iadungeontime"); resp.add_str("5/1702656000/1703620800/1703707200"); - resp.add_key("achievement(208)"); + resp.start_section("achievement(208)"); resp.add_str( "0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/\ 0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/\ @@ -795,19 +796,19 @@ pub(crate) async fn poll( 0/0/0/0/", ); - resp.add_key("scrapbook.r"); + resp.start_section("scrapbook.r"); resp.add_str("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); - resp.add_key("smith"); + resp.start_section("smith"); resp.add_str("5/0"); - resp.add_key("owntowerlevel"); + resp.start_section("owntowerlevel"); resp.add_val(0); - resp.add_key("webshopid"); + resp.start_section("webshopid"); resp.add_str("Q7tGCJhe$r464"); - resp.add_key("dailytasklist"); + resp.start_section("dailytasklist"); resp.add_val(98); for typ_id in 1..=10 { resp.add_val(typ_id); // typ @@ -816,7 +817,7 @@ pub(crate) async fn poll( resp.add_val(10); // reward } - resp.add_key("eventtasklist"); + resp.start_section("eventtasklist"); for typ_id in 1..=99 { if typ_id == 73 { continue; @@ -827,19 +828,19 @@ pub(crate) async fn poll( resp.add_val(typ_id); // reward } - resp.add_key("dailytaskrewardpreview"); + resp.start_section("dailytaskrewardpreview"); add_reward_previews(resp); - resp.add_key("eventtaskrewardpreview"); + resp.start_section("eventtaskrewardpreview"); add_reward_previews(resp); - resp.add_key("eventtaskinfo"); + resp.start_section("eventtaskinfo"); resp.add_val(1708300800); resp.add_val(1798646399); resp.add_val(2); // event typ - resp.add_key("unlockfeature"); + resp.start_section("unlockfeature"); let dungeon_progress_light = [ 0, // DesecratedCatacombs = 0, @@ -881,7 +882,7 @@ pub(crate) async fn poll( 5, // Meeting room = 36 ]; - resp.add_key(&format!( + resp.start_section(&format!( "dungeonprogresslight({})", dungeon_progress_light.len() )); @@ -929,7 +930,7 @@ pub(crate) async fn poll( 5, // Meeting room = 36 ]; - resp.add_key(&format!( + resp.start_section(&format!( "dungeonprogressshadow({})", dungeon_progress_shadow.len() )); @@ -939,14 +940,14 @@ pub(crate) async fn poll( let dungeon_info = calc_dungeon_progress(&dungeon_progress_light, false); - resp.add_key(&format!("dungeonenemieslight({})", dungeon_info.len())); + resp.start_section(&format!("dungeonenemieslight({})", dungeon_info.len())); for dungeon in &dungeon_info { resp.add_val(dungeon.enemy.monster_name); resp.add_val(dungeon.id); resp.add_val(dungeon.enemy.loot); } - resp.add_key(&format!( + resp.start_section(&format!( "currentdungeonenemieslight({})", dungeon_info.iter().filter(|a| a.is_current).count() )); @@ -960,14 +961,17 @@ pub(crate) async fn poll( let dungeon_info = calc_dungeon_progress(&dungeon_progress_shadow, true); - resp.add_key(&format!("dungeonenemiesshadow({})", dungeon_info.len())); + resp.start_section(&format!( + "dungeonenemiesshadow({})", + dungeon_info.len() + )); for dungeon in &dungeon_info { resp.add_val(dungeon.enemy.monster_name); resp.add_val(dungeon.id); resp.add_val(dungeon.enemy.loot); } - resp.add_key(&format!( + resp.start_section(&format!( "currentdungeonenemiesshadow({})", dungeon_info.iter().filter(|a| a.is_current).count() )); @@ -979,7 +983,7 @@ pub(crate) async fn poll( resp.add_val(dungeon.enemy.element); } - resp.add_key("portalprogress(3)"); + resp.start_section("portalprogress(3)"); resp.add_val("27/100/194"); resp.skip_key(); @@ -990,11 +994,10 @@ pub(crate) async fn poll( WHERE pid = $1", session.player_id ) - .fetch_all(db) + .fetch_all(&mut *tx) .await?; - resp.add_key("expeditions"); - + resp.start_section("expeditions"); for exp in expeditions { resp.add_val(exp.target); // typ resp.add_val(71); // ?? @@ -1006,13 +1009,54 @@ pub(crate) async fn poll( resp.add_val(0); // 1 => egg, 2 => inc. daily task } - resp.add_key("expeditionevent"); + resp.start_section("expeditionevent"); resp.add_val(in_seconds(-60 * 60)); resp.add_val(in_seconds(60 * 60)); resp.add_val(1); resp.add_val(in_seconds(60 * 60)); - resp.add_key("usersettings"); + let expedition = sqlx::query!( + "SELECT * FROM ActiveExpedition WHERE pid = $1", session.player_id + ) + .fetch_optional(&mut *tx) + .await?; + + if let Some(exp) = expedition { + resp.start_section("expeditionstate"); + resp.add_val(exp.current_floor); + resp.add_val(14); // ?? + resp.add_val(exp.floor_stage); + resp.add_val(exp.target); // 3 + resp.add_val(124); // 4 + resp.add_val(32); // 5 + resp.add_val(83); // 6 + resp.add_val(exp.target_current); // 7 + resp.add_val(exp.target_amount); // 8 + resp.add_val(exp.item1.unwrap_or(0)); // 9 + resp.add_val(exp.item2.unwrap_or(0)); // 10 + resp.add_val(exp.item3.unwrap_or(0)); // 11 + resp.add_val(exp.item4.unwrap_or(0)); // 12 + resp.add_val(exp.heroism); // 13 + resp.add_val(0); // busy since + resp.add_val(0); // busy until + resp.add_val(0); // ?? + resp.add_val(5); // ?? + resp.add_val(-5); // ?? + resp.add_val(0); // ?? + resp.add_val(1); // ?? + + resp.start_section("expeditioncrossroad"); + + for enc in [exp.encounter1, exp.encounter2, exp.encounter3] { + if enc == 0 { + break; + } + resp.add_val(enc); // encounter type + resp.add_val(10); // Heroism for encounter + } + } + + resp.start_section("usersettings"); resp.add_str("en"); resp.add_val(0); resp.add_val(0); @@ -1020,13 +1064,13 @@ pub(crate) async fn poll( resp.add_str("a"); resp.add_val(0); - resp.add_key("mailinvoice"); + resp.start_section("mailinvoice"); resp.add_str("a*******@a****.***"); - resp.add_key("cryptoid"); + resp.start_section("cryptoid"); resp.add_val(session.crypto_id); - resp.add_key("cryptokey"); + resp.start_section("cryptokey"); resp.add_val(session.crypto_key); // resp.add_key("pendingrewards"); @@ -1039,6 +1083,8 @@ pub(crate) async fn poll( // resp.add_val(1718382386); // } + tx.commit().await?; + resp.build() } diff --git a/src/response.rs b/src/response.rs index fa49d5c..556407b 100644 --- a/src/response.rs +++ b/src/response.rs @@ -59,7 +59,7 @@ pub struct ResponseBuilder { } impl ResponseBuilder { - pub fn add_key(&mut self, key: &str) -> &mut ResponseBuilder { + pub fn start_section(&mut self, key: &str) -> &mut ResponseBuilder { if !self.resp.is_empty() { self.resp.push('&') } From 140edbf40538ceeeeb1e475f05217bdb4d2a4b06 Mon Sep 17 00:00:00 2001 From: Marenga Date: Tue, 5 Aug 2025 18:49:20 +0200 Subject: [PATCH 08/14] Some work on expeditons --- src/command/update.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/command/update.rs b/src/command/update.rs index 88e658d..b0026b4 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -1015,18 +1015,18 @@ pub(crate) async fn poll( resp.add_val(1); resp.add_val(in_seconds(60 * 60)); - let expedition = sqlx::query!( + let active_expedition = sqlx::query!( "SELECT * FROM ActiveExpedition WHERE pid = $1", session.player_id ) .fetch_optional(&mut *tx) .await?; - if let Some(exp) = expedition { + if let Some(exp) = active_expedition { resp.start_section("expeditionstate"); resp.add_val(exp.current_floor); - resp.add_val(14); // ?? + resp.add_val(14); // location resp.add_val(exp.floor_stage); - resp.add_val(exp.target); // 3 + resp.add_val(exp.target); resp.add_val(124); // 4 resp.add_val(32); // 5 resp.add_val(83); // 6 @@ -1054,6 +1054,29 @@ pub(crate) async fn poll( resp.add_val(enc); // encounter type resp.add_val(10); // Heroism for encounter } + + // expeditionstate:5/1/3/124/71/0/0/0/1/122/1012/0/0/-4/0/0/0/10/-5/0/1& + // expeditioncrossroad:123/-5/123/-5/131/0& + // expeditionmonster:-145/& + // expeditionhalftime:-145/6/6/4/219/26/1& + // expeditionevent:1754321308/1754494108/1/1754494108& + + if exp.current_floor == 5 { + if exp.floor_stage == 2 { + resp.start_section("expeditionmonster"); + resp.add_val(-exp.boss_id); + resp.add_str(""); // Number of items + } else if exp.floor_stage == 3 { + resp.start_section("expeditionhalftime"); + resp.add_val(-exp.boss_id); + resp.add_val(exp.reward1_type); + resp.add_val(exp.reward1_amount); + resp.add_val(exp.reward2_type); + resp.add_val(exp.reward2_amount); + resp.add_val(exp.reward3_type); + resp.add_val(exp.reward3_amount); + } + } } resp.start_section("usersettings"); From c8666f9411f4a32a2b337bfc43e9c9f1074ee792 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sat, 20 Sep 2025 13:14:14 +0200 Subject: [PATCH 09/14] Reverse engineering items --- src/command/update.rs | 54 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/command/update.rs b/src/command/update.rs index b0026b4..36b549a 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -247,8 +247,8 @@ pub(crate) async fn poll( resp.add_val(0); // 40..=44 } - resp.add_val(char.activitytyp); // Current action - resp.add_val(char.activitysubtyp); // Secondary (time busy) + resp.add_val(0); // Current action + resp.add_val(0); // Secondary (time busy) resp.add_val(char.busy_until); // Busy until // Equipment @@ -393,8 +393,8 @@ pub(crate) async fn poll( resp.add_val(0); // 489 resp.add_val(0); // 490 - resp.add_val(0); // 491 aura_level (0 == locked) - resp.add_val(0); // 492 aura_now + resp.add_val(500); // 491 aura_level (0 == locked) + resp.add_val(100); // 492 aura_now // Active potions for _ in 0..3 { @@ -1096,6 +1096,52 @@ pub(crate) async fn poll( resp.start_section("cryptokey"); resp.add_val(session.crypto_key); + resp.start_section("toiletstate"); + resp.add_val(100); // Aura required maybe? Seems to do nothing rn + resp.add_val(0); // Might be overflow + resp.add_val(1); + + resp.start_section("ownplayersaveequipment"); + let vals = [ + [6, 1, 61, 2008, 10, 1315, 0, 2, 0, 31, 755, 0, 12, 64237500, 0, 0, 0, 0, 0], + [3, 25, 31, 2063, 50, 1589, 0, 6, 0, 34, 379, 0, 3, 200000000, 0, 0, 259, 0, 0], + [5, 24, 51, 2010, 1, 1959, 0, 2, 5, 4, 748, 0, 0, 50761792, 0, 0, 398, 0, 0], + [4, 25, 41, 2054, 30, 982, 0, 22, 0, 32, 389, 0, 12, 159711312, 0, 0, 237, 0, 0], + [8, 1, 81, 11, 10, 0, 0, 2, 0, 0, 756, 0, 0, 157096290, 0, 0, 0, 0, 0], + [7, 1, 71, 2010, 1, 1548, 0, 2, 0, 0, 760, 0, 0, 63002228, 0, 0, 0, 0, 0], + [9, 1, 91, 8, 10, 0, 0, 2, 0, 0, 763, 0, 0, 55415228, 0, 0, 0, 0, 0], + [10, 1, 101, 15, 20, 0, 0, 2, 0, 0, 740, 0, 0, 46696042, 0, 0, 0, 0, 0], + [1, 1, 11, 30, 5, 415, 1101, 4, 0, 0, 747, 0, 0, 59738715, 0, 0, 0, 0, 0], + [1, 1, 11, 30, 5, 415, 1101, 4, 0, 0, 747, 0, 0, 59738715, 0, 0, 0, 0, 0], + // 1/1/11/2010/5/ 518/1376/1/0/0/1494/0/0/59738715/0/0/0/0/1 + ]; + + for item in vals { + for v in item { + // [0] => item type + // [1] => gem slot / type + // [2] => Enchantment + // [3] => model id / class / sub ident + // [4] => enchantment effect + // [5] => min_attack / armor. [color] + // [6] => max_attack [color] + // [7] => atr typ 1 / rune [color] + // [8] => atr typ 2 / rune [color] + // [9] => atr typ 3 / rune [color] + // [10] => atr val 1 [color] + // [11] => atr val 2 [color] + // [12] => atr val 3 [color] + // [13] => sell price + // [14] => probably mushroom price + // [15] => upgrade_count (blacksmith) + // [16] => gem val + // [17] => item quality + // [18] => is_washed + resp.add_val(v); + } + } + + // resp.add_key("pendingrewards"); // for i in 0..10 { // resp.add_val(9999 + i); From 8176ffb714f6c66d2bd606c0c3c5b0854b105fb0 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sun, 21 Sep 2025 15:52:16 +0200 Subject: [PATCH 10/14] Legendary dungeons --- src/command/account.rs | 7 +- src/command/update.rs | 188 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 179 insertions(+), 16 deletions(-) diff --git a/src/command/account.rs b/src/command/account.rs index 84a1348..ec9572c 100644 --- a/src/command/account.rs +++ b/src/command/account.rs @@ -292,9 +292,10 @@ pub(crate) async fn account_login( let pwhash = info.pw_hash; let correct_full_hash = sha1_hash(&format!("{pwhash}{login_count}")); - if correct_full_hash != full_hash { - Err(ServerError::WrongPassword)?; - } + + // if correct_full_hash != full_hash { + // Err(ServerError::WrongPassword)?; + // } let session_id: String = (0..DEFAULT_SESSION_ID.len()) .map(|_| rng.alphanumeric()) diff --git a/src/command/update.rs b/src/command/update.rs index 36b549a..62bb5e0 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -782,9 +782,6 @@ pub(crate) async fn poll( resp.skip_key(); - resp.start_section("iadungeontime"); - resp.add_str("5/1702656000/1703620800/1703707200"); - resp.start_section("achievement(208)"); resp.add_str( "0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/\ @@ -1103,16 +1100,45 @@ pub(crate) async fn poll( resp.start_section("ownplayersaveequipment"); let vals = [ - [6, 1, 61, 2008, 10, 1315, 0, 2, 0, 31, 755, 0, 12, 64237500, 0, 0, 0, 0, 0], - [3, 25, 31, 2063, 50, 1589, 0, 6, 0, 34, 379, 0, 3, 200000000, 0, 0, 259, 0, 0], - [5, 24, 51, 2010, 1, 1959, 0, 2, 5, 4, 748, 0, 0, 50761792, 0, 0, 398, 0, 0], - [4, 25, 41, 2054, 30, 982, 0, 22, 0, 32, 389, 0, 12, 159711312, 0, 0, 237, 0, 0], - [8, 1, 81, 11, 10, 0, 0, 2, 0, 0, 756, 0, 0, 157096290, 0, 0, 0, 0, 0], - [7, 1, 71, 2010, 1, 1548, 0, 2, 0, 0, 760, 0, 0, 63002228, 0, 0, 0, 0, 0], - [9, 1, 91, 8, 10, 0, 0, 2, 0, 0, 763, 0, 0, 55415228, 0, 0, 0, 0, 0], - [10, 1, 101, 15, 20, 0, 0, 2, 0, 0, 740, 0, 0, 46696042, 0, 0, 0, 0, 0], - [1, 1, 11, 30, 5, 415, 1101, 4, 0, 0, 747, 0, 0, 59738715, 0, 0, 0, 0, 0], - [1, 1, 11, 30, 5, 415, 1101, 4, 0, 0, 747, 0, 0, 59738715, 0, 0, 0, 0, 0], + [ + 6, 1, 61, 2008, 10, 1315, 0, 2, 0, 31, 755, 0, 12, 64237500, 0, 0, + 0, 0, 0, + ], + [ + 3, 25, 31, 2063, 50, 1589, 0, 6, 0, 34, 379, 0, 3, 200000000, 0, 0, + 259, 0, 0, + ], + [ + 5, 24, 51, 2010, 1, 1959, 0, 2, 5, 4, 748, 0, 0, 50761792, 0, 0, + 398, 0, 0, + ], + [ + 4, 25, 41, 2054, 30, 982, 0, 22, 0, 32, 389, 0, 12, 159711312, 0, + 0, 237, 0, 0, + ], + [ + 8, 1, 81, 11, 10, 0, 0, 2, 0, 0, 756, 0, 0, 157096290, 0, 0, 0, 0, + 0, + ], + [ + 7, 1, 71, 2010, 1, 1548, 0, 2, 0, 0, 760, 0, 0, 63002228, 0, 0, 0, + 0, 0, + ], + [ + 9, 1, 91, 8, 10, 0, 0, 2, 0, 0, 763, 0, 0, 55415228, 0, 0, 0, 0, 0, + ], + [ + 10, 1, 101, 15, 20, 0, 0, 2, 0, 0, 740, 0, 0, 46696042, 0, 0, 0, 0, + 0, + ], + [ + 1, 1, 11, 30, 5, 415, 1101, 4, 0, 0, 747, 0, 0, 59738715, 0, 0, 0, + 0, 0, + ], + [ + 1, 1, 11, 30, 5, 415, 1101, 4, 0, 0, 747, 0, 0, 59738715, 0, 0, 0, + 0, 0, + ], // 1/1/11/2010/5/ 518/1376/1/0/0/1494/0/0/59738715/0/0/0/0/1 ]; @@ -1141,6 +1167,142 @@ pub(crate) async fn poll( } } + resp.start_section("iamap"); + resp.add_val(25); + resp.add_val(-5159); + + // 0 => max 0 + // 1..=4 => max 1 + // 5..=8 => max 2 + // 9..=12 => max 3 + // 13.. => max 4 + resp.add_val(9); // Removes other? + // -315 => 0 / X + // 315 => 1 / X + resp.add_val(315); + + resp.add_val(25); + resp.add_val(-5160); + resp.add_val(9); + resp.add_val(-315); + + resp.add_val(25); + resp.add_val(-5172); + resp.add_val(9); + resp.add_val(-315); + + resp.add_val(25); + resp.add_val(-5168); + resp.add_val(9); + resp.add_val(-315); + + resp.start_section("iamerchant"); + resp.add_val(102); + resp.add_val(40100); + resp.add_val(5); + + resp.add_val(3); + resp.add_val(50080); + resp.add_val(0); + + resp.start_section("iadungeonstats"); + resp.add_val(100); // items looted + resp.add_val(17); // epic items looted + resp.add_val(300); // keys found + resp.add_val(1846722900); // silver found + resp.add_val(1); // attempts + + resp.start_section("iadungeonstatstotal"); + resp.add_val(69); + resp.add_val(420); + resp.add_val(5); + resp.add_val(77); + resp.add_val(1846722900); + resp.add_val(2); // Unknown + + resp.start_section("iadungeon.iadungeonsave"); + + resp.add_val(993073103); + + // Player health status? + resp.add_val(2); // healing hp ? + // 0 => healing + // 1 => allowed to enter? + // 2 => alive + + resp.add_val(-511294); // current hp + resp.add_val(553143); // pre attack hp + + resp.add_val(7642555); // total hp + + resp.add_val(0); // blessing type + resp.add_val(0); + resp.add_val(0); + + resp.add_val(0); // curse type? + resp.add_val(0); + resp.add_val(0); + + resp.add_val(0); // blessing duration & strength + resp.add_val(0); + resp.add_val(0); + + resp.add_val(0); // curse 1 duration + + resp.add_val(101); // stage (15) // Finished? + resp.add_val(0); // stage extra? + + resp.add_val(25); // current floor + resp.add_val(100); // max floor + + resp.add_val(1); // 19 // left door & room type + resp.add_val(0); // 20 // right door type + + resp.add_val(0); + + resp.add_val(-5159); // 22 encounter type + + resp.add_val(0); // appeared after death + resp.add_val(0); + + resp.add_val(0); // trap left + resp.add_val(0); // trap right + + // Item + for _ in 0..12 { + resp.add_val(0); + } + + resp.add_val(1); // keys + resp.add_val(0); // 40 + resp.add_val(0); + + resp.add_val(0); // 42 + resp.add_val(0); + resp.add_val(0); + + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + + resp.add_val(0); + resp.add_val(0); // 49 + + resp.start_section("iadungeontime"); + resp.add_val(1); + resp.add_val(in_seconds(-600)); + resp.add_val(in_seconds(6000)); + resp.add_val(in_seconds(6000 + ((60 * 60) * 24))); + + resp.start_section("iadungeon20cost"); + resp.add_str("10"); + + // 18 => + resp.start_section("iadungeonsoulstones"); + resp.add_str("0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"); + resp.add_str("4/1/1/0/0/30"); + resp.add_str("5/10/1/0/0/31"); + resp.add_str("6/30/1/0/0/32"); // resp.add_key("pendingrewards"); // for i in 0..10 { From 5e2b913388f433f4b2de3e280ba3f5041dea53bb Mon Sep 17 00:00:00 2001 From: Marenga Date: Fri, 23 Jan 2026 22:39:06 +0100 Subject: [PATCH 11/14] World boss testing --- src/command/mod.rs | 2 + src/command/update.rs | 471 +++++++++++++++++++++++++++++------------- 2 files changed, 335 insertions(+), 138 deletions(-) diff --git a/src/command/mod.rs b/src/command/mod.rs index b149b32..458d99c 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -86,6 +86,8 @@ pub(crate) async fn handle_command<'a>( "UserSettingsUpdate" => Ok(ServerResponse::Success), // TODO: "getserverversion" => get_server_version(session, db).await, "ExpeditionStart" => player_start_expedition(session, db, args).await, + "WorldBossEventPoll" | "WorldBossEnter" => poll(session, "", db, Default::default()).await, + "WorldBossLogRewards" | "WorldBossLogDayInfos" => Ok(ServerResponse::Success), _ => { error!("Unknown command: {name} - {args:?}"); Err(ServerError::UnknownRequest(name.into())) diff --git a/src/command/update.rs b/src/command/update.rs index 62bb5e0..009a17e 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -1,5 +1,7 @@ use sf_api::{ - command::AttributeType, gamestate::items::EquipmentSlot, misc::to_sf_string, + command::AttributeType, + gamestate::{items::EquipmentSlot, rewards::Event}, + misc::to_sf_string, }; use sqlx::Sqlite; use strum::IntoEnumIterator; @@ -164,13 +166,310 @@ pub(crate) async fn poll( resp.skip_key(); resp.start_section("tavernspecial"); - resp.add_val(0); // 100 if event active + resp.add_val(100); // 100 if event active resp.start_section("tavernspecialsub"); - resp.add_val(0); // 1 << Event + resp.add_val(1 << 17); resp.start_section("tavernspecialend"); resp.add_val(in_seconds(600)); + // resp.start_section("adventscalendar"); + // resp.add_val("3"); + // resp.add_val("100"); + + resp.start_section("eventstatus"); + resp.add_val(6); + resp.add_val(2); + resp.add_val(in_seconds(-100)); + resp.add_val(in_seconds(999999)); + resp.add_val(in_seconds(999999)); + + resp.start_section("wbcharacter"); + resp.add_val(6969); // catalyst + resp.add_val(420); // medals + resp.add_val(50); // rank + resp.add_val(1); // lvl + + resp.add_val(100); // ??? + + resp.add_val(in_seconds(60)); // next atk + resp.add_val(2550); // dmg per atk + resp.add_val(121); // ??? + resp.add_val(121); // ??? + resp.add_val(20_000); // dmg per hour + resp.add_val(1007); // loot per hour + resp.add_val(433); // comparative + + resp.add_val(100); // chests + + resp.add_val(121); // ??? + + resp.add_val(in_seconds(9999)); // reward dist + + // The chest we got + resp.start_section("wbdailychests"); + resp.add_val(1); + resp.add_val(1); + resp.add_val(1); + resp.add_val(1); + + resp.start_section("wblogloot"); + resp.add_val(0); // battle loot + resp.add_val(0); // weak point chest + resp.add_val(0); // kill steal chest + resp.add_val(0); // damage master chest + resp.add_val(0); // single hit chest + + resp.start_section("wbupgradestore"); + + for i in 1..=3 { + resp.add_val(1); // typ + resp.add_val(1); // restriction + resp.add_val(1); // effect val 1 + + let price = ((i * 10_000) * 100) / 3; + resp.add_val(price); // main price + resp.add_val(10); // main type + resp.add_val(price); // secondary price + resp.add_val(price); // mushroom price + } + + resp.start_section("wbammostore"); + for i in 0..3 { + resp.add_val(i + 1); + + resp.add_val(20); // small_amount + resp.add_val(50); // large_amount + + resp.add_val(10); // effect value + + resp.add_val(100); // 20x price + resp.add_val(250); // 50x price + } + + resp.start_section("wblogattacks"); + + resp.add_val(1769173199); + resp.add_val(49); + resp.add_val(2); + resp.add_val(1769170381); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769169902); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769169599); + resp.add_val(169); + resp.add_val(7); + resp.add_val(1769169362); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769168881); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769168401); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769167861); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769167381); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769166841); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769166361); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769165999); + resp.add_val(152); + resp.add_val(7); + resp.add_val(1769165881); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769165342); + resp.add_val(50); + resp.add_val(1); + resp.add_val(2550); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769164861); + resp.add_val(50); + resp.add_val(1); + resp.add_val(1856); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769164321); + resp.add_val(50); + resp.add_val(1); + resp.add_val(1856); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769163842); + resp.add_val(50); + resp.add_val(1); + resp.add_val(3712); + resp.add_val(1); + resp.add_val(0); + resp.add_val(1769163361); + resp.add_val(50); + resp.add_val(1); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769162761); + resp.add_val(50); + resp.add_val(3); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769162399); + resp.add_val(99); + resp.add_val(6); + resp.add_val(1769162161); + resp.add_val(50); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769161622); + resp.add_val(50); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769161022); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769160482); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769159881); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769159281); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769158799); + resp.add_val(82); + resp.add_val(5); + resp.add_val(1769158682); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769158081); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769157481); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769156882); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1769156282); + resp.add_val(45); + resp.add_val(2); + resp.add_val(1735); + resp.add_val(0); + resp.add_val(0); + + resp.start_section("wbtower"); + resp.add_val(1); // boss nr + resp.add_val(40); // ?? + resp.add_val(2); // weak point + resp.add_val(1); // has_been_hit + + for _ in 0..3 { + resp.add_val(740); // Signed up heroes + resp.add_val(23704175); // Joint damage + resp.add_val(62500000); // max health + resp.add_val(21134662); // remaining health + + resp.add_val(600); // active special attacks + + // most total damage + for _ in 0..10 { + resp.add_val(6969); // lvl + resp.add_str("username"); + } + + // Most special attacks + for _ in 0..3 { + resp.add_val(6969); // lvl + resp.add_str("username"); + resp.add_val(10000); // count? + } + } + + resp.start_section("wbupgrade"); + resp.add_val(in_seconds(90)); + + for i in 0..4 { + resp.add_val(i + 1); + resp.add_val(2); + resp.add_val(9); + resp.add_val(10000); + } + + resp.start_section("wbammo"); + resp.add_val(3); + resp.add_val(25); + resp.add_val(100); + resp.start_section("attbonus1(3)"); resp.add_str("0/0/0/0"); resp.start_section("attbonus2(3)"); @@ -234,7 +533,7 @@ pub(crate) async fn poll( // Attributes for _ in AttributeType::iter() { - resp.add_val(100); // 30..=34 + resp.add_val(10000); // 30..=34 } // attribute_additions (aggregate from equipment) @@ -1003,7 +1302,7 @@ pub(crate) async fn poll( resp.add_val(exp.location_1); // location 1 resp.add_val(exp.location_2); // location 2 resp.add_val(exp.alu_sec); // alu - resp.add_val(0); // 1 => egg, 2 => inc. daily task + resp.add_val(1); // 1 => egg, 2 => inc. daily task } resp.start_section("expeditionevent"); @@ -1167,142 +1466,38 @@ pub(crate) async fn poll( } } - resp.start_section("iamap"); - resp.add_val(25); - resp.add_val(-5159); - - // 0 => max 0 - // 1..=4 => max 1 - // 5..=8 => max 2 - // 9..=12 => max 3 - // 13.. => max 4 - resp.add_val(9); // Removes other? - // -315 => 0 / X - // 315 => 1 / X - resp.add_val(315); - - resp.add_val(25); - resp.add_val(-5160); - resp.add_val(9); - resp.add_val(-315); - - resp.add_val(25); - resp.add_val(-5172); - resp.add_val(9); - resp.add_val(-315); - - resp.add_val(25); - resp.add_val(-5168); - resp.add_val(9); - resp.add_val(-315); - - resp.start_section("iamerchant"); - resp.add_val(102); - resp.add_val(40100); - resp.add_val(5); - - resp.add_val(3); - resp.add_val(50080); - resp.add_val(0); - - resp.start_section("iadungeonstats"); - resp.add_val(100); // items looted - resp.add_val(17); // epic items looted - resp.add_val(300); // keys found - resp.add_val(1846722900); // silver found - resp.add_val(1); // attempts - - resp.start_section("iadungeonstatstotal"); - resp.add_val(69); - resp.add_val(420); - resp.add_val(5); - resp.add_val(77); - resp.add_val(1846722900); - resp.add_val(2); // Unknown - - resp.start_section("iadungeon.iadungeonsave"); - - resp.add_val(993073103); - - // Player health status? - resp.add_val(2); // healing hp ? - // 0 => healing - // 1 => allowed to enter? - // 2 => alive - - resp.add_val(-511294); // current hp - resp.add_val(553143); // pre attack hp - - resp.add_val(7642555); // total hp - - resp.add_val(0); // blessing type - resp.add_val(0); - resp.add_val(0); - - resp.add_val(0); // curse type? - resp.add_val(0); - resp.add_val(0); - - resp.add_val(0); // blessing duration & strength - resp.add_val(0); - resp.add_val(0); - - resp.add_val(0); // curse 1 duration - - resp.add_val(101); // stage (15) // Finished? - resp.add_val(0); // stage extra? - - resp.add_val(25); // current floor - resp.add_val(100); // max floor - - resp.add_val(1); // 19 // left door & room type - resp.add_val(0); // 20 // right door type - - resp.add_val(0); - - resp.add_val(-5159); // 22 encounter type - - resp.add_val(0); // appeared after death - resp.add_val(0); - - resp.add_val(0); // trap left - resp.add_val(0); // trap right - - // Item - for _ in 0..12 { + resp.start_section("ownplayersaveequipment"); + for _ in 0..10 { resp.add_val(0); } - resp.add_val(1); // keys - resp.add_val(0); // 40 - resp.add_val(0); - - resp.add_val(0); // 42 - resp.add_val(0); - resp.add_val(0); - - resp.add_val(0); - resp.add_val(0); - resp.add_val(0); - - resp.add_val(0); - resp.add_val(0); // 49 - - resp.start_section("iadungeontime"); - resp.add_val(1); - resp.add_val(in_seconds(-600)); - resp.add_val(in_seconds(6000)); - resp.add_val(in_seconds(6000 + ((60 * 60) * 24))); - - resp.start_section("iadungeon20cost"); - resp.add_str("10"); - - // 18 => - resp.start_section("iadungeonsoulstones"); - resp.add_str("0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"); - resp.add_str("4/1/1/0/0/30"); - resp.add_str("5/10/1/0/0/31"); - resp.add_str("6/30/1/0/0/32"); + resp.start_section("backpack"); + let inv_len = 5; + resp.add_val(10); // item type + resp.add_val(0); // gem slot / type + resp.add_val(0); // Enchantment + resp.add_val(35); // model id / class / sub ident + resp.add_val(0); // enchantment effect % + resp.add_val(0); // armor YES + resp.add_val(0); // max_attack + resp.add_val(4); // atr typ 1 / rune + resp.add_val(0); // atr typ 2 / rune + resp.add_val(0); // atr typ 3 / rune + + resp.add_val(306); // atr val 1 + resp.add_val(0); // atr val 2 + resp.add_val(0); // atr val 3 + + resp.add_val(0); // sell price + resp.add_val(0); // probably mushroom price + resp.add_val(0); // upgrade_count (blacksmith) + resp.add_val(0); // gem val + resp.add_val(0); // item quality NO + resp.add_val(0); // is_washed NO + + for _ in 0..(inv_len - 1) { + resp.add_val(0); + } // resp.add_key("pendingrewards"); // for i in 0..10 { From 0229162b8a66e2666a5c04bf8e76ef8ced580cb2 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sun, 29 Mar 2026 05:20:12 +0200 Subject: [PATCH 12/14] misc. world boss testing --- src/command/update.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/command/update.rs b/src/command/update.rs index 009a17e..a95fd60 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -208,7 +208,7 @@ pub(crate) async fn poll( // The chest we got resp.start_section("wbdailychests"); - resp.add_val(1); + resp.add_val(0); resp.add_val(1); resp.add_val(1); resp.add_val(1); @@ -222,14 +222,14 @@ pub(crate) async fn poll( resp.start_section("wbupgradestore"); - for i in 1..=3 { + for _ in 1..=3 { resp.add_val(1); // typ resp.add_val(1); // restriction resp.add_val(1); // effect val 1 - let price = ((i * 10_000) * 100) / 3; + let price = 1; // ((i * 10_000) * 100) / 3; resp.add_val(price); // main price - resp.add_val(10); // main type + resp.add_val(4); // main type resp.add_val(price); // secondary price resp.add_val(price); // mushroom price } @@ -438,7 +438,6 @@ pub(crate) async fn poll( resp.add_val(23704175); // Joint damage resp.add_val(62500000); // max health resp.add_val(21134662); // remaining health - resp.add_val(600); // active special attacks // most total damage @@ -456,19 +455,19 @@ pub(crate) async fn poll( } resp.start_section("wbupgrade"); - resp.add_val(in_seconds(90)); + resp.add_val(in_seconds((60 * 60 * 10) / 2)); for i in 0..4 { resp.add_val(i + 1); resp.add_val(2); - resp.add_val(9); + resp.add_val(1); resp.add_val(10000); } resp.start_section("wbammo"); - resp.add_val(3); - resp.add_val(25); - resp.add_val(100); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); resp.start_section("attbonus1(3)"); resp.add_str("0/0/0/0"); @@ -986,7 +985,7 @@ pub(crate) async fn poll( resp.start_section("resources"); resp.add_val(session.player_id); // pid resp.add_val(char.mushrooms); // mushrooms - resp.add_val(char.silver); // silver + resp.add_val(char.silver + 10000000); // silver resp.add_val(0); // lucky coins resp.add_val(char.quicksand); // quicksand glasses resp.add_val(0); // wood From 67a51cd23596c5e5a33aee9f47e4ef74a6ba5be6 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sun, 29 Mar 2026 06:30:20 +0200 Subject: [PATCH 13/14] Updted for ldungeon & new api --- src/command/update.rs | 496 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 489 insertions(+), 7 deletions(-) diff --git a/src/command/update.rs b/src/command/update.rs index a95fd60..50f9b93 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -1,7 +1,5 @@ use sf_api::{ - command::AttributeType, - gamestate::{items::EquipmentSlot, rewards::Event}, - misc::to_sf_string, + command::AttributeType, gamestate::items::EquipmentSlot, misc::to_sf_string, }; use sqlx::Sqlite; use strum::IntoEnumIterator; @@ -1465,10 +1463,16 @@ pub(crate) async fn poll( } } - resp.start_section("ownplayersaveequipment"); - for _ in 0..10 { - resp.add_val(0); - } + + resp.start_section("events"); + resp.add_val(7); + resp.add_val(147796); + resp.add_val(1774828740); + resp.add_val(2097153); + resp.add_val(1775519940); + resp.add_val(20); + resp.add_val(5); + resp.add_val(2097152); resp.start_section("backpack"); let inv_len = 5; @@ -1508,6 +1512,484 @@ pub(crate) async fn poll( // resp.add_val(1718382386); // } + resp.start_section("iadungeonchances"); + resp.add_val(0); + resp.add_val(20); + resp.add_val(1); + resp.add_val(200); + resp.add_val(2); + resp.add_val(0); + resp.add_val(3); + resp.add_val(400); + resp.add_val(4); + resp.add_val(400); + resp.add_val(5); + resp.add_val(400); + resp.add_val(6); + resp.add_val(400); + resp.add_val(7); + resp.add_val(400); + resp.add_val(8); + resp.add_val(400); + resp.add_val(9); + resp.add_val(400); + resp.add_val(10); + resp.add_val(400); + resp.add_val(11); + resp.add_val(200); + resp.add_val(12); + resp.add_val(0); + resp.add_val(13); + resp.add_val(800); + resp.add_val(14); + resp.add_val(800); + resp.add_val(15); + resp.add_val(800); + resp.add_val(16); + resp.add_val(800); + resp.add_val(17); + resp.add_val(800); + resp.add_val(18); + resp.add_val(800); + resp.add_val(19); + resp.add_val(800); + resp.add_val(20); + resp.add_val(800); + + resp.start_section("iadungeonsoulstones"); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(9); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1); + resp.add_val(-15); + resp.add_val(18); + resp.add_val(7); + resp.add_val(40); + resp.add_val(-20); + resp.add_val(0); + resp.add_val(0); + resp.add_val(24); + resp.add_val(18); + resp.add_val(10); + resp.add_val(20); + resp.add_val(31); + resp.add_val(1); + resp.add_val(0); + + resp.start_section("iadungeontime"); + resp.add_val(3); + resp.add_val(1774630800); + resp.add_val(1775505600); + resp.add_val(1775592000); + + resp.start_section("iadungeon"); + resp.add_val(299715687); + resp.add_val(2); + resp.add_val(4074729); + resp.add_val(4074729); + resp.add_val(24939872); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(12); + resp.add_val(0); + resp.add_val(25); + resp.add_val(100); + resp.add_val(4); + resp.add_val(900); + resp.add_val(904); + resp.add_val(-5236); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + + resp.start_section("iadungeon20cost"); + resp.add_val(10); + + resp.start_section("iadungeonstats"); + resp.add_val(0); + resp.add_val(1); + resp.add_val(5); + resp.add_val(1463932930); + resp.add_val(1); + + resp.start_section("iadungeonstatstotal"); + resp.add_val(0); + resp.add_val(0); + resp.add_val(6); + resp.add_val(1); + resp.add_val(1463932930); + resp.add_val(0); + + resp.start_section("adventure"); + resp.add_val(198); + resp.add_val(198); + resp.add_val(360); + resp.add_val(4); + resp.add_val(-134); + resp.add_val(15); + resp.add_val(210); + resp.add_val(943848); + resp.add_val(43042200); + resp.add_val(360); + resp.add_val(1); + resp.add_val(-29); + resp.add_val(10); + resp.add_val(210); + resp.add_val(937611); + resp.add_val(69372600); + resp.add_val(360); + resp.add_val(2); + resp.add_val(-4); + resp.add_val(21); + resp.add_val(420); + resp.add_val(1773353); + resp.add_val(134964000); + + resp.start_section("ownplayersavecharacter"); + resp.add_val(1165808075); + resp.add_val(session.player_id); + resp.add_val(0); + resp.add_val(char.level); + resp.add_val(char.experience); + resp.add_val(xp_for_next_level(level)); + resp.add_val(honor); + resp.add_val(rank); + resp.add_val(char.mouth); // mouth + resp.add_val(char.hair); // hair + resp.add_val(char.brows); // brows + resp.add_val(char.eyes); // eyes + resp.add_val(char.beards); // beards + resp.add_val(char.nose); // nose + resp.add_val(char.ears); // ears + resp.add_val(char.extra); // extra + resp.add_val(char.horns); // horns + resp.add_val(char.influencer); // influencer + resp.add_val(char.race); // race + resp.add_val(char.gender); // Gender & Mirror + resp.add_val(char.class); // class + resp.add_val(char.mount); + resp.add_val(0); // ??? + resp.add_val(10531); // armor + resp.add_val(705); // min dmg + resp.add_val(1625); // max dmg + resp.add_val(25); // portal damage_bonus + resp.add_val(5507416); // ???? + resp.add_val(33); // hp bonus + resp.add_val(char.mount_end); + + for _ in AttributeType::iter() { + resp.add_val(10000); + } + // attribute_additions (aggregate from equipment) + for _ in AttributeType::iter() { + resp.add_val(0); + } + // attribute_times_bought + for _ in AttributeType::iter() { + resp.add_val(0); + } + resp.add_val(0); + resp.add_val(1); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1); + resp.add_val(38); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(26); + resp.add_val(7); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); // guild id + resp.add_val(12138); // scrapbook count + resp.add_val(1); + resp.add_val(31); + resp.add_val(15); // gladiators + + resp.start_section("characterstatus"); + resp.add_val(1); + + resp.add_val(0); // Current action + resp.add_val(0); // Secondary (time busy) + resp.add_val(char.busy_until); // Busy until + resp.add_val(0); // Busy since? + + resp.add_val(11); // total beer + resp.add_val(char.tfa); // alu + resp.add_val(0); // beer drunk + resp.add_val(1); // calendar collected + resp.add_val(1774828801); // calendar next + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1); + resp.add_val(0); + resp.add_val(2463); // ??? + resp.add_val(1386953147); // acc creation time? + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1597743456); // next free pet exp + resp.add_val(1774762235); // next dungeon fight + resp.add_val(0); + resp.add_val(1); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + + resp.start_section("vipstatus"); + resp.add_val(0); + + resp.start_section("ownplayersavepotions"); + resp.add_val(470832); + resp.add_val(4); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1775017827); + resp.add_val(0); + resp.add_val(0); + resp.add_val(10); + resp.add_val(0); + resp.add_val(0); + + resp.start_section("arena"); + resp.add_val(1774760391); + resp.add_val(0); + resp.add_val(346900); + resp.add_val(24475); + resp.add_val(303528); + resp.add_val(1); + + resp.start_section("dice"); + resp.add_val(1774762130); + resp.add_val(18); + + resp.start_section("wheel"); + resp.add_val(2); + resp.add_val(10); + resp.add_val(1774828801); + + resp.start_section("fortress"); + resp.add_val(19); + resp.add_val(15); + resp.add_val(18); + resp.add_val(18); + resp.add_val(17); + resp.add_val(18); + resp.add_val(15); + resp.add_val(15); + resp.add_val(15); + resp.add_val(17); + resp.add_val(18); + resp.add_val(17); + resp.add_val(10); + resp.add_val(1775478676); + resp.add_val(1774758676); + resp.add_val(373); + resp.add_val(7005); + resp.add_val(1568); + resp.add_val(1774759003); + resp.add_val(535684); + resp.add_val(1459278099); + resp.add_val(1774783551); + resp.add_val(13); + resp.add_val(1771874051); + resp.add_val(1771848851); + resp.add_val(18); + resp.add_val(535684); + + resp.start_section("fortressunits"); + resp.add_val(13); + resp.add_val(0); + resp.add_val(0); + resp.add_val(32); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1774760996); + resp.add_val(1771054177); + resp.add_val(1771054177); + resp.add_val(1774761241); + resp.add_val(0); + resp.add_val(0); + resp.add_val(18); + resp.add_val(18); + resp.add_val(18); + + resp.start_section("fortressGroupPrice"); + resp.add_val(0); + resp.add_val(0); + resp.add_val(132000000); + resp.add_val(43200000); + + resp.start_section("fortressstorage"); + resp.add_val(2563619); + resp.add_val(854534); + resp.add_val(4756824); + resp.add_val(4050000); + resp.add_val(1350000); + resp.add_val(4756824); + resp.add_val(165000000); + resp.add_val(54000000); + resp.add_val(150000); + resp.add_val(50000); + resp.add_val(440445); + resp.add_val(1774758678); + resp.add_val(300000000); + resp.add_val(100000000); + resp.add_val(49500000); + resp.add_val(16200000); + + resp.start_section("fortresschances"); + resp.add_val(10000); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1700); + resp.add_val(8300); + + resp.start_section("fortresspricereroll"); + resp.add_val(35705681); + + resp.start_section("fortressprice"); + resp.add_val(1296000); + resp.add_val(20000); + resp.add_val(165000000); + resp.add_val(54000000); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1209600); + resp.add_val(3800); + resp.add_val(22500000); + resp.add_val(15000000); + resp.add_val(1209600); + resp.add_val(5700); + resp.add_val(67500000); + resp.add_val(12000000); + resp.add_val(1123200); + resp.add_val(27000); + resp.add_val(50000000); + resp.add_val(17500000); + resp.add_val(1209600); + resp.add_val(13300); + resp.add_val(18000000); + resp.add_val(24000000); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(720000); + resp.add_val(37500); + resp.add_val(5760000); + resp.add_val(1872000); + resp.add_val(1209600); + resp.add_val(7600); + resp.add_val(45000000); + resp.add_val(15000000); + resp.add_val(1123200); + resp.add_val(270000); + resp.add_val(30000000); + resp.add_val(14000000); + resp.add_val(25200); + resp.add_val(255000); + resp.add_val(1367500); + resp.add_val(450000); + + resp.start_section("deedsandtitlesplayersave"); + resp.add_val(470832); + resp.add_val(320); + resp.add_val(3254); + resp.add_val(16); + resp.add_val(6); + resp.add_val(1); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(1); + resp.add_val(94); + resp.add_val(0); + resp.add_val(118); + resp.add_val(0); + resp.add_val(119); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + resp.add_val(0); + tx.commit().await?; resp.build() From 97c395a842655020865d1e303304fcc097d58c98 Mon Sep 17 00:00:00 2001 From: Marenga Date: Sun, 29 Mar 2026 06:48:26 +0200 Subject: [PATCH 14/14] More --- src/command/update.rs | 972 +++++++++++++++++++++--------------------- 1 file changed, 486 insertions(+), 486 deletions(-) diff --git a/src/command/update.rs b/src/command/update.rs index 50f9b93..c20ab82 100644 --- a/src/command/update.rs +++ b/src/command/update.rs @@ -490,495 +490,495 @@ pub(crate) async fn poll( resp.start_section("inboxcapacity"); resp.add_val(100); - resp.start_section("ownplayersave.playerSave"); - resp.add_val(403127023); // What is this? - resp.add_val(session.player_id); - resp.add_val(0); - resp.add_val(1708336503); - resp.add_val(1292388336); - resp.add_val(0); - resp.add_val(0); - let level = char.level; - resp.add_val(level); // Level | Arena << 16 - resp.add_val(char.experience); // Experience - resp.add_val(xp_for_next_level(level)); // Next Level XP - let honor = char.honor; - resp.add_val(honor); // Honor - let rank = char.rank; - resp.add_val(rank); // Rank - - resp.add_val(0); // 12? - resp.add_val(10); // 13? - resp.add_val(0); // 14? - resp.add_val(char.mushrooms); // Mushroms gained - resp.add_val(0); // 16? - - // Portrait start - resp.add_val(char.mouth); // mouth - resp.add_val(char.hair); // hair - resp.add_val(char.brows); // brows - resp.add_val(char.eyes); // eyes - resp.add_val(char.beards); // beards - resp.add_val(char.nose); // nose - resp.add_val(char.ears); // ears - resp.add_val(char.extra); // extra - resp.add_val(char.horns); // horns - resp.add_val(char.influencer); // influencer - resp.add_val(char.race); // race - resp.add_val(char.gender); // Gender & Mirror - resp.add_val(char.class); // class - - // Attributes - for _ in AttributeType::iter() { - resp.add_val(10000); // 30..=34 - } - - // attribute_additions (aggregate from equipment) - for _ in AttributeType::iter() { - resp.add_val(0); // 35..=38 - } - - // attribute_times_bought - for _ in AttributeType::iter() { - resp.add_val(0); // 40..=44 - } - - resp.add_val(0); // Current action - resp.add_val(0); // Secondary (time busy) - resp.add_val(char.busy_until); // Busy until - - // Equipment - for slot in [ - EquipmentSlot::Hat, - EquipmentSlot::BreastPlate, - EquipmentSlot::Gloves, - EquipmentSlot::FootWear, - EquipmentSlot::Amulet, - EquipmentSlot::Belt, - EquipmentSlot::Ring, - EquipmentSlot::Talisman, - EquipmentSlot::Weapon, - EquipmentSlot::Shield, - ] { - add_debug_item(resp, format!("{slot:?}").to_lowercase()); - } - add_debug_item(resp, "inventory1"); - add_debug_item(resp, "inventory2"); - add_debug_item(resp, "inventory3"); - add_debug_item(resp, "inventory4"); - add_debug_item(resp, "inventory5"); - - resp.add_val(in_seconds(60 * 60)); // 228 - - // Ok, so Flavour 1, Flavour 2 & Monster ID decide => - // - The Line they say - // - the quest name - // - the quest giver - resp.add_val(char.q1f1); // 229 Quest1 Flavour1 - resp.add_val(char.q2f1); // 230 Quest2 Flavour1 - resp.add_val(char.q3f1); // 231 Quest3 Flavour1 - - resp.add_val(char.q1f2); // 233 Quest2 Flavour2 - resp.add_val(char.q2f2); // 232 Quest1 Flavour2 - resp.add_val(char.q3f2); // 234 Quest3 Flavour2 - - resp.add_val(-char.q1monster); // 235 quest 1 monster - resp.add_val(-char.q2monster); // 236 quest 2 monster - resp.add_val(-char.q3monster); // 237 quest 3 monster - - resp.add_val(char.q1location); // 238 quest 1 location - resp.add_val(char.q2location); // 239 quest 2 location - resp.add_val(char.q3location); // 240 quest 3 location - - let mut mount_end = char.mount_end; - let mut mount = char.mount; + // resp.start_section("ownplayersave.playerSave"); + // resp.add_val(403127023); // What is this? + // resp.add_val(session.player_id); + // resp.add_val(0); + // resp.add_val(1708336503); + // resp.add_val(1292388336); + // resp.add_val(0); + // resp.add_val(0); + // let level = char.level; + // resp.add_val(level); // Level | Arena << 16 + // resp.add_val(char.experience); // Experience + // resp.add_val(xp_for_next_level(level)); // Next Level XP + // let honor = char.honor; + // resp.add_val(honor); // Honor + // let rank = char.rank; + // resp.add_val(rank); // Rank + + // resp.add_val(0); // 12? + // resp.add_val(10); // 13? + // resp.add_val(0); // 14? + // resp.add_val(char.mushrooms); // Mushroms gained + // resp.add_val(0); // 16? + + // // Portrait start + // resp.add_val(char.mouth); // mouth + // resp.add_val(char.hair); // hair + // resp.add_val(char.brows); // brows + // resp.add_val(char.eyes); // eyes + // resp.add_val(char.beards); // beards + // resp.add_val(char.nose); // nose + // resp.add_val(char.ears); // ears + // resp.add_val(char.extra); // extra + // resp.add_val(char.horns); // horns + // resp.add_val(char.influencer); // influencer + // resp.add_val(char.race); // race + // resp.add_val(char.gender); // Gender & Mirror + // resp.add_val(char.class); // class + + // // Attributes + // for _ in AttributeType::iter() { + // resp.add_val(10000); // 30..=34 + // } - let mount_effect = effective_mount(&mut mount_end, &mut mount); + // // attribute_additions (aggregate from equipment) + // for _ in AttributeType::iter() { + // resp.add_val(0); // 35..=38 + // } - resp.add_val((char.q1length as f32 * mount_effect) as i32); // 241 quest 1 length - resp.add_val((char.q2length as f32 * mount_effect) as i32); // 242 quest 2 length - resp.add_val((char.q3length as f32 * mount_effect) as i32); // 243 quest 3 length + // // attribute_times_bought + // for _ in AttributeType::iter() { + // resp.add_val(0); // 40..=44 + // } - // Quest 1..=3 items - for _ in 0..3 { - for _ in 0..12 { - resp.add_val(0); // 244..=279 - } - } + // resp.add_val(0); // Current action + // resp.add_val(0); // Secondary (time busy) + // resp.add_val(char.busy_until); // Busy until + + // // Equipment + // for slot in [ + // EquipmentSlot::Hat, + // EquipmentSlot::BreastPlate, + // EquipmentSlot::Gloves, + // EquipmentSlot::FootWear, + // EquipmentSlot::Amulet, + // EquipmentSlot::Belt, + // EquipmentSlot::Ring, + // EquipmentSlot::Talisman, + // EquipmentSlot::Weapon, + // EquipmentSlot::Shield, + // ] { + // add_debug_item(resp, format!("{slot:?}").to_lowercase()); + // } + // add_debug_item(resp, "inventory1"); + // add_debug_item(resp, "inventory2"); + // add_debug_item(resp, "inventory3"); + // add_debug_item(resp, "inventory4"); + // add_debug_item(resp, "inventory5"); + + // resp.add_val(in_seconds(60 * 60)); // 228 + + // // Ok, so Flavour 1, Flavour 2 & Monster ID decide => + // // - The Line they say + // // - the quest name + // // - the quest giver + // resp.add_val(char.q1f1); // 229 Quest1 Flavour1 + // resp.add_val(char.q2f1); // 230 Quest2 Flavour1 + // resp.add_val(char.q3f1); // 231 Quest3 Flavour1 + + // resp.add_val(char.q1f2); // 233 Quest2 Flavour2 + // resp.add_val(char.q2f2); // 232 Quest1 Flavour2 + // resp.add_val(char.q3f2); // 234 Quest3 Flavour2 + + // resp.add_val(-char.q1monster); // 235 quest 1 monster + // resp.add_val(-char.q2monster); // 236 quest 2 monster + // resp.add_val(-char.q3monster); // 237 quest 3 monster + + // resp.add_val(char.q1location); // 238 quest 1 location + // resp.add_val(char.q2location); // 239 quest 2 location + // resp.add_val(char.q3location); // 240 quest 3 location + + // let mut mount_end = char.mount_end; + // let mut mount = char.mount; + + // let mount_effect = effective_mount(&mut mount_end, &mut mount); + + // resp.add_val((char.q1length as f32 * mount_effect) as i32); // 241 quest 1 length + // resp.add_val((char.q2length as f32 * mount_effect) as i32); // 242 quest 2 length + // resp.add_val((char.q3length as f32 * mount_effect) as i32); // 243 quest 3 length + + // // Quest 1..=3 items + // for _ in 0..3 { + // for _ in 0..12 { + // resp.add_val(0); // 244..=279 + // } + // } - resp.add_val(char.q1xp); // 280 quest 1 xp - resp.add_val(char.q2xp); // 281 quest 2 xp - resp.add_val(char.q3xp); // 282 quest 3 xp + // resp.add_val(char.q1xp); // 280 quest 1 xp + // resp.add_val(char.q2xp); // 281 quest 2 xp + // resp.add_val(char.q3xp); // 282 quest 3 xp - resp.add_val(char.q1silver); // 283 quest 1 silver - resp.add_val(char.q2silver); // 284 quest 2 silver - resp.add_val(char.q3silver); // 285 quest 3 silver + // resp.add_val(char.q1silver); // 283 quest 1 silver + // resp.add_val(char.q2silver); // 284 quest 2 silver + // resp.add_val(char.q3silver); // 285 quest 3 silver - resp.add_val(mount); // Mount? + // resp.add_val(mount); // Mount? - // Weapon shop - resp.add_val(1708336503); // 287 - for _ in 0..6 { - add_debug_item(resp, "weapon"); - } + // // Weapon shop + // resp.add_val(1708336503); // 287 + // for _ in 0..6 { + // add_debug_item(resp, "weapon"); + // } - // Magic shop - resp.add_val(1708336503); // 360 - for _ in 0..6 { - add_debug_item(resp, "weapon"); - } + // // Magic shop + // resp.add_val(1708336503); // 360 + // for _ in 0..6 { + // add_debug_item(resp, "weapon"); + // } - resp.add_val(0); // 433 - resp.add_val(1); // 434 might be tutorial related? - resp.add_val(0); // 435 - resp.add_val(0); // 436 - resp.add_val(0); // 437 - - resp.add_val(0); // 438 scrapbook count - resp.add_val(0); // 439 - resp.add_val(0); // 440 - resp.add_val(0); // 441 - resp.add_val(0); // 442 - - resp.add_val(0); // 443 guild join date - resp.add_val(0); // 444 - resp.add_val(0); // 445 character_hp_bonus << 24, damage_bonus << 16 - resp.add_val(0); // 446 - resp.add_val(0); // 447 Armor - resp.add_val(6); // 448 Min damage - resp.add_val(12); // 449 Max damage - resp.add_val(112); // 450 - resp.add_val(mount_end); // 451 Mount end - resp.add_val(0); // 452 - resp.add_val(0); // 453 - resp.add_val(0); // 454 - resp.add_val(1708336503); // 455 - resp.add_val(char.tfa); // 456 Alu secs - resp.add_val(char.beer_drunk); // 457 Beer drunk - resp.add_val(0); // 458 - resp.add_val(0); // 459 dungeon_timer - resp.add_val(1708336503); // 460 Next free fight - resp.add_val(0); // 461 - resp.add_val(0); // 462 - resp.add_val(0); // 463 - resp.add_val(0); // 464 - resp.add_val(408); // 465 - resp.add_val(0); // 466 - resp.add_val(0); // 467 - resp.add_val(0); // 468 - resp.add_val(0); // 469 - resp.add_val(0); // 470 - resp.add_val(0); // 471 - resp.add_val(0); // 472 - resp.add_val(0); // 473 - resp.add_val(-111); // 474 - resp.add_val(0); // 475 - resp.add_val(0); // 476 - resp.add_val(4); // 477 - resp.add_val(1708336504); // 478 - resp.add_val(0); // 479 - resp.add_val(0); // 480 - resp.add_val(0); // 481 - resp.add_val(0); // 482 - resp.add_val(0); // 483 - resp.add_val(0); // 484 - resp.add_val(0); // 485 - resp.add_val(0); // 486 - resp.add_val(0); // 487 - resp.add_val(0); // 488 - resp.add_val(0); // 489 - resp.add_val(0); // 490 - - resp.add_val(500); // 491 aura_level (0 == locked) - resp.add_val(100); // 492 aura_now - - // Active potions - for _ in 0..3 { - resp.add_val(0); // typ & size - } - for _ in 0..3 { - resp.add_val(0); // ?? - } - for _ in 0..3 { - resp.add_val(0); // expires - } - resp.add_val(0); // 502 - resp.add_val(0); // 503 - resp.add_val(0); // 504 - resp.add_val(0); // 505 - resp.add_val(0); // 506 - resp.add_val(0); // 507 - resp.add_val(0); // 508 - resp.add_val(0); // 509 - resp.add_val(0); // 510 - resp.add_val(6); // 511 - resp.add_val(2); // 512 - resp.add_val(0); // 513 - resp.add_val(0); // 514 - resp.add_val(100); // 515 aura_missing - resp.add_val(0); // 516 - resp.add_val(0); // 517 - resp.add_val(0); // 518 - resp.add_val(100); // 519 - resp.add_val(0); // 520 - resp.add_val(0); // 521 - resp.add_val(0); // 522 - resp.add_val(0); // 523 - - // Fortress - // Building levels - resp.add_val(0); // 524 - resp.add_val(0); // 525 - resp.add_val(0); // 526 - resp.add_val(0); // 527 - resp.add_val(0); // 528 - resp.add_val(0); // 529 - resp.add_val(0); // 530 - resp.add_val(0); // 531 - resp.add_val(0); // 532 - resp.add_val(0); // 533 - resp.add_val(0); // 534 - resp.add_val(0); // 535 - resp.add_val(0); // 536 - resp.add_val(0); // 537 - resp.add_val(0); // 538 - resp.add_val(0); // 539 - resp.add_val(0); // 540 - resp.add_val(0); // 541 - resp.add_val(0); // 542 - resp.add_val(0); // 543 - resp.add_val(0); // 544 - resp.add_val(0); // 545 - resp.add_val(0); // 546 - // unit counts - resp.add_val(0); // 547 - resp.add_val(0); // 548 - resp.add_val(0); // 549 - // upgrade_began - resp.add_val(0); // 550 - resp.add_val(0); // 551 - resp.add_val(0); // 552 - // upgrade_finish - resp.add_val(0); // 553 - resp.add_val(0); // 554 - resp.add_val(0); // 555 - - resp.add_val(0); // 556 - resp.add_val(0); // 557 - resp.add_val(0); // 558 - resp.add_val(0); // 559 - resp.add_val(0); // 560 - resp.add_val(0); // 561 - - // Current resource in store - resp.add_val(0); // 562 - resp.add_val(0); // 563 - resp.add_val(0); // 564 - // max_in_building - resp.add_val(0); // 565 - resp.add_val(0); // 566 - resp.add_val(0); // 567 - // max saved - resp.add_val(0); // 568 - resp.add_val(0); // 569 - resp.add_val(0); // 570 - - resp.add_val(0); // 571 building_upgraded - resp.add_val(0); // 572 building_upgrade_finish - resp.add_val(0); // 573 building_upgrade_began - // per hour - resp.add_val(0); // 574 - resp.add_val(0); // 575 - resp.add_val(0); // 576 - resp.add_val(0); // 577 unknown time stamp - resp.add_val(0); // 578 - - resp.add_val(0); // 579 wheel_spins_today - resp.add_val(now() + 60 * 10); // 580 wheel_next_free_spin - - resp.add_val(0); // 581 ft level - resp.add_val(100); // 582 ft honor - resp.add_val(0); // 583 rank - resp.add_val(900); // 584 - resp.add_val(300); // 585 - resp.add_val(0); // 586 - - resp.add_val(0); // 587 attack target - resp.add_val(0); // 588 attack_free_reroll - resp.add_val(0); // 589 - resp.add_val(0); // 590 - resp.add_val(0); // 591 - resp.add_val(0); // 592 - resp.add_val(3); // 593 - - resp.add_val(0); // 594 gem_stone_target - resp.add_val(0); // 595 gem_search_finish - resp.add_val(0); // 596 gem_search_began - resp.add_val(char.tutorial_status); // 597 Pretty sure this is a bit map of which messages have been seen - resp.add_val(0); // 598 - - // Arena enemies - resp.add_val(get_debug_value_default("arena_enemy1", 1)); // 599 - resp.add_val(get_debug_value_default("arena_enemy2", 1)); // 600 - resp.add_val(get_debug_value_default("arena_enemy3", 1)); // 601 - - resp.add_val(0); // 602 - resp.add_val(0); // 603 - resp.add_val(0); // 604 - resp.add_val(0); // 605 - resp.add_val(0); // 606 - resp.add_val(0); // 607 - resp.add_val(0); // 608 - resp.add_val(0); // 609 - resp.add_val(1708336504); // 610 - resp.add_val(0); // 611 - resp.add_val(0); // 612 - resp.add_val(0); // 613 - resp.add_val(0); // 614 - resp.add_val(0); // 615 - resp.add_val(0); // 616 - resp.add_val(1); // 617 - resp.add_val(0); // 618 - resp.add_val(0); // 619 - resp.add_val(0); // 620 - resp.add_val(0); // 621 - resp.add_val(0); // 622 - resp.add_val(0); // 623 own_treasure_skill - resp.add_val(0); // 624 own_instr_skill - resp.add_val(0); // 625 - resp.add_val(30); // 626 - resp.add_val(0); // 627 hydra_next_battle - resp.add_val(0); // 628 remaining_pet_battles - resp.add_val(0); // 629 - resp.add_val(0); // 630 - resp.add_val(0); // 631 - resp.add_val(0); // 632 - resp.add_val(0); // 633 - resp.add_val(0); // 634 - resp.add_val(0); // 635 - resp.add_val(0); // 636 - resp.add_val(0); // 637 - resp.add_val(0); // 638 - resp.add_val(0); // 639 - resp.add_val(0); // 640 - resp.add_val(0); // 641 - resp.add_val(0); // 642 - resp.add_val(0); // 643 - resp.add_val(0); // 644 - resp.add_val(0); // 645 - resp.add_val(0); // 646 - resp.add_val(0); // 647 - resp.add_val(0); // 648 - resp.add_val(in_seconds(60 * 60)); // 649 calendar_next_possible - resp.add_val(char.dice_game_next_free); // 650 dice_games_next_free - resp.add_val(char.dice_games_remaining); // 651 dice_games_remaining - resp.add_val(0); // 652 - resp.add_val(0); // 653 druid mask - resp.add_val(0); // 654 - resp.add_val(0); // 655 - resp.add_val(0); // 656 - resp.add_val(6); // 657 - resp.add_val(0); // 658 - resp.add_val(2); // 659 - resp.add_val(0); // 660 pet dungeon timer - resp.add_val(0); // 661 - resp.add_val(0); // 662 - resp.add_val(0); // 663 - resp.add_val(0); // 664 - resp.add_val(0); // 665 - resp.add_val(0); // 666 - resp.add_val(0); // 667 - resp.add_val(0); // 668 - resp.add_val(0); // 669 - resp.add_val(0); // 670 - resp.add_val(1950020000000i64); // 671 - resp.add_val(0); // 672 - resp.add_val(0); // 673 - resp.add_val(0); // 674 - resp.add_val(0); // 675 - resp.add_val(0); // 676 - resp.add_val(0); // 677 - resp.add_val(0); // 678 - resp.add_val(0); // 679 - resp.add_val(0); // 680 - resp.add_val(0); // 681 - resp.add_val(0); // 682 - resp.add_val(0); // 683 - resp.add_val(0); // 684 - resp.add_val(0); // 685 - resp.add_val(0); // 686 - resp.add_val(0); // 687 - resp.add_val(0); // 688 - resp.add_val(0); // 689 - resp.add_val(0); // 690 - resp.add_val(0); // 691 - resp.add_val(1); // 692 - resp.add_val(0); // 693 - resp.add_val(0); // 694 - resp.add_val(0); // 695 - resp.add_val(0); // 696 - resp.add_val(0); // 697 - resp.add_val(0); // 698 - resp.add_val(0); // 699 - resp.add_val(0); // 700 - resp.add_val(0); // 701 bard instrument - resp.add_val(0); // 702 - resp.add_val(0); // 703 - resp.add_val(1); // 704 - resp.add_val(0); // 705 - resp.add_val(0); // 706 - resp.add_val(0); // 707 - resp.add_val(0); // 708 - resp.add_val(0); // 709 - resp.add_val(0); // 710 - resp.add_val(0); // 711 - resp.add_val(0); // 712 - resp.add_val(0); // 713 - resp.add_val(0); // 714 - resp.add_val(0); // 715 - resp.add_val(0); // 716 - resp.add_val(0); // 717 - resp.add_val(0); // 718 - resp.add_val(0); // 719 - resp.add_val(0); // 720 - resp.add_val(0); // 721 - resp.add_val(0); // 722 - resp.add_val(0); // 723 - resp.add_val(0); // 724 - resp.add_val(0); // 725 - resp.add_val(0); // 726 - resp.add_val(0); // 727 - resp.add_val(0); // 728 - resp.add_val(0); // 729 - resp.add_val(0); // 730 - resp.add_val(0); // 731 - resp.add_val(0); // 732 - resp.add_val(0); // 733 - resp.add_val(0); // 734 - resp.add_val(0); // 735 - resp.add_val(0); // 736 - resp.add_val(0); // 737 - resp.add_val(0); // 738 - resp.add_val(0); // 739 - resp.add_val(0); // 740 - resp.add_val(0); // 741 - resp.add_val(0); // 742 - resp.add_val(0); // 743 - resp.add_val(0); // 744 - resp.add_val(0); // 745 - resp.add_val(0); // 746 - resp.add_val(0); // 747 - resp.add_val(0); // 748 - resp.add_val(0); // 749 - resp.add_val(0); // 750 - resp.add_val(0); // 751 - resp.add_val(0); // 752 - resp.add_val(0); // 753 - resp.add_val(0); // 754 - resp.add_val(0); // 755 - resp.add_val(0); // 756 - resp.add_val(0); // 757 - resp.add_str(""); // 758 + // resp.add_val(0); // 433 + // resp.add_val(1); // 434 might be tutorial related? + // resp.add_val(0); // 435 + // resp.add_val(0); // 436 + // resp.add_val(0); // 437 + + // resp.add_val(0); // 438 scrapbook count + // resp.add_val(0); // 439 + // resp.add_val(0); // 440 + // resp.add_val(0); // 441 + // resp.add_val(0); // 442 + + // resp.add_val(0); // 443 guild join date + // resp.add_val(0); // 444 + // resp.add_val(0); // 445 character_hp_bonus << 24, damage_bonus << 16 + // resp.add_val(0); // 446 + // resp.add_val(0); // 447 Armor + // resp.add_val(6); // 448 Min damage + // resp.add_val(12); // 449 Max damage + // resp.add_val(112); // 450 + // resp.add_val(mount_end); // 451 Mount end + // resp.add_val(0); // 452 + // resp.add_val(0); // 453 + // resp.add_val(0); // 454 + // resp.add_val(1708336503); // 455 + // resp.add_val(char.tfa); // 456 Alu secs + // resp.add_val(char.beer_drunk); // 457 Beer drunk + // resp.add_val(0); // 458 + // resp.add_val(0); // 459 dungeon_timer + // resp.add_val(1708336503); // 460 Next free fight + // resp.add_val(0); // 461 + // resp.add_val(0); // 462 + // resp.add_val(0); // 463 + // resp.add_val(0); // 464 + // resp.add_val(408); // 465 + // resp.add_val(0); // 466 + // resp.add_val(0); // 467 + // resp.add_val(0); // 468 + // resp.add_val(0); // 469 + // resp.add_val(0); // 470 + // resp.add_val(0); // 471 + // resp.add_val(0); // 472 + // resp.add_val(0); // 473 + // resp.add_val(-111); // 474 + // resp.add_val(0); // 475 + // resp.add_val(0); // 476 + // resp.add_val(4); // 477 + // resp.add_val(1708336504); // 478 + // resp.add_val(0); // 479 + // resp.add_val(0); // 480 + // resp.add_val(0); // 481 + // resp.add_val(0); // 482 + // resp.add_val(0); // 483 + // resp.add_val(0); // 484 + // resp.add_val(0); // 485 + // resp.add_val(0); // 486 + // resp.add_val(0); // 487 + // resp.add_val(0); // 488 + // resp.add_val(0); // 489 + // resp.add_val(0); // 490 + + // resp.add_val(500); // 491 aura_level (0 == locked) + // resp.add_val(100); // 492 aura_now + + // // Active potions + // for _ in 0..3 { + // resp.add_val(0); // typ & size + // } + // for _ in 0..3 { + // resp.add_val(0); // ?? + // } + // for _ in 0..3 { + // resp.add_val(0); // expires + // } + // resp.add_val(0); // 502 + // resp.add_val(0); // 503 + // resp.add_val(0); // 504 + // resp.add_val(0); // 505 + // resp.add_val(0); // 506 + // resp.add_val(0); // 507 + // resp.add_val(0); // 508 + // resp.add_val(0); // 509 + // resp.add_val(0); // 510 + // resp.add_val(6); // 511 + // resp.add_val(2); // 512 + // resp.add_val(0); // 513 + // resp.add_val(0); // 514 + // resp.add_val(100); // 515 aura_missing + // resp.add_val(0); // 516 + // resp.add_val(0); // 517 + // resp.add_val(0); // 518 + // resp.add_val(100); // 519 + // resp.add_val(0); // 520 + // resp.add_val(0); // 521 + // resp.add_val(0); // 522 + // resp.add_val(0); // 523 + + // // Fortress + // // Building levels + // resp.add_val(0); // 524 + // resp.add_val(0); // 525 + // resp.add_val(0); // 526 + // resp.add_val(0); // 527 + // resp.add_val(0); // 528 + // resp.add_val(0); // 529 + // resp.add_val(0); // 530 + // resp.add_val(0); // 531 + // resp.add_val(0); // 532 + // resp.add_val(0); // 533 + // resp.add_val(0); // 534 + // resp.add_val(0); // 535 + // resp.add_val(0); // 536 + // resp.add_val(0); // 537 + // resp.add_val(0); // 538 + // resp.add_val(0); // 539 + // resp.add_val(0); // 540 + // resp.add_val(0); // 541 + // resp.add_val(0); // 542 + // resp.add_val(0); // 543 + // resp.add_val(0); // 544 + // resp.add_val(0); // 545 + // resp.add_val(0); // 546 + // // unit counts + // resp.add_val(0); // 547 + // resp.add_val(0); // 548 + // resp.add_val(0); // 549 + // // upgrade_began + // resp.add_val(0); // 550 + // resp.add_val(0); // 551 + // resp.add_val(0); // 552 + // // upgrade_finish + // resp.add_val(0); // 553 + // resp.add_val(0); // 554 + // resp.add_val(0); // 555 + + // resp.add_val(0); // 556 + // resp.add_val(0); // 557 + // resp.add_val(0); // 558 + // resp.add_val(0); // 559 + // resp.add_val(0); // 560 + // resp.add_val(0); // 561 + + // // Current resource in store + // resp.add_val(0); // 562 + // resp.add_val(0); // 563 + // resp.add_val(0); // 564 + // // max_in_building + // resp.add_val(0); // 565 + // resp.add_val(0); // 566 + // resp.add_val(0); // 567 + // // max saved + // resp.add_val(0); // 568 + // resp.add_val(0); // 569 + // resp.add_val(0); // 570 + + // resp.add_val(0); // 571 building_upgraded + // resp.add_val(0); // 572 building_upgrade_finish + // resp.add_val(0); // 573 building_upgrade_began + // // per hour + // resp.add_val(0); // 574 + // resp.add_val(0); // 575 + // resp.add_val(0); // 576 + // resp.add_val(0); // 577 unknown time stamp + // resp.add_val(0); // 578 + + // resp.add_val(0); // 579 wheel_spins_today + // resp.add_val(now() + 60 * 10); // 580 wheel_next_free_spin + + // resp.add_val(0); // 581 ft level + // resp.add_val(100); // 582 ft honor + // resp.add_val(0); // 583 rank + // resp.add_val(900); // 584 + // resp.add_val(300); // 585 + // resp.add_val(0); // 586 + + // resp.add_val(0); // 587 attack target + // resp.add_val(0); // 588 attack_free_reroll + // resp.add_val(0); // 589 + // resp.add_val(0); // 590 + // resp.add_val(0); // 591 + // resp.add_val(0); // 592 + // resp.add_val(3); // 593 + + // resp.add_val(0); // 594 gem_stone_target + // resp.add_val(0); // 595 gem_search_finish + // resp.add_val(0); // 596 gem_search_began + // resp.add_val(char.tutorial_status); // 597 Pretty sure this is a bit map of which messages have been seen + // resp.add_val(0); // 598 + + // // Arena enemies + // resp.add_val(get_debug_value_default("arena_enemy1", 1)); // 599 + // resp.add_val(get_debug_value_default("arena_enemy2", 1)); // 600 + // resp.add_val(get_debug_value_default("arena_enemy3", 1)); // 601 + + // resp.add_val(0); // 602 + // resp.add_val(0); // 603 + // resp.add_val(0); // 604 + // resp.add_val(0); // 605 + // resp.add_val(0); // 606 + // resp.add_val(0); // 607 + // resp.add_val(0); // 608 + // resp.add_val(0); // 609 + // resp.add_val(1708336504); // 610 + // resp.add_val(0); // 611 + // resp.add_val(0); // 612 + // resp.add_val(0); // 613 + // resp.add_val(0); // 614 + // resp.add_val(0); // 615 + // resp.add_val(0); // 616 + // resp.add_val(1); // 617 + // resp.add_val(0); // 618 + // resp.add_val(0); // 619 + // resp.add_val(0); // 620 + // resp.add_val(0); // 621 + // resp.add_val(0); // 622 + // resp.add_val(0); // 623 own_treasure_skill + // resp.add_val(0); // 624 own_instr_skill + // resp.add_val(0); // 625 + // resp.add_val(30); // 626 + // resp.add_val(0); // 627 hydra_next_battle + // resp.add_val(0); // 628 remaining_pet_battles + // resp.add_val(0); // 629 + // resp.add_val(0); // 630 + // resp.add_val(0); // 631 + // resp.add_val(0); // 632 + // resp.add_val(0); // 633 + // resp.add_val(0); // 634 + // resp.add_val(0); // 635 + // resp.add_val(0); // 636 + // resp.add_val(0); // 637 + // resp.add_val(0); // 638 + // resp.add_val(0); // 639 + // resp.add_val(0); // 640 + // resp.add_val(0); // 641 + // resp.add_val(0); // 642 + // resp.add_val(0); // 643 + // resp.add_val(0); // 644 + // resp.add_val(0); // 645 + // resp.add_val(0); // 646 + // resp.add_val(0); // 647 + // resp.add_val(0); // 648 + // resp.add_val(in_seconds(60 * 60)); // 649 calendar_next_possible + // resp.add_val(char.dice_game_next_free); // 650 dice_games_next_free + // resp.add_val(char.dice_games_remaining); // 651 dice_games_remaining + // resp.add_val(0); // 652 + // resp.add_val(0); // 653 druid mask + // resp.add_val(0); // 654 + // resp.add_val(0); // 655 + // resp.add_val(0); // 656 + // resp.add_val(6); // 657 + // resp.add_val(0); // 658 + // resp.add_val(2); // 659 + // resp.add_val(0); // 660 pet dungeon timer + // resp.add_val(0); // 661 + // resp.add_val(0); // 662 + // resp.add_val(0); // 663 + // resp.add_val(0); // 664 + // resp.add_val(0); // 665 + // resp.add_val(0); // 666 + // resp.add_val(0); // 667 + // resp.add_val(0); // 668 + // resp.add_val(0); // 669 + // resp.add_val(0); // 670 + // resp.add_val(1950020000000i64); // 671 + // resp.add_val(0); // 672 + // resp.add_val(0); // 673 + // resp.add_val(0); // 674 + // resp.add_val(0); // 675 + // resp.add_val(0); // 676 + // resp.add_val(0); // 677 + // resp.add_val(0); // 678 + // resp.add_val(0); // 679 + // resp.add_val(0); // 680 + // resp.add_val(0); // 681 + // resp.add_val(0); // 682 + // resp.add_val(0); // 683 + // resp.add_val(0); // 684 + // resp.add_val(0); // 685 + // resp.add_val(0); // 686 + // resp.add_val(0); // 687 + // resp.add_val(0); // 688 + // resp.add_val(0); // 689 + // resp.add_val(0); // 690 + // resp.add_val(0); // 691 + // resp.add_val(1); // 692 + // resp.add_val(0); // 693 + // resp.add_val(0); // 694 + // resp.add_val(0); // 695 + // resp.add_val(0); // 696 + // resp.add_val(0); // 697 + // resp.add_val(0); // 698 + // resp.add_val(0); // 699 + // resp.add_val(0); // 700 + // resp.add_val(0); // 701 bard instrument + // resp.add_val(0); // 702 + // resp.add_val(0); // 703 + // resp.add_val(1); // 704 + // resp.add_val(0); // 705 + // resp.add_val(0); // 706 + // resp.add_val(0); // 707 + // resp.add_val(0); // 708 + // resp.add_val(0); // 709 + // resp.add_val(0); // 710 + // resp.add_val(0); // 711 + // resp.add_val(0); // 712 + // resp.add_val(0); // 713 + // resp.add_val(0); // 714 + // resp.add_val(0); // 715 + // resp.add_val(0); // 716 + // resp.add_val(0); // 717 + // resp.add_val(0); // 718 + // resp.add_val(0); // 719 + // resp.add_val(0); // 720 + // resp.add_val(0); // 721 + // resp.add_val(0); // 722 + // resp.add_val(0); // 723 + // resp.add_val(0); // 724 + // resp.add_val(0); // 725 + // resp.add_val(0); // 726 + // resp.add_val(0); // 727 + // resp.add_val(0); // 728 + // resp.add_val(0); // 729 + // resp.add_val(0); // 730 + // resp.add_val(0); // 731 + // resp.add_val(0); // 732 + // resp.add_val(0); // 733 + // resp.add_val(0); // 734 + // resp.add_val(0); // 735 + // resp.add_val(0); // 736 + // resp.add_val(0); // 737 + // resp.add_val(0); // 738 + // resp.add_val(0); // 739 + // resp.add_val(0); // 740 + // resp.add_val(0); // 741 + // resp.add_val(0); // 742 + // resp.add_val(0); // 743 + // resp.add_val(0); // 744 + // resp.add_val(0); // 745 + // resp.add_val(0); // 746 + // resp.add_val(0); // 747 + // resp.add_val(0); // 748 + // resp.add_val(0); // 749 + // resp.add_val(0); // 750 + // resp.add_val(0); // 751 + // resp.add_val(0); // 752 + // resp.add_val(0); // 753 + // resp.add_val(0); // 754 + // resp.add_val(0); // 755 + // resp.add_val(0); // 756 + // resp.add_val(0); // 757 + // resp.add_str(""); // 758 resp.start_section("resources"); resp.add_val(session.player_id); // pid @@ -1466,7 +1466,7 @@ pub(crate) async fn poll( resp.start_section("events"); resp.add_val(7); - resp.add_val(147796); + resp.add_val(session.player_id); // ?? resp.add_val(1774828740); resp.add_val(2097153); resp.add_val(1775519940); @@ -1701,9 +1701,9 @@ pub(crate) async fn poll( resp.add_val(0); resp.add_val(char.level); resp.add_val(char.experience); - resp.add_val(xp_for_next_level(level)); - resp.add_val(honor); - resp.add_val(rank); + resp.add_val(xp_for_next_level(char.level)); + resp.add_val(char.honor); + resp.add_val(char.rank); resp.add_val(char.mouth); // mouth resp.add_val(char.hair); // hair resp.add_val(char.brows); // brows @@ -1803,7 +1803,7 @@ pub(crate) async fn poll( resp.add_val(0); resp.start_section("ownplayersavepotions"); - resp.add_val(470832); + resp.add_val(session.player_id); resp.add_val(4); resp.add_val(0); resp.add_val(0); @@ -1967,7 +1967,7 @@ pub(crate) async fn poll( resp.add_val(450000); resp.start_section("deedsandtitlesplayersave"); - resp.add_val(470832); + resp.add_val(session.player_id); resp.add_val(320); resp.add_val(3254); resp.add_val(16);