diff --git a/README.md b/README.md index 2a75bad1..2809f4a9 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,20 @@ A few things to be aware of when using the proxy server: ### Connecting local clients +#### PSO DC + +Some versions of PSO DC will connect to a private server if you just set their DNS server address (in the network configuration) to newserv's address, and enable newserv's DNS server. This will not work for other versions; for those, you'll need a cheat code. Creating such a code is beyond the scope of this document. + +If you're emulating PSO DC or have a disc image, you can patch the appropriate files within the disc image to make it connect to any address you want. Creating such a patch is also beyond the scope of this document. + +Finally, if you're emulating PSO DC, you can modify the loaded executable in memory to make it connect anywhere you want. There is a script included with newserv that can do this for Flycast. The script only works on macOS because it uses memwatch, which is a macOS-specific program, but a similar technique could be done manually using scanmem on Linux or Cheat Engine on Windows. To use the script, do this: +1. Build and install memwatch (https://github.com/fuzziqersoftware/memwatch). +2. Start Flycast and run PSO. +3. Run `sudo patch_flycast_memory.py `. `` should be the hostname that PSO wants to connect to (you can find this out by using Wireshark and looking for DNS queries). The script may take up to a minute; you can continue using Flycast while it runs, but don't start an online game until the script is done. +4. Run newserv and start an online game in PSO. + +If you use this method, you'll have to run the script every time you start PSO in Flycast, but you won't have to run it again if you start another online game without restarting emulation. + #### PSO PC The version of PSO PC I have has the server addresses starting at offset 0x29CB34 in pso.exe. Using a hex editor, change those to "localhost" (without quotes) if you just want to connect to a locally-running newserv instance. Alternatively, you can add an entry to the Windows hosts file (C:\Windows\System32\drivers\etc\hosts) to redirect the connection to 127.0.0.1 (localhost) or any other IP address. diff --git a/patch_flycast_memory.py b/patch_flycast_memory.py new file mode 100755 index 00000000..c5b81146 --- /dev/null +++ b/patch_flycast_memory.py @@ -0,0 +1,38 @@ +#!/bin/env python3 + +import os +import subprocess +import sys + + +def get_ip_address(ifname): + data = subprocess.check_output(['ifconfig', ifname]) + for line in data.splitlines(): + line = line.strip() + if line.startswith(b'inet '): + return line.split()[1].decode('ascii') + raise RuntimeError('cannot get address for interface ' + ifname) + + +def main(argv): + if len(argv) < 2: + raise RuntimeError(f'Usage: {argv[0]} [new-destination]') + if os.geteuid() != 0: + raise RuntimeError('You must use sudo to run this script') + original_destination = argv[1] + new_destination = argv[2] if len(argv) > 2 else get_ip_address('en0') + + print(f'Finding occurrences of \"{original_destination}\"') + addresses_str = subprocess.check_output(['memwatch', 'Flycast.app', 'find', f'\"{original_destination}\"']) + for line in addresses_str.splitlines(): + tokens = line.split() + if len(tokens) != 3: + continue + print(f'Replacing \"{original_destination}\" with \"{new_destination}\" at {tokens[1]} in Flycast') + subprocess.check_call(['memwatch', 'Flycast.app', 'write', tokens[1], f'\"{new_destination}\" 00']) + + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv))