As a French person I feel like it's my duty to explain strikes to you. - AdrienIer

Create an account  

 
Multiplayer after GameSpy - Lobby and NatNeg

So here I am again, hoping that someone can help me with a network problem. This is the situation:
up to 5 pc, all on the same LAN. All of them using ZeroTier to share a virtual LAN so that we can play when we are not on the same physical LAN. Works flawlessly with DirectIP, tested it also with 4 pc on the same physical LAN and one connected through a mobile hotspot, always using ZeroTier. No problem at all with DirectIP although there's a mix of Win11, Win10 Pro, Win10 Home, 2 Win7 pc and laptops. It looks like I can't properly make the Wrapper work but that's not an issue as we share the savegame on a OneDrive account. To be more specific, I share my OneDrive savegame folder with other players and they add that shared OneDrive folder to "MyFiles" on their accounts. We all created an altroot folder on our pc named "_http_xx.xx.xx.xx" where xx is the IP address of the host and mklinked properly every altroot folder to the shared OneDrive folder (I know it's not necessary to name the folder like that when sharing a common OneDrive folder, but that's ok). When playing DirectIP using ZeroTier and using my virutal LAN PC address (I'm the host), no problem at all and loading is instant. No need for port forwarding or any other change to the port number for anyone.
The problem starts when I try to host a pitboss game. Same setting as above, I run the pitboss on my pc; I also run my game on the same pc. I can connect properly, no loading time. Second laptop connects properly, no loading time. Third pc and every other can connect but they ALL start the old and slow savegame transfer process. If I interrupt the transfer process and I try reconnecting again on that pc, game is loaded immediately, I just get an error on the pitboss pc stating that the recovery savegame for that player can't be written; after one turn, the game goes OOS, I assume because of the incomplete savegame transfer. If I painfully let all the transfer go on, no OOS and the game works flawlessly. The strange part is that even if nobody is connected and even if I start a new pitboss game on my pc, I can always connect properly to the pitboss and the same goes for the second laptop. But even if I start a game with my pc as pitboss and any other of the 3 pc (except the second laptop, which works) the game is always being transferred slowly.
I really can't understand why and what's happening. I would assume it's something related to the other pc/laptops configuration or their OneDrive accounts, but there's no firewall and no port forwarding or anything else. Like the second laptop which connects properly, no matter how many other players are already connected to the pitboss server, so I suppose should be for every other pc in the virtual LAN. Except it doesn't work.
Any advice anyone to let all the pc/laptops have a quick savegame transfer?
Thanks.

P.S. On a sidenote, I tried doing the same with Dropbox instead of OneDrive and I have the same identical issue
Reply

I just noticed something strange with my problem above: when I connect my pc or the second laptop to the pitboss, loading/transferring is quick and I can see Recovery_Username savegame being created in my Saves\pitboss\auto folder. But when I connect the third pc, it creates a Recovery_Username savegame in Saves\multi\auto too and it looks like this is why it takes so long to transfer the game to the third pc: I end up with a coopy of Recovery_Username in Saves\pitboss\auto and another one in Saves\multi\auto, which is created 4 minutes later, exactly when the transfer is finished. I really can't understand this behaviour, and I'm sure the folders are properly mklinked. I hope anyone can enlighten me.

Edit: it's the BTS_Wrapper: for some reason it doesn't kick in on the third PC. I tried using the stardard Civ4 exe (2015) on the second laptop, and transfer is slow; also, in addition to Recovery_username savegame under Saves\pitboss\auto, another Recovery_username savegame is created in Saves\multi\auto exactly after the transfer is finished. As soon as I restore the original start with the BTS_Wrapper on the second laptop, transfer is quick again. Now, why does the wrapper not work on the third pc? I have no clue. I tried running it as admin, but no luck. Third pc is using Windows10 Home, but I don't see what difference it could make. Maybe Ramkhamhaeng or someone else has any idea?
Reply

Hi,

1) If the wrapper starting is Civ4 but does not working then probably the hooking fails because it can not find MinHook.x86.dll.
• Did this file existing in the Civ4:BTS installation folder?
• Could you see/post the BTS_Wrapper.log file from the problematic machine? If the Civ4:BTS folder is not write protected it will written there.
(Other possible target folders for the log file are %TMP% and Civ4:BTS/Logs ^^°)
The log file should list each save game transfer if its working.

2) Did you use the same version of the wrapper on all machines? In the latest version (the version with the ipv6 support) I've putted all external dlls into the subdirectory „BTS_Wrapper_Libs“. This is a big difference to earlier versions.
In  older versions the dlls are placed into the same folder as the Civ4:BTS binary.

3) An player noted (a few years ago) that the  'Hidden Intrusion Protection' functionality of the default firewall BTS_Wrapper's hooking process disturbs.


Edit: If nothing helps, I had still two other programs, one for windows and one for linux, created which working similar to folder your sharing approach: They tracing the file-reading of the savegame and downloading the saves.
But fixing the issues with the Wrapper is probably less work. [Image: Civ4Religion.png]
Reply

Thanks for your reply Ramk,

in the meantime I've been able to make it work on 2 of the 3 pc that weren't working. I set up a pitboss server using Win10 built in feature and now 4 of 5 pc are working correctly.
There's just 1 pc which is not working, and yes, MinHook.x86.dll is the BTS_Wrapper_Libs subfolder, I'm using this latest version on all pc, it's exactly the same. I've tried with and without MinHook.x86.dll in the BTS folder too. I can't post a log for that machine because it doesn't create a log, not in BTS folder, not in the %tmp% folder, not in civ4logs folder. Parameters in the shortcut are correct as they work on the other 4 machines, this is what I use:

"C:\FOLDER\Civilization 4\Civ4\Beyond the Sword\BTS_Wrapper.exe" /ALTROOT="C:\FOLDER\_http_aa.bbb.cc.dd"  mod= "Realism Invictus" -l BTSWrapper.log -P 2057

I tried with and without BTSWrapper.log as an argument, I've tried different ports. I also noticed that for some reason on some machine (those using Win7) I have to add an extra " after the mod's name or the link will be interpreted as the mod name is including BTS_Wrapper arguments. Windows Firewall is off on the problematic machine, there are no other firewalls. We're all connected via ZeroTier virtual LAN and all machines are working without issues, even those using older versions of ZeroTier.
Just thinking about it right now: the problematic machine is the only one using italian as language, so Users folder is actually called Utenti. Could this be the problem? I thought it shouldn't as Users is still a valid folder which should be the same as Utenti, but I have no other idea.
Reply

Well, language is not an issue. I tried changing the language from italian to english, so Users folder is now actually called like that, but it still doesn't work. I also tried uninstalling everything related to Visual Studio and reinstalled only the redistributable package (x64, as per civ-wiki.de), still not working. I mean, when I start the wrapper with the appropriate arguments, Civ4BeyondSword2015 is actually launched so that part works. But logs are nowhere to be found, so there must be something wrong. I'm really out of ideas.
Reply

No way, I tried your other program for windows Ramk, but it doesn'twork. I'm not trying to connect to zulan's pitboss, so that might be the issue as I think your program is tailored for zulan's server, if I'm not mistaken. What I don't understand about the wrapper is where the problem might be, as it partially works since it correctly starts Civ4BeyondSword2015 even if I don't specify the exe in the wrapper arguments, but no log is created and it looks like the wrapper is crashing immediately after launching Civ4BeyondSword2015.exe.
Reply

I'm sorry to hear that. It's hard to give you good advice without a log. (And I'm responsible for this non-working log ^^)

The Wrapper-Program is a command line tool and its terminal window is closed if you're starting it by a shortcut. If you run it in a terminal window you can read the output:
Code:
1. Run cmd.exe
2. cd "C:\FOLDER\Civilization 4\Civ4\Beyond the Sword"
3. BTS_Wrapper.exe /ALTROOT="C:\FOLDER\_http_aa.bbb.cc.dd"  mod= "Realism Invictus" -l
Note: If your unfamiliar with the terminal: To paste text in the old windows cmd.exe you has to right-click on its title bar. Ctrl+C will not work.

Other idea:
Maybe the older version of the Wrapper works or creating at least a log?!
https://civ.zulan.net/pb/BTS_Wrapper_v9_...py_fix.zip
(Here, the log filename can not be set manually. It's always BTS_Wrapper.log)
Reply

I made some more experiments.
On the working machine, if I don't set an argument for the log, it doesn't get created. But whatever argument I use for the log, always BTS_Wrapper.log gets created in the temp folder, no matter what name I choose.
On the problematic machine, I've also tried your v9 but as before, civ2015 gets started but no log is created. I tied launching it from the terminal, what I see different between the working and the not working machine is that I get 2 different lines in the terminal output after launching the wrapper. On the working machine I can read

dllHandleRemote: 70240000
pSetOtherArgsRemote: 7024C6C0

On the not working machine those lines are

dllHandleRemote: 00000000
pSetOtherArgsRemote: 00000000

I also noted that if I start with just the port argument, I get a message like

"Startserver function not exists. CivSaveOverHttp.dll not found ?!"
But the dll is there in the lib folder. I also tried to move it to the main folder where the wrapper is, but it didn't work either. Does it help you in any way? It might be some Windows component missing or something like that?
Reply

(May 19th, 2023, 04:11)45°38'N-13°47'E Wrote: […] On the working machine I can read

dllHandleRemote: 70240000
pSetOtherArgsRemote: 7024C6C0

On the not working machine those lines are

dllHandleRemote: 00000000
pSetOtherArgsRemote: 00000000

[…]Does it help you in any way? It might be some Windows component missing or something like that?

Yes, this helps. So something failing in this section of the code:
Code:
243   std::cout << "Creating remote thread" << std::endl;
244   HANDLE hThread = CreateRemoteThread(processInformation.hProcess, NULL, 1,
245       (LPTHREAD_START_ROUTINE)pLoadLibrary, pReservedSpace, 0, NULL);
246   if (!hThread)
247   {
248     std::cout << "Unable to create the remote thread. GetLastError() = " << GetLastError() <    < std::endl;
249     return 0;
250   }
251
252   std::cout << "Thread created" << std::endl;
253
254   WaitForSingleObject(hThread, INFINITE);
255   VirtualFreeEx(processInformation.hProcess, pReservedSpace, dllName.length(), MEM_COMMIT);
256   //VirtualFreeEx(processInformation.hProcess, pReservedSpace, strlen(dllName), MEM_COMMIT);
257
258

259   // Get return value of remote call of LoadLibrary by reading GetExitCodeThread
260   // We need this value for calls of GetRemoteProcAddress later...
261   // NOTE: Unfortunately this doesn’t work for 64bit processes! GetExitCodeThread returns a 32bit value; in a 64bit process, LoadLibrary will return a 64bit value.
262   DWORD exitCode;
263   if( !GetExitCodeThread(hThread, &exitCode) ){
264     std::cout << "Unable to get exit code of remote thread. GetLastError() = " << GetLastError() << std::endl;
265     return 0;
266   }
267   HMODULE dllHandleRemote = (HMODULE) exitCode;
268
269   std::cout << "dllHandleRemote: " << std::hex << dllHandleRemote << std::endl;
270
=>  GetExitCodeThread(…, &exitCode) returns NULL
=> pLoadLibrary returns NULL
=> Probably a DLL-Dependency of CivSaveOverHttp.dll is missing.

You can check this by a dependency viewer like this

If I open the dll with the linked program it looks like this:
   
I assume on your problematic System is one of the following dlls not installed: VCRUNTIME140.dll, MSVCP100.dll, or MSVCR100.dll.

If we know which dependency is missing we could probably fix the problem! smile
Reply

The next version of the wrapper will point out this error and keeping the terminal window open if an error occurs. So, hopefully this will help other users with the same problem.
Reply



Forum Jump: