From 0e3df10fc091e004616a08376a0f17197ae78ae4 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Wed, 6 Mar 2024 12:48:18 -0800 Subject: [PATCH] print Devolution phone numbers during startup --- README.md | 11 +++++++++++ src/Main.cc | 15 ++++++++++++++- src/NetworkAddresses.cc | 14 ++++++++++++++ src/NetworkAddresses.hh | 2 ++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9be38426..33914fdf 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,17 @@ You can make PSO connect to newserv by setting its default gateway and DNS serve If you have PSO Plus or Episode III, it won't want to connect to a server on the same local network as the GameCube itself, as determined by the GameCube's IP address and subnet mask. In the old days, one way to get around this was to create a fake network adapter on the server (or use an existing real one) that has an IP address on a different subnet, tell the GameCube that the server is the default gateway (as above), and have the server reply to the DNS request with its non-local IP address. To do this with newserv, just set LocalAddress in the config file to a different interface. For example, if the GameCube is on the 192.168.0.x network and your other adapter has address 10.0.1.6, set newserv's LocalAddress to 10.0.1.6 and set PSO's DNS server and default gateway addresses to the server's 192.168.0.x address. This may not work on modern systems or on non-Windows machines - I haven't tested it in many years. +### PSO GC on a Wii or Wii U + +Using a Wii or Wii U to connect to newserv requires the Wii or vWii to be softmodded. How to do this is beyond the scope of this document. + +Nintendont includes BBA emulation and is compatible with all PSO GameCube versions except Episodes I&II Trial Edition. To use Nintendont, enable BBA emulation in Nintendont's settings and follow the instructions in the above section (PSO GC on a real GameCube). + +Devolution includes modem emulation and is compatible with all PSO GameCube versions including Episodes I&II Trial Edition. newserv can act as a PPP server, which Devolution can directly cnnect to. To do this: +1. Enable the PPPRawListen option according to the comments in config.json. +2. Start newserv. +3. In the game's network settings, set the username and password to anything (they cannot be blank), and set the phone number to the number that newserv outputs to the console during startup. (It will be near the end of all the startup log messages.) If your Wii is on the same network as newserv, use the local number; otherwise, use the external number. + ### PSO GC on Dolphin If you're using the HLE BBA type, set the BBA's DNS server address to newserv's IP address and it should work. (If newserv is on the same machine as Dolphin, you will need to use an action replay code directed at 127.0.0.1 to connect, as PSO rejects DNS queries from the same IP address.) Set PSO's network settings the same as listed below. diff --git a/src/Main.cc b/src/Main.cc index 40c1e1cb..80d5a029 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -2483,7 +2483,7 @@ Action a_run_server_replay_log( } } - if (!state->ip_stack_addresses.empty() || !state->ppp_stack_addresses.empty()) { + if (!state->ip_stack_addresses.empty() || !state->ppp_stack_addresses.empty() || !state->ppp_raw_addresses.empty()) { config_log.info("Starting IP/PPP stack simulator"); ip_stack_simulator = make_shared(base, state); for (const auto& it : state->ip_stack_addresses) { @@ -2500,6 +2500,19 @@ Action a_run_server_replay_log( auto netloc = parse_netloc(it); string spec = (netloc.second == 0) ? ("T-PPPSR-" + netloc.first) : string_printf("T-PPPSR-%hu", netloc.second); ip_stack_simulator->listen(spec, netloc.first, netloc.second, IPStackSimulator::Protocol::HDLC_RAW); + if (netloc.second) { + if (state->local_address == state->external_address) { + config_log.info( + "Note: The Devolution phone number for %s is %" PRIu64, + spec.c_str(), devolution_phone_number_for_netloc(state->local_address, netloc.second)); + } else { + config_log.info( + "Note: The Devolution phone numbers for %s are %" PRIu64 " (local) and %" PRIu64 " (external)", + spec.c_str(), + devolution_phone_number_for_netloc(state->local_address, netloc.second), + devolution_phone_number_for_netloc(state->external_address, netloc.second)); + } + } } } diff --git a/src/NetworkAddresses.cc b/src/NetworkAddresses.cc index 9f6ab13a..6554fe28 100644 --- a/src/NetworkAddresses.cc +++ b/src/NetworkAddresses.cc @@ -88,3 +88,17 @@ string string_for_address(uint32_t address) { uint32_t address_for_string(const char* address) { return ntohl(inet_addr(address)); } + +uint64_t devolution_phone_number_for_netloc(uint32_t addr, uint16_t port) { + // It seems the address part of the number is fixed-width, but the port is + // not. Why did they do it this way? + if (port & 0xF000) { + return (static_cast(addr) << 16) | port; + } else if (port & 0x0F00) { + return (static_cast(addr) << 12) | port; + } else if (port & 0x00F0) { + return (static_cast(addr) << 8) | port; + } else { + return (static_cast(addr) << 4) | port; + } +} diff --git a/src/NetworkAddresses.hh b/src/NetworkAddresses.hh index 7f894397..396daa84 100644 --- a/src/NetworkAddresses.hh +++ b/src/NetworkAddresses.hh @@ -17,3 +17,5 @@ bool is_local_address(const sockaddr_storage& daddr); std::string string_for_address(uint32_t address); uint32_t address_for_string(const char* address); + +uint64_t devolution_phone_number_for_netloc(uint32_t addr, uint16_t port);