fix(seasons): supply the FUT web-file base so Seasons stops failing
Entering single-player Seasons showed "There was a problem communicating with the FIFA Ultimate Team Servers". The deployed trace caught the whole chain: SEASON_CALL: LoadOfflineSeasons_asyncimpl(0x57560) SEASONS_WEBFILE_URL: url="packs/loc/storepackdescriptions.en_us.xml" SEASONS_STAGE1: status(+0x1c)=999 -> CACHE_PACKNAMES_FAILED SEASONS_LOAD_CALLBACK: final kind=ERROR result="CACHE_PACKNAMES_FAILED" Not a server fault: no /season/* request is ever made. The client's RS4::ServerSettings CDN base is EMPTY in the emulator, so the pack-names web file is requested as a BARE relative path and 999s, and Seasons aborts on that prerequisite. Ports the base-supply rewriter from wip/seasons/base-supply-veh onto the deployed lineage (that branch forked before the TLS work and cannot be rebased), taking only the URL supply: absolute urls pass through untouched, and the success-forcing CACHE_PACKNAMES bypass is deliberately NOT taken — masking the failure would hide whether the supply actually worked. Corrects the port while porting: the branch hardcoded 8110, where nothing listens. The content server is POW (`pow_server.py`, kind "content") on 8085 — the port Blaze already advertises to the client as its content host. Verified live: GET http://10.10.0.120:8085/fut/packs/loc/storepackdescriptions.en_us.xml returns 200 with a 180-byte XLIFF document. `default_ports::FUT_CONTENT` is now 8085 and the base is still derived from openfut.cfg, so no address is compiled in (confirmed absent from the artifact). Artifact keeps the roster TLS gate patch (11 fifa17_tls markers) and the kit trace alongside the new base supply.
This commit is contained in:
@@ -53,6 +53,17 @@ pub mod default_ports {
|
||||
pub const BLAZE_REDIRECTOR: u16 = 42127;
|
||||
/// OpenFUT FIFA 17 Blaze main listener.
|
||||
pub const BLAZE_MAIN: u16 = 42130;
|
||||
/// OpenFUT FUT web-file (CDN) content server. Unlike the others this is not
|
||||
/// an EA redirect target: the client never dials it directly, because its
|
||||
/// `RS4::ServerSettings` CDN base arrives EMPTY in the emulator. The hook
|
||||
/// supplies the missing `<base>/fut/` prefix, and the base is built from the
|
||||
/// configured server host plus this port.
|
||||
///
|
||||
/// 8085 is the POW content server (`pow_server.py`, kind "content"), which is
|
||||
/// the port Blaze already advertises to the client as its content host and
|
||||
/// which serves `/fut/packs/loc/storepackdescriptions.en_us.xml`. Verified
|
||||
/// live: that path returns 200 with a 180-byte XLIFF document.
|
||||
pub const FUT_CONTENT: u16 = 8085;
|
||||
}
|
||||
|
||||
/// OpenFUT destination ports. Each field is where an intercepted EA source port
|
||||
@@ -66,6 +77,9 @@ pub struct OpenFutPorts {
|
||||
pub blaze_redirector: u16,
|
||||
/// Destination for EA :42127 traffic (Blaze main).
|
||||
pub blaze_main: u16,
|
||||
/// FUT web-file content server. Not a redirect destination — see
|
||||
/// [`default_ports::FUT_CONTENT`].
|
||||
pub fut_content: u16,
|
||||
}
|
||||
|
||||
impl Default for OpenFutPorts {
|
||||
@@ -74,6 +88,7 @@ impl Default for OpenFutPorts {
|
||||
https: default_ports::HTTPS,
|
||||
blaze_redirector: default_ports::BLAZE_REDIRECTOR,
|
||||
blaze_main: default_ports::BLAZE_MAIN,
|
||||
fut_content: default_ports::FUT_CONTENT,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,6 +259,7 @@ impl ServerConfig {
|
||||
"https_port" => ports.https = parse_port(value)?,
|
||||
"blaze_redirector_port" => ports.blaze_redirector = parse_port(value)?,
|
||||
"blaze_main_port" => ports.blaze_main = parse_port(value)?,
|
||||
"fut_content_port" => ports.fut_content = parse_port(value)?,
|
||||
other => {
|
||||
return Err(ConfigError::MalformedConfig(format!(
|
||||
"line {}: unknown key '{other}'",
|
||||
@@ -260,8 +276,27 @@ impl ServerConfig {
|
||||
/// Serialize to the structured `openfut.cfg` format.
|
||||
pub fn to_cfg_string(&self) -> String {
|
||||
format!(
|
||||
"host={}\nhttps_port={}\nblaze_redirector_port={}\nblaze_main_port={}\n",
|
||||
self.host, self.ports.https, self.ports.blaze_redirector, self.ports.blaze_main
|
||||
"host={}\nhttps_port={}\nblaze_redirector_port={}\nblaze_main_port={}\nfut_content_port={}\n",
|
||||
self.host,
|
||||
self.ports.https,
|
||||
self.ports.blaze_redirector,
|
||||
self.ports.blaze_main,
|
||||
self.ports.fut_content
|
||||
)
|
||||
}
|
||||
|
||||
/// Base URL the FUT web-file (CDN) prefix is built from, e.g.
|
||||
/// `http://10.10.0.120:8085/fut/`.
|
||||
///
|
||||
/// The client's `RS4::ServerSettings` CDN base arrives EMPTY in the emulator,
|
||||
/// so FUT web-file urls reach the download entry point as bare relative paths
|
||||
/// and fail. The hook supplies this prefix. Built from the SAME configured
|
||||
/// host as every other redirect, so a lab address is never compiled in.
|
||||
pub fn fut_content_base(&self) -> String {
|
||||
format!(
|
||||
"http://{}:{}/fut/",
|
||||
self.host.trim(),
|
||||
self.ports.fut_content
|
||||
)
|
||||
}
|
||||
|
||||
@@ -449,12 +484,36 @@ mod tests {
|
||||
https: 8443,
|
||||
blaze_redirector: 10041,
|
||||
blaze_main: 42127,
|
||||
fut_content: 8085,
|
||||
},
|
||||
};
|
||||
let s = c.to_cfg_string();
|
||||
assert_eq!(ServerConfig::parse(&s).unwrap(), c);
|
||||
}
|
||||
|
||||
/// The FUT web-file prefix follows the CONFIGURED server, so no lab address
|
||||
/// is ever compiled into the hook.
|
||||
#[test]
|
||||
fn fut_content_base_follows_the_configured_host() {
|
||||
let c = ServerConfig::parse("host=192.168.1.50\n").unwrap();
|
||||
assert_eq!(c.fut_content_base(), "http://192.168.1.50:8085/fut/");
|
||||
|
||||
let c = ServerConfig::parse("host=fut.mylan.home\nfut_content_port=9110\n").unwrap();
|
||||
assert_eq!(c.fut_content_base(), "http://fut.mylan.home:9110/fut/");
|
||||
}
|
||||
|
||||
/// A cfg written before `fut_content_port` existed must still parse, taking
|
||||
/// the default rather than failing the whole config (which would disarm the
|
||||
/// network redirect too).
|
||||
#[test]
|
||||
fn cfg_without_content_port_takes_the_default() {
|
||||
let c = ServerConfig::parse(
|
||||
"host=10.0.0.5\nhttps_port=8443\nblaze_redirector_port=42127\nblaze_main_port=42130\n",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(c.ports.fut_content, default_ports::FUT_CONTENT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn configured_ipv4_becomes_correct_sockaddr() {
|
||||
// Resolve an IPv4 literal and confirm the sin_addr value.
|
||||
|
||||
Reference in New Issue
Block a user