Ododo / scc-lan-restore

Restores LAN mode on Splinter Cell Conviction (PC) after servers shutdown.
37 stars 0 forks source link

Out of sync if not same cpu #3

Open vince1016 opened 5 months ago

vince1016 commented 5 months ago

I know thats something you have found something and you doesn't really understand the code, but just trying to let you know thats something that would be great to resolve. I think thats really related to not having the same cpu brand. Will test it when i can. I can join no problem with hamachi tho on windows 10

Ododo commented 5 months ago

yeah.. that would be great indeed. i'm very busy at the moment however. if anyone has findings on their side they can post them in this issue.

Splainte commented 5 months ago

Hi ! First of all, thanks a lot for your work. My brother and I wanted to play this game Coop for a long time, and now we are closer than ever to be able to !

I just want to let you know that indeed, there is a problem with Ryzen (or at least, with the Intel/Ryzen coop combo). I tried to play on my main PC which has a R9 5900X with my brother who has an Intel Core i5, and at the first input, we are disconnected.

I then tried on my laptop which is Intel based, and it worked !! First try we got a disconnection, but second try worked !

If you find something to correct this issue, that would be awesome.

Thanks again !

ThirteenAG commented 2 months ago

if anyone has findings on their side they can post them in this issue.

I checked and the error displayed has "DivergenceMessageBoxMessage" id in localization files, and that id is used only by one function.

...
      *(float *)&dword_142EB64 = *(float *)&dword_13A31CC + *(float *)&dword_142EB64;
      if ( *(float *)&dword_142EB64 >= 2.0 && sub_8C4079((_DWORD **)dword_142EB7C) )
      {
        v3 = sub_792B49();
        v4 = (*(int (__thiscall **)(int))(*(_DWORD *)v3 + 496))(v3);
        if ( !(*(int (__thiscall **)(int))(*(_DWORD *)v4 + 400))(v4) )
        {
          if ( dword_142EB7C )
            sub_8C409B(dword_142EB7C);
          sub_40C3A0((void *)&Caption);
          sub_40C3A0((void *)&Caption);
          sub_40C3A0((void *)&Caption);
          sub_40C3A0((void *)&Caption);
          sub_77BB27(83, v14, v12, 1, 0, 0, v15, v13, 1, 1, -1.0);
          sub_40C40E(v14);
          sub_40C40E(v12);
          sub_40C40E(v15);
          sub_40C40E(v13);
          v9 = 11;
          v5 = sub_445900((int)&off_10D3024, (int)L"DivergenceMessageBoxTitle", (int)"Localization\\System", 0, 0);
          sub_40DBB2(v10, v5);
          v6 = sub_445900((int)&off_10D3024, (int)L"DivergenceMessageBoxMessage", (int)"Localization\\System", 0, 0);
          sub_40DBB2(v11, v6);
          v11[7] = dword_142EB84;
          v11[5] = 1;
          v11[6] = 1;
          v7 = sub_792B49();
          (*(void (__thiscall **)(int, int *, int))(*(_DWORD *)v7 + 340))(v7, &v9, 3);
          sub_77BC47(&v9);
        }
...

Tried to disable this code path, but the game just gets stuck without an error message. This code is not executed until the button is pressed, or rather character movement occurs.

int __usercall sub_7C4A7A@<eax>(MassiveAdClient3::CMassiveAsset *a1@<ebx>, float a2)
{
  int result; // eax
  int v3; // esi

  result = sub_7C0894();
  if ( result )
  {
    sub_45FA0A();
    sub_45F36B(0);
    v3 = sub_7C2FCF(LODWORD(a2)); // this is executed always
    sub_45FA0A();
    result = sub_45F36B(1);
    if ( v3 ) // false until player moves and out of sync occurs
    {
      result = sub_7C0745();
      if ( !result )
        return sub_7C465E(a1); // out of sync error message displayed here
    }
  }
  return result;
}

Overall it might be an issue described here, since many people confirmed different CPUs cause out of sync error.

https://cookieplmonster.github.io/2020/07/19/silentpatch-mass-effect/#part-3

pancake-re commented 2 months ago

if anyone has findings on their side they can post them in this issue. Overall it might be an issue described here, since many people confirmed different CPUs cause out of sync error.

https://cookieplmonster.github.io/2020/07/19/silentpatch-mass-effect/#part-3

I can send you some Wireshark records from intel-ryzen and intel-intel sessions, if it may help in research

ThirteenAG commented 2 months ago

I wouldn't know what to do with them, just upload them here and maybe someone else can take a look.

Ododo commented 2 months ago

Thanks for sharing @ThirteenAG I have bit searched for sse related issues but did not come across this paper. We might aswell just blindy test the solutions proposed here then ..

Thats where i stopped so far: dword_13A31CC or dword_142EB64 seems to be some kind of divergence accumulator which main calculation resides in a function syncing both players. It is the same routine capping both player at a fixed framerate (30).

Function starts like this:

void FUN_0042ce22(int *param_1)
  ...
  (**(code **)(*(int *)PTR_PTR_01265ee4 + 0xac))(1);
  local_c = 0x78;
  (**(code **)(*DAT_013a0fe0 + 4))("Engine.Display","MaxFPS",&local_c,"User.ini");
  iVar5 = 0x1e;
  if ((0x1d < local_c) && (iVar5 = 1000, local_c < 1000)) {
    iVar5 = local_c;
  }

Then something like:

 For frame:
   float delayAcc;
   float tpf = 1/MAXFPS // time per frame
   s = QueryPerformanceCounter();  // portable across platforms
   do_stuff_for_player1();
   a = QueryPerformanceCounter();
   probably_do_stuff_with(a-s)(&delayAcc);
   do_stuff_for_player2();
   b = QueryPerformanceCounter();
   probably_do_stuff_with(b-a)(&delayAcc);
   diff  = b-s:
   if (diff > tpf) { delayAcc += (diff - tpf) }
   if (diff < tpf) { wait_until_frame_is_finished; go to next frame }

Disabling the threshold completly gives pretty much same results as yours, but i have some generic error message instead smthing like "connection with remote player lost". So I was even wondering if the divergence is the main issue here, or if it just a result of some previous operation failing and the game happens to catch it as divergence event.

ThirteenAG commented 2 months ago

Something I also noticed while testing coop with two instances of exe, after initial movement game freezes for a bit, and normally after that, when playing with another pc, out of sync error appears, yet locally it unfreezes and continues. Maybe the problem is localized to whatever is happening during that freeze.

Ododo commented 2 months ago

Overall it might be an issue described here, since many people confirmed different CPUs cause out of sync error.

https://cookieplmonster.github.io/2020/07/19/silentpatch-mass-effect/#part-3

Unless i did something wrong disabling PSGP did not help.. Tried with: DisablePSGP DisableD3DXPSGP DisableD3DX10PSGP On both intel and amd machines.

Do note that for dx9 the variable is DisableD3DXPSGP, but it is DisableD3DX10PSGP for dx10.

I wonder what could happen if we spoof cpuid though..

ThirteenAG commented 2 months ago

Well, I tried to nop all cpuid instructions, doesn't make any difference.

r3538987 commented 1 month ago

Just played with friend first coop map. No issues what's so ever, silky smooth 60fps. Used scc_lan_helper EXE version. My CPU - Ryzen 9 5900X His CPU - Ryzen 7 3800XT

2nd map - quite some desyncs. 3rd map - no desyncs.

Not sure if these are map related things or not.

englerd commented 5 days ago

@r3538987 my CPU: AMD Ryzen 5 6600H - Shall we play together in co-op mode?