DescentDevelopers / Descent3

Descent 3 by Outrage Entertainment
GNU General Public License v3.0
2.87k stars 248 forks source link

[Runtime Issue]: Multiplayer crash after round completion #217

Closed DescentMax closed 5 months ago

DescentMax commented 6 months ago

Build Version

v1.5 Stable Milestone

Operating System Environment

CPU Environment

Game Modes Affected

Game Environment

Anarchy on The Core

Description

Played a round of Anarchy on the Core. Myself, DAK, and CCFireball were using the latest build of v1.5 Stable Milestone as of 4.27.2024. The server and clients crashed after round completion. Server was on Windows. Gameplay also on Windows Screenshot 2024-04-27 225842

Regression Status

Unsure on Commit number

Steps to Reproduce

Complete Anarchy round on MP

DescentMax commented 6 months ago

Update on this: So the main branch 1.5 "stable milestone" has the issue when the level ends and transitions to the next level, it crashes on the server and the clients hang and crash along with it. However, I pulled the latest build of SaladBadgers Piccu Engine (as of 4.28.2024) and loaded it on the clients and server, and the server did NOT crash. Tested with transitioning to another level, and also letting it repeat the same level after 20 kills, and no crashes. So somethings borked on the main 1.5 branch

JeodC commented 6 months ago

Is this related to #213 where a new dfmc.dll build is required?

JeodC commented 5 months ago

@DescentMax does this still occur?

DescentMax commented 5 months ago

Will need to test this. Sorry just saw my email on this. I need to get folks to test this. Piccu Edition does not crash on the Fury set at least. I gotta see about main v1.5

DescentMax commented 5 months ago

UPDATE: I ran a 5 min test to see what it would do and it crashed as soon as the level ended. Server Side. Running the artifact from 5.8.2024 Screenshot 2024-05-09 212336

JeodC commented 5 months ago

I am not sure if it's linked, but on Windows 11, the game will crash multiple times on startup in dedicated mode. The white console pops up, you see Initializing I/O System, and then it crashes. It takes a few times to get the console to continue to where it will download the data and start the server.

I have traced this, painstakingly since there are no debugging symbols to assist in dedicated mode. In init.cpp I added some console messages to better log the init process:

//  do io init stuff
  io_info.obj = Descent;
  io_info.use_lo_res_time = (bool)(FindArg("-lorestimer") != 0);
  io_info.joy_emulation = (bool)((FindArg("-alternatejoy") == 0) && (FindArg("-directinput") == 0));
  io_info.key_emulation = (bool)(FindArg("-slowkey")!=0); //WIN95: DirectInput is flaky for some keys.
  INIT_MESSAGE("Starting DDIO Initialization.");
  if (!ddio_Init(&io_info)) {
    INIT_MESSAGE("I/O initialization failed.");
    Error("I/O initialization failed.");
  } else {
       INIT_MESSAGE("I/O initialized.");
    }

The final message I get before a crash is Starting DDIO Initialization. That means the game crashes in the function ddio_Init. That function is in ddio_common/ddio.cpp:

bool ddio_Init(ddio_init_info *init_info) {
  static bool first_time = true;
  bool res;
  ASSERT(!DDIO_initialized);
  if (first_time) {
    atexit(ddio_Close);
  }
  mprintf((0, "DDIO system initializing...\n"));
  res = ddio_InternalInit(init_info);
  if (res) {
    if (first_time) { // initialize once and only once.
      timer_Init(0, init_info->use_lo_res_time);
    }
    if (!ddio_KeyInit(init_info)) {
      Error("Failed to initialize keyboard system.");
    }
    ddio_MouseInit();
  }
  first_time = false;
  DDIO_initialized = true;
  joy_Init(init_info->joy_emulation);
  return res;
}

I tried commenting out the assertion to try and force it, but that proved to not be the problem. Therefore, we can check the actual initialization ddio_InternalInit. That's in ddio_win/winio.cpp:

bool ddio_InternalInit(ddio_init_info *init_info) {
  oeWin32Application *obj = (oeWin32Application *)init_info->obj;
  LPDIRECTINPUT lpdi;
  HRESULT dires;

  ASSERT(!DDIO_init);

  //    Initialize DirectInput subsystem
  mprintf((0, "DI system initializing.\n"));

  // Try to open DirectX 5.00
  dires = DirectInputCreate((HINSTANCE)obj->m_hInstance, DIRECTINPUT_VERSION, &lpdi, NULL);

  // Deal with error opening DX5
  if (dires != DI_OK) {

    // If running NT, try DirectX 3.0
    if (obj->NT()) {

      dires = DirectInputCreate((HINSTANCE)obj->m_hInstance, 0x0300, &lpdi, NULL);
      if (dires != DI_OK) {
        Error("Unable to DirectInput system (Requires at least DirectX 3.0 For NT) [DirectInput:%x]\n", dires);
      }
    } else { // Not running NT, so error out

      // Couldn't open DirectX, so print error
      Error("Unable to DirectInput system (Requires at least DirectX 5.0) [DirectInput:%x]\n", dires);
    }
  }

  DInputData.app = obj;
  DInputData.lpdi = lpdi;
  DInputData.hwnd = (HWND)obj->m_hWnd;

  DDIO_init = 1;

  return 1;
}

This will need a refactor for modern systems eventually. The solution, for now, is to use Windows 95 compatibility mode. By doing so I am able to start the server consistently.

HOWEVER, this does not resolve the initial problem, which is a crash on end of round or server shutdown.

DescentMax commented 5 months ago

The servers I host are running windows server 2022 just for your info