@Puppytine, problems with the servers I do not see. They are stable even at max. players online.
I use command in .bat file:
mb2server.bat
openjkded.x86.exe +set dedicated 2 +set net_port 60001 +set fs_game MBII +exec server.cfg
mb2server2.bat
openjkded.x86.exe +set dedicated 2 +set net_port 60002 +set fs_game MBII +exec server2.cfg
mb2server3.bat
openjkded.x86.exe +set dedicated 2 +set net_port 60003 +set fs_game MBII +exec server3.cfg
and other your files on GameData and no problems.
Great. If your players doesn't report any errors, just keep it as it is.
BTW the more "clean" way is still to have a full mb2 folder dedicated to each server instance.
Not sure about "clean", but it's definitely not so elegant/pretty. It shouldn't be necessary to duplicate installation just to run a second instance of application.
Weird, because client fatal errors are the most known ones. Google the UI ones.
Ha! I've done some research, now I know why it happens.
jamp.exe and mbii.x86.exe both unpack dll and both whining when destination file is locked. The reason why it's possible to run a second instance of mbii is that it uses different folder to extract file but loads from JediAcademy\GameData\MBII!
So that's how it goes:
- mbii starts, unzip to uix86.dll to My Documents\My Games\OpenJK\MBII.
- My Documents\My Games\OpenJK\MBII\uix86.dll isn't locked now.
- mbii calls LoadLibrary, which pick uix86.dll from JediAcademy\GameData\MBII, which was placed there by jamp.exe.
- JediAcademy\GameData\MBII\uix86.dll is locked (for writing) now.
- Second copy mbii starts and successfully unpacks dll to My Documents\My Games\OpenJK\MBII\uix86.dll
- My Documents\My Games\OpenJK\MBII\uix86.dll still isn't locked now.
- ... I think it's obvious now.
Therefore it needs to have uix86.dll in JediAcademy\GameData\MBII to have multiple instances running. If mbii.x86.exe will not find some other copy of uix.86.dll to load, it will load and lock the one from "My Documents", and next copy of game will just fail to start due a sharing violation.
So here is universal way to run multiple instances of jamp, jampDed, jaMME etc: just copy all three files (cgamex86.dll, jampgamex86.dll, uix86.dll) to somewhere on search way, to "JediAcademy\GameData", for example.
Dlls in JediAcademy\GameData\MBII and My Documents\My Games\OpenJK\MBII will be overwritten over and over again, but they never be locked.
I've already tested it, and it works just fine!
But there's more of it. I looked at old source code, and that's what I've seen:
Code:
//make sure the dll can be opened by the file system, then write the
759 //file back out again so it can be loaded is a library. If the read
760 //fails then the dll is probably not in the pk3 and we are running
761 //a pure server -rww
762 bool Sys_UnpackDLL(const char *name)
763 {
764 void *data;
765 fileHandle_t f;
766 int len = FS_ReadFile(name, &data);
767 int ck;
768
769 if (len < 1)
770 { //failed to read the file (out of the pk3 if pure)
771 return false;
772 }
773
774 if (FS_FileIsInPAK(name, &ck) == -1)
775 { //alright, it isn't in a pk3 anyway, so we don't need to write it.
776 //this is allowable when running non-pure.
777 FS_FreeFile(data);
778 return true;
779 }
780
781 f = FS_FOpenFileWrite( name );
782 if ( !f )
783 { //can't open for writing? Might be in use.
784 //This is possibly a malicious user attempt to circumvent dll
785 //replacement so we won't allow it.
786 FS_FreeFile(data);
787 return false;
788 }
789
790 if (FS_Write( data, len, f ) < len)
791 { //Failed to write the full length. Full disk maybe?
792 FS_FreeFile(data);
793 return false;
794 }
795
796 FS_FCloseFile( f );
797 FS_FreeFile(data);
798
799 return true;
800 }
Jedi-Academy/win_main.cpp at d71d53e8ecc1edd300c7a9dd22b8fbc39c095423 · grayj/Jedi-Academy · GitHub
According to this, jamp/jampDed won't bother unpacking in case files are found on drive and files aren't in pk3.
So I deleted 3 dlls both from JediAcademy\GameData\MBII\MBII.pk3 and from JediAcademy\GameData\base\assets2.pk3, and after that I didn't get any errors launching second instance of jamp, jampDed and jaMME!
This is the second way to have multiple instances.
Then I explored new sources, there's some differences:
Code:
void *Sys_LoadLegacyGameDll( const char *name, VMMainProc **vmMain, SystemCallProc *systemcalls )
451 {
452 void *libHandle = NULL;
453 char filename[MAX_OSPATH];
454
455 Com_sprintf (filename, sizeof(filename), "%s" ARCH_STRING DLL_EXT, name);
456
457 #if defined(_DEBUG)
458 libHandle = Sys_LoadLibrary( name );
459 if ( !libHandle )
460 #endif
461 {
462 UnpackDLLResult unpackResult = Sys_UnpackDLL(filename);
463 if ( !unpackResult.succeeded )
464 {
465 if ( Sys_DLLNeedsUnpacking() )
466 {
467 FreeUnpackDLLResult(&unpackResult);
468 Com_DPrintf( "Sys_LoadLegacyGameDll: Failed to unpack %s from PK3.\n", filename );
469 return NULL;
470 }
471 }
472 else
473 {
474 libHandle = Sys_LoadLibrary(unpackResult.tempDLLPath);
475 }
476
OpenJK/sys_main.cpp at aa57c85e59f6067ec234f176255a4b73d03b0e64 · JACoders/OpenJK · GitHub
Code:
UnpackDLLResult Sys_UnpackDLL(const char *name)
505 {
506 UnpackDLLResult result = {};
507 void *data;
508 int len = FS_ReadFile(name, &data);
509
510 if (len >= 1)
511 {
512 if (FS_FileIsInPAK(name, NULL) == 1)
513 {
514 char *tempFileName;
515 if ( FS_WriteToTemporaryFile(data, len, &tempFileName) )
516 {
517 result.tempDLLPath = tempFileName;
518 result.succeeded = true;
519 }
520 }
521 }
522
523 FS_FreeFile(data);
524
525 return result;
526
}
527
528 bool Sys_DLLNeedsUnpacking()
529 {
530 #if defined(_JK2EXE)
531 return false;
532 #else
533 return Cvar_VariableIntegerValue("sv_pure") != 0;
534 #endif
535 }
OpenJK/sys_win32.cpp at db94c70b13df7ca22072f846ea324ff451b0ceb4 · JACoders/OpenJK · GitHub
As you can see, modern openjk unpacks stuff to temporary folder, so there is no way to have problems with locked files. When I started openjkDed.x86.exe, I found it loaded one module from temp directory.
Also source code says "if can't unpack and sv_pure is 0 proceed anyway, if can't unpack and sv_pure != 0 die".
I restricted access to temp files' folder, write in server's config:
And openjkDed.x86.exe ran normally, but when I modify config to:
openjkDed refused to start.