367 lines
9.6 KiB
C++
367 lines
9.6 KiB
C++
/*
|
|
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
|
* United States. Use of a copyright notice is precautionary only and
|
|
* does not imply publication or disclosure.
|
|
*
|
|
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
|
* OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION,
|
|
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
|
* EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT.
|
|
*/
|
|
|
|
#include "../types.h"
|
|
|
|
int nthread_cpp_init_value; // weak
|
|
char byte_679704; // weak
|
|
int gdwMsgLenTbl[4];
|
|
static CRITICAL_SECTION sgMemCrit;
|
|
int gdwDeltaBytesSec; // weak
|
|
char byte_679734; // weak
|
|
int gdwTurnsInTransit; // weak
|
|
int glpMsgTbl[4];
|
|
unsigned int glpNThreadId;
|
|
char sgbSyncCountdown; // weak
|
|
int dword_679754; // weak
|
|
char byte_679758; // weak
|
|
char sgbPacketCountdown; // weak
|
|
char sgbThreadIsRunning; // weak
|
|
int gdwLargestMsgSize; // weak
|
|
int gdwNormalMsgSize; // weak
|
|
int dword_679764; // weak
|
|
|
|
int nthread_inf = 0x7F800000; // weak
|
|
|
|
/* rdata */
|
|
static HANDLE sghThread = (HANDLE)0xFFFFFFFF; // idb
|
|
|
|
//----- (00440DB3) --------------------------------------------------------
|
|
struct nthread_cpp_init_1
|
|
{
|
|
nthread_cpp_init_1()
|
|
{
|
|
nthread_cpp_init_value = nthread_inf;
|
|
}
|
|
} _nthread_cpp_init_1;
|
|
// 47F164: using guessed type int nthread_inf;
|
|
// 679700: using guessed type int nthread_cpp_init_value;
|
|
|
|
//----- (00440DBE) --------------------------------------------------------
|
|
struct nthread_cpp_init_2
|
|
{
|
|
nthread_cpp_init_2()
|
|
{
|
|
nthread_init_mutex();
|
|
nthread_cleanup_mutex_atexit();
|
|
}
|
|
} _nthread_cpp_init_2;
|
|
|
|
//----- (00440DC8) --------------------------------------------------------
|
|
void __cdecl nthread_init_mutex()
|
|
{
|
|
InitializeCriticalSection(&sgMemCrit);
|
|
}
|
|
|
|
//----- (00440DD4) --------------------------------------------------------
|
|
void __cdecl nthread_cleanup_mutex_atexit()
|
|
{
|
|
atexit(nthread_cleanup_mutex);
|
|
}
|
|
|
|
//----- (00440DE0) --------------------------------------------------------
|
|
void __cdecl nthread_cleanup_mutex()
|
|
{
|
|
DeleteCriticalSection(&sgMemCrit);
|
|
}
|
|
|
|
//----- (00440DEC) --------------------------------------------------------
|
|
void __fastcall nthread_terminate_game(char *pszFcn)
|
|
{
|
|
char *v1; // esi
|
|
int v2; // eax
|
|
char *v3; // eax
|
|
|
|
v1 = pszFcn;
|
|
v2 = SErrGetLastError();
|
|
if ( v2 != STORM_ERROR_INVALID_PLAYER )
|
|
{
|
|
if ( v2 == STORM_ERROR_GAME_TERMINATED || v2 == STORM_ERROR_NOT_IN_GAME )
|
|
{
|
|
gbGameDestroyed = 1;
|
|
}
|
|
else
|
|
{
|
|
v3 = GetLastErr();
|
|
TermMsg("%s:\n%s", v1, v3);
|
|
}
|
|
}
|
|
}
|
|
// 67862D: using guessed type char gbGameDestroyed;
|
|
|
|
//----- (00440E28) --------------------------------------------------------
|
|
int __fastcall nthread_send_and_recv_turn(int cur_turn, int turn_delta)
|
|
{
|
|
int v2; // ebx
|
|
unsigned int v3; // edi
|
|
char *v5; // ecx
|
|
int v6; // eax
|
|
int turn; // [esp+Ch] [ebp-8h]
|
|
int turns; // [esp+10h] [ebp-4h]
|
|
|
|
v2 = turn_delta;
|
|
v3 = cur_turn;
|
|
if ( SNetGetTurnsInTransit(&turns) )
|
|
{
|
|
if ( turns >= (unsigned int)gdwTurnsInTransit )
|
|
return v3;
|
|
while ( 1 )
|
|
{
|
|
++turns;
|
|
v6 = dword_679754 | v3 & 0x7FFFFFFF;
|
|
dword_679754 = 0;
|
|
turn = v6;
|
|
if ( !SNetSendTurn((char *)&turn, 4) )
|
|
break;
|
|
v3 += v2;
|
|
if ( v3 >= 0x7FFFFFFF )
|
|
v3 = (unsigned short)v3;
|
|
if ( turns >= (unsigned int)gdwTurnsInTransit )
|
|
return v3;
|
|
}
|
|
v5 = "SNetSendTurn";
|
|
}
|
|
else
|
|
{
|
|
v5 = "SNetGetTurnsInTransit";
|
|
}
|
|
nthread_terminate_game(v5);
|
|
return 0;
|
|
}
|
|
// 679738: using guessed type int gdwTurnsInTransit;
|
|
// 679754: using guessed type int dword_679754;
|
|
|
|
//----- (00440EAA) --------------------------------------------------------
|
|
int __fastcall nthread_recv_turns(int *pfSendAsync)
|
|
{
|
|
int *v1; // esi
|
|
bool v2; // zf
|
|
|
|
v1 = pfSendAsync;
|
|
*pfSendAsync = 0;
|
|
if ( --sgbPacketCountdown )
|
|
{
|
|
dword_679764 += 50;
|
|
return 1;
|
|
}
|
|
v2 = sgbSyncCountdown-- == 1;
|
|
sgbPacketCountdown = byte_679704;
|
|
if ( !v2 )
|
|
goto LABEL_11;
|
|
if ( SNetReceiveTurns(0, 4, (char **)glpMsgTbl, (unsigned int *)gdwMsgLenTbl, (unsigned long *)player_state) )
|
|
{
|
|
if ( !byte_679758 )
|
|
{
|
|
byte_679758 = 1;
|
|
dword_679764 = GetTickCount();
|
|
}
|
|
sgbSyncCountdown = 4;
|
|
multi_msg_countdown();
|
|
LABEL_11:
|
|
*v1 = 1;
|
|
dword_679764 += 50;
|
|
return 1;
|
|
}
|
|
if ( SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING )
|
|
nthread_terminate_game("SNetReceiveTurns");
|
|
byte_679758 = 0;
|
|
sgbSyncCountdown = 1;
|
|
sgbPacketCountdown = 1;
|
|
return 0;
|
|
}
|
|
// 679704: using guessed type char byte_679704;
|
|
// 679750: using guessed type char sgbSyncCountdown;
|
|
// 679758: using guessed type char byte_679758;
|
|
// 679759: using guessed type char sgbPacketCountdown;
|
|
// 679764: using guessed type int dword_679764;
|
|
|
|
//----- (00440F56) --------------------------------------------------------
|
|
void __cdecl nthread_set_turn_upper_bit()
|
|
{
|
|
dword_679754 = 0x80000000;
|
|
}
|
|
// 679754: using guessed type int dword_679754;
|
|
|
|
//----- (00440F61) --------------------------------------------------------
|
|
void __fastcall nthread_start(bool set_turn_upper_bit)
|
|
{
|
|
BOOL v1; // esi
|
|
char *v3; // eax
|
|
unsigned int v4; // esi
|
|
unsigned int v5; // eax
|
|
char *v6; // eax
|
|
_SNETCAPS caps; // [esp+8h] [ebp-24h]
|
|
|
|
v1 = set_turn_upper_bit;
|
|
dword_679764 = GetTickCount();
|
|
sgbPacketCountdown = 1;
|
|
sgbSyncCountdown = 1;
|
|
byte_679758 = 1;
|
|
if ( v1 )
|
|
nthread_set_turn_upper_bit();
|
|
else
|
|
dword_679754 = 0;
|
|
caps.size = 36;
|
|
if ( !SNetGetProviderCaps(&caps) )
|
|
{
|
|
v3 = GetLastErr();
|
|
TermMsg("SNetGetProviderCaps:\n%s", v3);
|
|
}
|
|
gdwTurnsInTransit = caps.defaultturnsintransit;
|
|
if ( !caps.defaultturnsintransit )
|
|
gdwTurnsInTransit = 1;
|
|
if ( caps.defaultturnssec <= 0x14u && caps.defaultturnssec )
|
|
byte_679704 = 0x14u / caps.defaultturnssec;
|
|
else
|
|
byte_679704 = 1;
|
|
v4 = 512;
|
|
if ( caps.maxmessagesize < 0x200u )
|
|
v4 = caps.maxmessagesize;
|
|
gdwDeltaBytesSec = (unsigned int)caps.bytessec >> 2;
|
|
gdwLargestMsgSize = v4;
|
|
if ( caps.maxplayers > 4u )
|
|
caps.maxplayers = 4;
|
|
v5 = (3 * (caps.bytessec * (unsigned int)(unsigned char)byte_679704 / 0x14) >> 2) / caps.maxplayers;
|
|
gdwNormalMsgSize = v5;
|
|
if ( v5 < 0x80 )
|
|
{
|
|
do
|
|
{
|
|
byte_679704 *= 2;
|
|
v5 *= 2;
|
|
}
|
|
while ( v5 < 0x80 );
|
|
gdwNormalMsgSize = v5;
|
|
}
|
|
if ( v5 > v4 )
|
|
gdwNormalMsgSize = v4;
|
|
if ( (unsigned char)gbMaxPlayers > 1u )
|
|
{
|
|
sgbThreadIsRunning = 0;
|
|
EnterCriticalSection(&sgMemCrit);
|
|
byte_679734 = 1;
|
|
sghThread = (HANDLE)_beginthreadex(NULL, 0, nthread_handler, NULL, 0, &glpNThreadId);
|
|
if ( sghThread == (HANDLE)-1 )
|
|
{
|
|
v6 = GetLastErr();
|
|
TermMsg("nthread2:\n%s", v6);
|
|
}
|
|
SetThreadPriority(sghThread, THREAD_PRIORITY_HIGHEST);
|
|
}
|
|
}
|
|
// 679660: using guessed type char gbMaxPlayers;
|
|
// 679704: using guessed type char byte_679704;
|
|
// 679730: using guessed type int gdwDeltaBytesSec;
|
|
// 679734: using guessed type char byte_679734;
|
|
// 679738: using guessed type int gdwTurnsInTransit;
|
|
// 679750: using guessed type char sgbSyncCountdown;
|
|
// 679754: using guessed type int dword_679754;
|
|
// 679758: using guessed type char byte_679758;
|
|
// 679759: using guessed type char sgbPacketCountdown;
|
|
// 67975A: using guessed type char sgbThreadIsRunning;
|
|
// 67975C: using guessed type int gdwLargestMsgSize;
|
|
// 679760: using guessed type int gdwNormalMsgSize;
|
|
// 679764: using guessed type int dword_679764;
|
|
|
|
//----- (004410CF) --------------------------------------------------------
|
|
unsigned int __stdcall nthread_handler(void *a1)
|
|
{
|
|
signed int v1; // esi
|
|
int recieved; // [esp+Ch] [ebp-4h]
|
|
|
|
if ( byte_679734 )
|
|
{
|
|
while ( 1 )
|
|
{
|
|
EnterCriticalSection(&sgMemCrit);
|
|
if ( !byte_679734 )
|
|
break;
|
|
nthread_send_and_recv_turn(0, 0);
|
|
if ( nthread_recv_turns(&recieved) )
|
|
v1 = dword_679764 - GetTickCount();
|
|
else
|
|
v1 = 50;
|
|
LeaveCriticalSection(&sgMemCrit);
|
|
if ( v1 > 0 )
|
|
Sleep(v1);
|
|
if ( !byte_679734 )
|
|
return 0;
|
|
}
|
|
LeaveCriticalSection(&sgMemCrit);
|
|
}
|
|
return 0;
|
|
}
|
|
// 679734: using guessed type char byte_679734;
|
|
// 679764: using guessed type int dword_679764;
|
|
|
|
//----- (00441145) --------------------------------------------------------
|
|
void __cdecl nthread_cleanup()
|
|
{
|
|
char *v0; // eax
|
|
|
|
byte_679734 = 0;
|
|
gdwTurnsInTransit = 0;
|
|
gdwNormalMsgSize = 0;
|
|
gdwLargestMsgSize = 0;
|
|
if ( sghThread != (HANDLE)-1 && glpNThreadId != GetCurrentThreadId() )
|
|
{
|
|
if ( !sgbThreadIsRunning )
|
|
LeaveCriticalSection(&sgMemCrit);
|
|
if ( WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1 )
|
|
{
|
|
v0 = GetLastErr();
|
|
TermMsg("nthread3:\n(%s)", v0);
|
|
}
|
|
CloseHandle(sghThread);
|
|
sghThread = (HANDLE)-1;
|
|
}
|
|
}
|
|
// 679734: using guessed type char byte_679734;
|
|
// 679738: using guessed type int gdwTurnsInTransit;
|
|
// 67975A: using guessed type char sgbThreadIsRunning;
|
|
// 67975C: using guessed type int gdwLargestMsgSize;
|
|
// 679760: using guessed type int gdwNormalMsgSize;
|
|
|
|
//----- (004411C4) --------------------------------------------------------
|
|
void __fastcall nthread_ignore_mutex(bool bStart)
|
|
{
|
|
bool v1; // bl
|
|
|
|
v1 = bStart;
|
|
if ( sghThread != (HANDLE)-1 )
|
|
{
|
|
if ( bStart )
|
|
LeaveCriticalSection(&sgMemCrit);
|
|
else
|
|
EnterCriticalSection(&sgMemCrit);
|
|
sgbThreadIsRunning = v1;
|
|
}
|
|
}
|
|
// 67975A: using guessed type char sgbThreadIsRunning;
|
|
|
|
//----- (004411EF) --------------------------------------------------------
|
|
bool __cdecl nthread_has_500ms_passed()
|
|
{
|
|
DWORD v0; // eax
|
|
int v1; // ecx
|
|
|
|
v0 = GetTickCount();
|
|
v1 = v0 - dword_679764;
|
|
if ( gbMaxPlayers == 1 && v1 > 500 )
|
|
{
|
|
dword_679764 = v0;
|
|
v1 = 0;
|
|
}
|
|
return v1 >= 0;
|
|
}
|
|
// 679660: using guessed type char gbMaxPlayers;
|
|
// 679764: using guessed type int dword_679764;
|