#include "MW4AppHeaders.hpp"
//#include "AdeptHeaders.hpp"
//
//
//
// This file is the interface between GameOS and the gosScript generic networking scripts.
//
// When an application comes to rewrite the generic Network scripts it may have to alter
// functions or callbacks in this file.
//
// This file includes GameOS\Network.hpp which exposes more network functions that are
// require to write a lobby or connection screens.
//
//
//
#include <GameOS\Network.hpp>
#include <GosScript\gosScriptHeaders.hpp>
#include <string.h>
#include <stdlib.h>
#include "GameSpy\GameSpy.h"
#include <GameOS\GUNGameList.h>
#include <GameOS\ToolOS.hpp>
#include "network.hpp"
#include "mw4\mwapplication.hpp"
#include "mw4\mw4shell.hpp"
#include "mw4\netparams.h"
#include "rasfuncs.h"
#include "missionlang\resource.h"

const char * const PLAYER_CLAN_NAME_KEY = "Clan Name";

#define SHELLSCRIPTS_PATH "Content\\ShellScripts\\"

//========================================================================
// global functions
//========================================================================
extern bool __stdcall PrepareDefaultServerAdvertisers(void);
extern int __stdcall Mech4CreateGame(char *szGameName, char *szPlayerName, char *szPassword);

//========================================================================
// definitions for callbacks
//========================================================================
#define SCRIPTCALLBACK(func) int __stdcall func( void * instance, int args, void * arg[])
#define SCRIPTVAR_INT(var) int var
#define SCRIPTVAR_STR(var) char * var
#define SCRIPTVAR_ARR(var) char ** var
#define SCRIPTVAR_IRR(var) int * var
#define RESET_NULL_TO_EMPTY(ptr) if ((ptr)==NULL) ptr=EMPTY_STRING
#define FREE_PTR(ptr) if ((void *)ptr) { gos_Free((void *)ptr); (ptr)=NULL; }
#define STRING_SIZE						256
#define NUM_ELEMENTS					20
#define MAX_FILTER_STRING				100
#define MAX_SORT_STRING					100
#define MAX_SORT_TYPE_STRING			20
#define MAX_SORT_COLUMNS				10
#define CONNECTION_FILE_VERSION			0x00010005
#define DEFAULT_SORT_COLUMN				1
#define ARRAY_SIZE(arr)					(sizeof(arr)/sizeof(arr[0]))
#define FixSZString(a)				((a)[sizeof(a)-1]) = 0
//#define USE_GAMESPY

//========================================================================
// global functions
//========================================================================
extern void MechMessageBox(char *szTitle, char *szMessage);
extern bool StringPurgeAndDuplicate(char * &szDest, const char *szSrc);

//========================================================================
// strings for options file
//========================================================================
extern const char OPTIONS_INI[];
extern const char OPTIONS_SECTION[];
extern const char OPTIONS_SERVER_SECTION[];
extern const char OPTION_PLAYERNAME[];
extern const char OPTION_TEAMNAME[];
extern const char OPTION_PASSWORD[];
extern const char OPTION_USEPASSWORD[];
extern const char OPTION_PLAYERICON[];
extern const char OPTION_TEAMICON[];
extern const char OPTION_CONNECTIONNAME[];
extern const char OPTION_ALLOWDECALTRANSFER[];
extern const char OPTION_DEFAULTSERVERNAME[];

//========================================================================
// typedefs
//========================================================================
typedef struct tagCONNECTION
{
	DWORD		dwVersion;
	DWORD		dwChecksum;
	bool		bBrowseGameSpy;
	bool		bBrowseLAN;
	bool		bBrowseGUN;
	int			iNumTCPIP;
	char		szTCPIPAddress[5][30];
	bool		bAlreadyConnected;
	char		szPhonebookEntryName[50];
	char		szConnectionName[100];
	char		szUserName[100];
	char		szPassword[100];
	MWApplication::Bandwidth_Type		bandwidth;
	MWApplication::Connection_Type		connectiontype;
	// mdm - Filter settings for game list
	// set the booleans
	bool		bPingFilterOn;
	bool		bGameTypeFilterOn;
	bool		bPlayerFilterOn;
	bool		bClanFilterOn;
	bool		bActiveFilterOn;
	bool		bAvailableFilterOn;
	int			PingVal;
	char		szGameType[MAX_FILTER_STRING];
    // mdm - Sort settings for game list
    int         sortColumn;
    char        sortColumnName[MAX_SORT_STRING];
    char        sortType[MAX_SORT_TYPE_STRING];
    int         sortDescending;
	
	bool		bCurVerOff;
	bool		bNewVerOff;
	bool		bOldVerOff;
	int			VersionSortVal;
} CONNECTION;


#if 0
typedef struct tagServerOptions
{
	BOOL	bDedicated;
	BOOL	bPasswordProtected;
	BOOL	bPrivateGame;
	BOOL	bDisplayServerMessage;
	int		iMapCycleIndex;
	int		iDelayBetweenMaps;
	BOOL	bAllowJoin;
	int		iAllowJoinTimeLimit;
	BOOL	bAllowCustomDecals;
	BOOL	bFirstPersonPerspectiveOnly;
	BOOL	bUnlimitedAmmo;
	BOOL	bHeat;
	BOOL	bFriendlyFire;
	bSplashDamage
		bImmediateRespawn
		bDeadCanTalk
		bDeadCanSee
		iMaxPlayers
		bUseMapCycle
		bMaxPing
		bAvailable
		bContains1OrMorePlayers
		bGameType
		bContainsPlayerNames
		bContainsPlayersClan
		iGameType
		iMaxPing
		iNumGameTypes
		bChatBoxNeedsUpdating
}
#endif


//========================================================================
// prototypes for the callback functions
//========================================================================
extern SCRIPTCALLBACK(GetReferenceVersion);
extern SCRIPTCALLBACK(GetListSize);
extern SCRIPTCALLBACK(SortGameList);
extern SCRIPTCALLBACK(Select);
extern SCRIPTCALLBACK(GetSelection);
extern SCRIPTCALLBACK(GetGameData);
extern SCRIPTCALLBACK(StartPingServer);
extern SCRIPTCALLBACK(StartPingClient);
extern SCRIPTCALLBACK(ShutdownPing);
extern SCRIPTCALLBACK(GetPing);
extern SCRIPTCALLBACK(GetPlayerList);
extern SCRIPTCALLBACK(UpdateGUNGameList);
extern SCRIPTCALLBACK(GetTotalGameCount);
extern SCRIPTCALLBACK(UpdateGameList);
extern SCRIPTCALLBACK(CancelActivity);
extern SCRIPTCALLBACK(IsGameListUpdating);
extern SCRIPTCALLBACK(SetGameNameDefault);
extern SCRIPTCALLBACK(SetPlayerNameDefault);
extern SCRIPTCALLBACK(CreateSession);
extern SCRIPTCALLBACK(JoinSelected);
extern SCRIPTCALLBACK(Disconnect);
extern SCRIPTCALLBACK(CheckZoneMatch);
extern SCRIPTCALLBACK(CreateBrowsers);
extern SCRIPTCALLBACK(LoadMPConnectionSettings);
extern SCRIPTCALLBACK(SaveMPConnectionSettings);
extern SCRIPTCALLBACK(InitMainMPScreen);
extern SCRIPTCALLBACK(InitNewConnectionScreen);
extern SCRIPTCALLBACK(InitBrowseChoiceScreen);
extern SCRIPTCALLBACK(InitServerListScreen);
extern SCRIPTCALLBACK(AddServer);
extern SCRIPTCALLBACK(UpdateServerList);
extern SCRIPTCALLBACK(RefreshServerInfo);
extern SCRIPTCALLBACK(SelectServer);
extern SCRIPTCALLBACK(JoinGame);
extern SCRIPTCALLBACK(HostGame);
extern SCRIPTCALLBACK(InitConnectionWizard);
extern SCRIPTCALLBACK(TermConnectionWizard);
extern SCRIPTCALLBACK(LaunchDUNWizard);
extern SCRIPTCALLBACK(RemoveConnection);
extern SCRIPTCALLBACK(QuickJoin);
extern SCRIPTCALLBACK(GetHostOptions);
extern SCRIPTCALLBACK(GetFilterOptions);
extern SCRIPTCALLBACK(RefreshGameList);
extern SCRIPTCALLBACK(ChatSend);
extern SCRIPTCALLBACK(FillPlayerRosterMechType);
extern SCRIPTCALLBACK(FillMechTypes);
extern SCRIPTCALLBACK(FillGameSettings);
extern SCRIPTCALLBACK(GetRASEntryUserNameAndPassword);
extern SCRIPTCALLBACK(kldc12);
extern SCRIPTCALLBACK(kldc13);
extern SCRIPTCALLBACK(kldc14);
extern SCRIPTCALLBACK(kldc15);
extern SCRIPTCALLBACK(kldc16);
extern SCRIPTCALLBACK(kldc17);
extern SCRIPTCALLBACK(kldc18);
extern SCRIPTCALLBACK(kldc19);
extern SCRIPTCALLBACK(kldc20);
extern SCRIPTCALLBACK(kldc21);
extern SCRIPTCALLBACK(kldc22);
extern SCRIPTCALLBACK(kldc23);
extern SCRIPTCALLBACK(kldc24);
extern SCRIPTCALLBACK(kldc25);
extern SCRIPTCALLBACK(GetDialupConnectionStatus);
extern SCRIPTCALLBACK(CancelDialup);
extern SCRIPTCALLBACK(PreConnect);
extern SCRIPTCALLBACK(CreateNewPhonebookEntry);
extern SCRIPTCALLBACK(BrowseIPAddress);
extern SCRIPTCALLBACK(GetServerInfo);
extern SCRIPTCALLBACK(GetServerInfoStatus);
extern SCRIPTCALLBACK(ApplyFilters);
extern SCRIPTCALLBACK(SaveFilters);
extern SCRIPTCALLBACK(ClearFIlters);
extern SCRIPTCALLBACK(RevertFilters);
extern SCRIPTCALLBACK(SetFilterParam);
extern SCRIPTCALLBACK(GetFilterParam);
extern SCRIPTCALLBACK(SaveSortInfo);
extern SCRIPTCALLBACK(GetSortInfo);

//========================================================================
// prototypes for callback variables
//========================================================================
extern SCRIPTVAR_INT(gConnectionType);
extern SCRIPTVAR_INT(NumberOfGames);
extern SCRIPTVAR_INT(NumberOfPlayers);
extern SCRIPTVAR_INT(Available);
extern SCRIPTVAR_STR(GameName);
extern SCRIPTVAR_STR(PlayerName);
extern SCRIPTVAR_STR(ServerIPAddress);
extern SCRIPTVAR_STR(NGPassword);
extern SCRIPTVAR_ARR(ListOfPlayers);
extern SCRIPTVAR_ARR(ListOfClans);
extern SCRIPTVAR_ARR(ListOfModems);
extern SCRIPTVAR_ARR(ListOfSerialPorts);
extern SCRIPTVAR_INT(ConnectionIndex);
extern SCRIPTVAR_INT(SortColumnID);
extern SCRIPTVAR_INT(SortDescending);
extern SCRIPTVAR_INT(NumConnections);
extern SCRIPTVAR_INT(AmIOnDialUpDefault);
extern SCRIPTVAR_INT(BrowseGameSpy);
extern SCRIPTVAR_INT(BrowseGUN);
extern SCRIPTVAR_INT(BrowseLAN);
extern SCRIPTVAR_INT(BrowseIPAddresses);
extern SCRIPTVAR_INT(NumIPAddresses);
extern SCRIPTVAR_INT(NumServers);
extern SCRIPTVAR_ARR(ListOfConnections);
extern SCRIPTVAR_ARR(ListOfIPAddresses);
extern SCRIPTVAR_ARR(ListOfServers);
extern SCRIPTVAR_ARR(ServerInfo);
extern SCRIPTVAR_INT(UseDUN);
extern SCRIPTVAR_INT(NumDUN);
extern SCRIPTVAR_ARR(ListOfDUN);
extern SCRIPTVAR_INT(DUNIndex);
extern SCRIPTVAR_STR(DUNUserName);
extern SCRIPTVAR_STR(DUNPassword);
extern SCRIPTVAR_STR(DialupConnectionStatus);
extern SCRIPTVAR_INT(AdvertiseThisGame);
extern SCRIPTVAR_STR(LocalIPAddress);
extern SCRIPTVAR_STR(ReferenceVersion);

extern SCRIPTVAR_INT(iDedicated);
extern SCRIPTVAR_INT(bPasswordProtected);
extern SCRIPTVAR_INT(kldi30);
extern SCRIPTVAR_INT(kldi61);

extern SCRIPTVAR_STR(GameDataID);
extern SCRIPTVAR_STR(SortColumnName);
extern SCRIPTVAR_STR(SortType);
extern SCRIPTVAR_STR(FilterParamVal);
extern SCRIPTVAR_STR(PingTimeStr);
extern SCRIPTVAR_STR(GamePassword);
extern SCRIPTVAR_STR(ErrorMsg);
extern SCRIPTVAR_STR(klds07);
extern SCRIPTVAR_STR(GameSpyAddress);

extern SCRIPTVAR_ARR(ListOfTCPIPAddresses);


//========================================================================
// other externs
//========================================================================
extern void RegisterData(void);
extern void UnRegisterData(void);
extern bool ValidatePath(char *pszData);
extern void SaveConnection(CONNECTION *con);
extern void LoadConnection(CONNECTION *con, char *szFileName, bool bSaveAsDefault);


//////////////////
// Some forward declarations
//////////////////
int PushFiltersToGameList( void );
void SetFilterDefaultsForConnection( CONNECTION * pConnection );



//========================================================================
// GUN key stuff
//========================================================================

//========================================================================
// global variables
//========================================================================
void* NetworkInstance=(void *)NET_SCRIPT_PRIORITY;
DWORD gInSecureGame=0;
static CONNECTION conDefault;

//========================================================================
// GosScript registered variable definitions
//========================================================================
SCRIPTVAR_INT(Available)				= 0;
SCRIPTVAR_INT(gConnectionType)			= -1;
SCRIPTVAR_STR(PlayerName)				= NULL;
SCRIPTVAR_STR(ServerIPAddress)			= NULL;
SCRIPTVAR_STR(GameName)					= NULL;
SCRIPTVAR_STR(NGPassword)				= NULL;
SCRIPTVAR_INT(NumberOfGames)			= 0;
SCRIPTVAR_ARR(ListOfPlayers)			= NULL;
SCRIPTVAR_ARR(ListOfClans)				= NULL;
SCRIPTVAR_INT(NumberOfPlayers)			= 0;
SCRIPTVAR_ARR(ListOfSerialPorts)		= NULL;
SCRIPTVAR_ARR(ListOfModems)				= NULL;
SCRIPTVAR_INT(ConnectionIndex)			= 0;
SCRIPTVAR_INT(SortColumnID)             = -1;
SCRIPTVAR_INT(SortDescending)           = 1;
SCRIPTVAR_INT(NumConnections)			= 0;
SCRIPTVAR_INT(AmIOnDialUpDefault)		= 0;			// 0=no, 1=yes
SCRIPTVAR_INT(BrowseGameSpy)			= 0;
SCRIPTVAR_INT(BrowseGUN)				= 0;
SCRIPTVAR_INT(BrowseLAN)				= 0;
SCRIPTVAR_INT(BrowseIPAddresses)		= 0;
SCRIPTVAR_INT(NumIPAddresses)			= 0;
SCRIPTVAR_INT(NumServers)				= 0;
SCRIPTVAR_ARR(ListOfConnections)		= NULL;
SCRIPTVAR_ARR(ListOfIPAddresses)		= NULL;
SCRIPTVAR_ARR(ListOfServers)			= NULL;
SCRIPTVAR_ARR(ServerInfo)				= NULL;
SCRIPTVAR_INT(UseDUN)					= 0;
SCRIPTVAR_INT(NumDUN)					= 0;
SCRIPTVAR_ARR(ListOfDUN)				= NULL;
SCRIPTVAR_INT(DUNIndex)					= 0;
SCRIPTVAR_STR(DUNUserName)				= NULL;
SCRIPTVAR_STR(DUNPassword)				= NULL;
SCRIPTVAR_STR(DialupConnectionStatus)	= NULL;
SCRIPTVAR_INT(AdvertiseThisGame)		= 1;
SCRIPTVAR_STR(LocalIPAddress)			= NULL;
SCRIPTVAR_STR(ReferenceVersion)         = NULL;

SCRIPTVAR_INT(iDedicated)				= 0;
SCRIPTVAR_INT(bPasswordProtected)		= 0;
SCRIPTVAR_INT(kldi30)					= 0;
SCRIPTVAR_INT(kldi61)					= 0;


SCRIPTVAR_STR(GameDataID)               = NULL;
SCRIPTVAR_STR(SortColumnName)           = NULL;
SCRIPTVAR_STR(SortType)                 = NULL;
SCRIPTVAR_STR(FilterParamVal)           = NULL;
SCRIPTVAR_STR(PingTimeStr)              = NULL;
SCRIPTVAR_STR(GamePassword)				= NULL;
SCRIPTVAR_STR(ErrorMsg)					= NULL;
SCRIPTVAR_STR(klds07)					= NULL;
SCRIPTVAR_STR(GameSpyAddress)			= NULL;

SCRIPTVAR_ARR(ListOfTCPIPAddresses)		= NULL;





char EMPTY_STRING[] = "";

//========================================================================
//	GameList Script API Variables
//========================================================================



struct APIVars
{
	SCRIPTVAR_STR(GameVersion);
	SCRIPTVAR_STR(ServerAddress);
	SCRIPTVAR_STR(ServerPort);
	SCRIPTVAR_STR(ServerName);
	SCRIPTVAR_STR(NumPlayers);
	SCRIPTVAR_STR(MaxPlayers);
	SCRIPTVAR_STR(PasswordStatus);
	SCRIPTVAR_STR(MapType);
	SCRIPTVAR_STR(GameType);

	SCRIPTVAR_STR(ProtocolString);
	SCRIPTVAR_INT(Protocol);
	SCRIPTVAR_STR(Flags);

	SCRIPTVAR_INT(ConnectionType);
	SCRIPTVAR_INT(Dedicated);
	SCRIPTVAR_INT(StatsTracking);
	SCRIPTVAR_INT(PureServer);
	SCRIPTVAR_INT(Locked);

	// internal vars
	char selectID[255];
};


APIVars g_APIVars;

// jcem - start
#include "ctcls.h"
#include "ctcl.h"

extern bool g_bCOOP; // COin OPeration
extern SCRIPTCALLBACK(CancelDialup);
extern SCRIPTCALLBACK(LoadMPConnectionSettings);
extern SCRIPTCALLBACK(InitConnectionWizard);
extern SCRIPTCALLBACK(PreConnect);
// jcem - end
//========================================================================
// This callback indicates the current size of the game list.
//========================================================================
SCRIPTCALLBACK(GetListSize)
{
	return (ServerBrowser::GetGameList())->GetIndexedView()->GetCount();
}

SCRIPTCALLBACK(GetReferenceVersion)
{
    int retval = 0;

    Browse::GameList::Lock();
    if ( ServerBrowser::GetGameList() )
    {
        Browse::GameList * pGameList = ServerBrowser::GetGameList();
        if ( pGameList )
        {
            const char * pRefID = pGameList->GetReferenceGameID();
            if ( pRefID )
            {
                // get version from reference game
                const char * pVersion = pGameList->GetDataField( pRefID, GAMELIST_KEY_PRODUCT_VERSION);

                if ( pVersion )
                {
                    strncpy(ReferenceVersion, pVersion, STRING_SIZE-1);
                    ReferenceVersion[STRING_SIZE-1] = 0;
                    retval = 1;
                    goto CLEANUP;
                }
            }
        }
    }

    // if we get here it is because we don't know what the current reference version is

    ReferenceVersion[0] = 0;

CLEANUP:
    Browse::GameList::Unlock();
    return retval;
}


//========================================================================
// This callback instructs the internal game list to sort itself according
// to the column specified.  If sortDescending is non-zero, then the list
// will be sorted in descending order.  Otherwise, the list will be sorted
// in ascending order.
//========================================================================
SCRIPTCALLBACK(SortGameList)
{
	if ( !ServerBrowser::GetGameList() ||
         !ServerBrowser::GetGameList()->GetIndexedView() )
    {
        return 0;
    }


	if (( args < 4 ) || ( args > 5 ))
	{
		PAUSE(( "Invalid number of arguments (%d) to SortGameList().", args ));
		return 0;
	}

    int columnID = (int) arg[0];
    if ( columnID < 0 || columnID > 9999 )
    {
        columnID = *( (int *) arg[0]);
        if ( columnID < 0 || columnID > 9999 )
        {
            return -1;
        }
    }

	const char * column = *( (char **) arg[1] );
	const char * sortType = *( (char **)arg[2] );
	int sortDescending =  (int)(arg[3]); // literals aren't pointers
    if ( sortDescending < 0 || sortDescending > 1 )
    {
        sortDescending = *( (int *) arg[3] );
    }

	Browse::IndexedTableView::VersionOrderType versionOrder = Browse::IndexedTableView::NO_VERSION;
	if ( args == 5 )
	{
		if ((int)(arg[4]) != 0)
		{
			switch (conDefault.VersionSortVal)
			{
			case 0:
				versionOrder = Browse::IndexedTableView::NO_VERSION;
				break;
			case 1:
				versionOrder = Browse::IndexedTableView::CUR_OLD_NEW_VERSION;
				break;
			case 2:
				versionOrder = Browse::IndexedTableView::CUR_NEW_OLD_VERSION;
				break;
			case 3:
				versionOrder = Browse::IndexedTableView::OLD_CUR_NEW_VERSION;
				break;
			case 4:
				versionOrder = Browse::IndexedTableView::OLD_NEW_CUR_VERSION;
				break;
			case 5:
				versionOrder = Browse::IndexedTableView::NEW_OLD_CUR_VERSION;
				break;
			case 6:
				versionOrder = Browse::IndexedTableView::NEW_CUR_OLD_VERSION;
				break;
			}
		}
		Verify(versionOrder <= Browse::IndexedTableView::TOTAL_VERSION);
	}

	Browse::IndexedTableView::SortOrderType sortEnum;

	// parse sort order
	if ( !strcmp(sortType, "numeric") )
	{
		if ( sortDescending )
		{
			sortEnum = Browse::IndexedTableView::DESCENDING_NUMERIC;
		}
		else
		{
			sortEnum = Browse::IndexedTableView::ASCENDING_NUMERIC;
		}
	}
	else
	{
		if ( sortDescending )
		{
			sortEnum = Browse::IndexedTableView::DESCENDING_ALPHABETICAL;
		}
		else
		{
			sortEnum = Browse::IndexedTableView::ASCENDING_ALPHABETICAL;
		}
	}

    // store the sort data in the current connection
    strncpy(conDefault.sortType, sortType, MAX_SORT_TYPE_STRING-1);
    conDefault.sortType[MAX_SORT_TYPE_STRING-1] = 0;
    strncpy(conDefault.sortColumnName, column, MAX_SORT_STRING-1);
    conDefault.sortColumnName[MAX_SORT_STRING-1] = 0;
    conDefault.sortDescending = sortDescending;
    conDefault.sortColumn = columnID;

	return (int) ServerBrowser::GetGameList()->GetIndexedView()->Sort(column, sortEnum, versionOrder);
}

//========================================================================
// This callback selects the row at the specified index.
// The selection serves as a reference point for the client application when
// the server list is updated (through sorting or new server updates, for example).
// See GetSelection() below.
//========================================================================
SCRIPTCALLBACK(Select)
{
    int retval = -1;

	if ( args != 1 )
	{
		PAUSE(( "Invalid number of arguments (%d) to Select().", args ));
		return 0;
	}

    int selIndex = (int)arg[0];
    if ( selIndex < -1 || selIndex > 9999 )
    {
        // assume its a pointer if its out of the above range
    	selIndex = *(int *)(arg[0]);
    }


	//
	// make sure we have a valid game list
	//
	if (ServerBrowser::GetGameList() == NULL)
		return -1;
	ServerBrowser::GetGameList()->Lock();
	Browse::IndexedTableView * indexView = ServerBrowser::GetGameList()->GetIndexedView();
	gosASSERT(indexView);


	if ( selIndex < 0 || selIndex >= indexView->GetCount() )
	{
//		PAUSE(( "Invalid select index %d, should be >= 0 and <= %d", selIndex, indexView->GetCount() ));
		goto CLEANUP;
	}

	char * gameID;

	if ( indexView->GetIndex( selIndex, &gameID ) == false )
	{
		PAUSE(( "Unable to find gameID for select index %d.", selIndex ));
		goto CLEANUP;
	}

    if ( indexView->SetSelection( gameID ) == false )
    {
        PAUSE(( "Error setting selectio to gameid %s.\n", gameID ));
        goto CLEANUP;
    }


	strcpy(g_APIVars.selectID, gameID);
    retval = 1;

CLEANUP:
	ServerBrowser::GetGameList()->Unlock();
	return retval;
}


//========================================================================
// This callback returns an integer indicating the index of the currently
// selected row.  This callback can be used to keep a specific game server
// in the client's view visible after a call to Update GUNGameList() or
// SortGameList().  By calling Select() and specifying the game server you
// want to keep track of, you can later call GetSelection() to obtain the
// current index of that game server in the list.
//========================================================================
SCRIPTCALLBACK(GetSelection)
{
	int index=0;
	Browse::GameList * pGameList;

	pGameList = ServerBrowser::GetGameList();

	if (pGameList)
		index = pGameList->GetIndexedView()->GetIndexFromID( g_APIVars.selectID );

	return index;
}

////////////////////////////////////////////////////////////////////////////////////////
//  SetFilterDefaultsForConnection()
//  Purpose:
//       Set the default values for a connection's filter settings.
//
//  Parameters:
//       [pConnection] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100400  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
void SetFilterDefaultsForConnection( CONNECTION * pConnection )
{
    gosASSERT(pConnection);
	pConnection->bPingFilterOn	= 0;
	pConnection->bGameTypeFilterOn= 0;
	pConnection->bPlayerFilterOn	= 0;
	pConnection->bClanFilterOn	= 0;
	pConnection->bActiveFilterOn	= 0;
	pConnection->bAvailableFilterOn	= 0;
	pConnection->PingVal			= 100;
	strcpy(pConnection->szGameType,			"");
	pConnection->bCurVerOff = 0;
	pConnection->bNewVerOff = 0;
	pConnection->bOldVerOff = 0;
	pConnection->VersionSortVal = 1;
}


////////////////////////////////////////////////////////////////////////////////////////
//  SetSortDefaultsForConnection()
//  Purpose:
//       Set the sorting defaults for the indicated connection structure.
//
//  Parameters:
//       [pConnectino] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100500  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
void SetSortDefaultsForConnection( CONNECTION * pConnection )
{
    gosASSERT(pConnection);
    pConnection->sortColumn = -1;
    pConnection->sortColumnName[0] = 0;
    strcpy(pConnection->sortType, "alphabetical");
    pConnection->sortDescending = 1;
}

////========================================================================
////========================================================================
//SCRIPTCALLBACK(LockServer)
//{
//	if (kldi59)
//		ServerAdvertiser::SetFlagsAllAdvertisers(ServerAdvertiser::GetFlagsAllAdvertisers() | NETFLAGS_LOCKED_FLAG);
//	else
//		ServerAdvertiser::SetFlagsAllAdvertisers(ServerAdvertiser::GetFlagsAllAdvertisers() & ~NETFLAGS_LOCKED_FLAG);
//
//	return 0;
//}

//========================================================================
//========================================================================
SCRIPTCALLBACK(InitConnectionWizard)
{
	NumDUN = RAS::GetListOfEntries(ListOfDUN);

	if (ConnectionIndex < NumConnections)
	{
		LoadConnection(&conDefault, ListOfConnections[ConnectionIndex], true);

		BrowseGameSpy		= conDefault.bBrowseGameSpy;
		BrowseGUN			= conDefault.bBrowseGUN;
		BrowseLAN			= conDefault.bBrowseLAN;
		BrowseIPAddresses	= conDefault.iNumTCPIP;
		kldi61				= conDefault.bAlreadyConnected;


		for (int i=0 ; i<5 ; i++)
			StringPurgeAndDuplicate(ListOfTCPIPAddresses[i],		conDefault.szTCPIPAddress[i]);
		StringPurgeAndDuplicate(klds07,							conDefault.szConnectionName);
		StringPurgeAndDuplicate(DUNUserName,					conDefault.szUserName);
		StringPurgeAndDuplicate(DUNPassword,					conDefault.szPassword);

		for (DUNIndex=0 ; DUNIndex<NumDUN ; DUNIndex++)
		{
			if (!strcmp(ListOfDUN[DUNIndex], conDefault.szPhonebookEntryName))
				break;
		}

		if (DUNIndex == NumDUN)
			DUNIndex = 0;
	}
	else
	{
		if (NumConnections == 0)
		{
			// set up default values
			BrowseGameSpy				= 0;
			BrowseGUN					= CheckForZoneMatch();
			BrowseLAN					= 0;
			BrowseIPAddresses			= 0;
			kldi61						= 1;
			ListOfTCPIPAddresses[0][0]	= 0;
			DUNIndex					= 0;
			klds07[0]					= 0;
			conDefault.connectiontype	= MWApplication::Modem;
			conDefault.bandwidth		= MWApplication::c_14_4kbps;
            SetFilterDefaultsForConnection( &conDefault );
            SetSortDefaultsForConnection( &conDefault );

			for (int i=0 ; i<5 ; i++)
				strcpy(conDefault.szTCPIPAddress[i],	ListOfTCPIPAddresses[i]);
			strcpy(conDefault.szPhonebookEntryName,	ListOfDUN[DUNIndex]);
			strcpy(conDefault.szUserName,			DUNUserName);
			strcpy(conDefault.szPassword,			DUNPassword);
		}

		//
		// now, fill in the next connection name with a good default name
		//
		if (true)
		{
			char szConnectionName[300];
			char szConnectionFile[300];

			strcpy(szConnectionName, Application::GetInstance()->GetLocString(IDS_NETUI_DEFAULT_CONNECTION_NAME));
			strcpy(szConnectionFile, "m4c");
			strcat(szConnectionFile, szConnectionName);
			strcat(szConnectionFile, ".m4c");

			int i=0;

			while (gos_DoesFileExist(szConnectionFile))
			{
				i++;

				sprintf(szConnectionName, "%s %d", Application::GetInstance()->GetLocString(IDS_NETUI_DEFAULT_CONNECTION_NAME), i);
				strcpy(szConnectionFile, "m4c");
				strcat(szConnectionFile, szConnectionName);
				strcat(szConnectionFile, ".m4c");
			}

			StringPurgeAndDuplicate(klds07, szConnectionName);
		}
	}

	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(TermConnectionWizard)
{
	//
	// here's where I save the connection
	//

	conDefault.bBrowseGameSpy		= !!BrowseGameSpy;
	conDefault.bBrowseGUN			= !!BrowseGUN;
	conDefault.bBrowseLAN			= !!BrowseLAN;
	conDefault.iNumTCPIP			= BrowseIPAddresses;
	conDefault.bAlreadyConnected	= !!kldi61;
	conDefault.connectiontype		= conDefault.connectiontype;
	conDefault.bandwidth			= conDefault.bandwidth;
	conDefault.dwVersion			= CONNECTION_FILE_VERSION;


	for (int i=0 ; i<5 ; i++)
		strcpy(conDefault.szTCPIPAddress[i],	ListOfTCPIPAddresses[i]);
	strcpy(conDefault.szPhonebookEntryName,	ListOfDUN[DUNIndex]);
	strcpy(conDefault.szConnectionName,		klds07);
	strcpy(conDefault.szUserName,			DUNUserName);
	strcpy(conDefault.szPassword,			DUNPassword);

	if (!ValidatePath(conDefault.szConnectionName))
		return -1;

	if (conDefault.szConnectionName[0])
		SaveConnection(&conDefault);

	return 0;
}

//========================================================================
//========================================================================
bool ValidatePath(char *pszData)
{
	char *pszTmp;
	//
	//Special case the name "NUL", it doesn't return a failure code for CreateDirectory()
	//or CreateFile(), even though no such folder\file gets created!
	//
	if (0 == _strcmpi(pszData, "NUL"))
	{
		return false;
	}

	pszTmp = pszData;
	while (*pszTmp != '\0')
	{
		switch (*pszTmp)
		{
		case '\"':
		case  '*':
		case  '?':
		case '\\':
		case  '/':
		case  ':':
		case  '<':
		case  '>':
		case  '|':
			return false;
		}

		pszTmp++;
	}
	return true;
}

//========================================================================
//========================================================================
void SaveConnection(CONNECTION *con)
{
	char szFileName[256];

	strcpy(szFileName, "m4c");
	strcat(szFileName, con->szConnectionName);
	strcat(szFileName, ".m4c");

	if (true)
	{
		HGOSFILE hf = NULL;

		gos_OpenFile(&hf, szFileName, READWRITE);
		if (hf)
		{
			gos_WriteFile(hf, con, sizeof(*con));
			gos_CloseFile(hf);
		}

		LoadConnection(con, con->szConnectionName, true);
	}
}

//========================================================================
//========================================================================
void LoadConnection(CONNECTION *con, char *szConnectionName, bool bSaveAsDefault)
{
	if (szConnectionName==NULL || szConnectionName[0]==0)
		return;

	char szFileName[256];

	strcpy(szFileName, "m4c");
	strcat(szFileName, szConnectionName);
	strcat(szFileName, ".m4c");

	if (true)
	{
		HGOSFILE hf = NULL;

		gos_OpenFile(&hf, szFileName, READONLY);
		if (hf)
		{
			gos_ReadFile(hf, con, sizeof(*con));
			gos_CloseFile(hf);
		}
	}

	//
	// save the connection
	//
	if (bSaveAsDefault)
	{
		NotationFile startup_ini(OPTIONS_INI, NotationFile::Standard, true);
		Page *page = startup_ini.SetPage(OPTIONS_SECTION);

		page->SetEntry(OPTION_CONNECTIONNAME, szConnectionName);

		startup_ini.Save();
	}


}

//========================================================================
//========================================================================
SCRIPTCALLBACK(LaunchDUNWizard)
{
	return 0;
}

//========================================================================
// This callback provides information about the game server located at
// the specified index.  The callback sets the following script
// variables, which represent the standard GUN server info fields:
//
//  $$GameID$$
//	$$GameVersion$$
//	$$ServerAddress$$
//	$$ServerPort$$
//	$$ServerName$$
//	$$NumPlayers$$
//	$$MaxPlayers$$
//	$$PasswordStatus$$
//	$$MapType$$
//	$$GameType$$
//========================================================================
SCRIPTCALLBACK(GetGameData)
{
	if ( args != 1 )
	{
		PAUSE(( "Invalid number of arguments (%d) to GetGameData callback.", args ));
		return 0;
	}

	Browse::GameList *pGameList = ServerBrowser::GetGameList();

	if (pGameList == NULL)
		return 0;

	pGameList->Lock();

	int index = *((int *) arg[0]);

	char * gameID;
	if ( pGameList->GetIndexedView()->GetIndex(index, &gameID) == false )
	{
		pGameList->Unlock();
		return 0;
	}

    strcpy(GameDataID, gameID);
	g_APIVars.GameVersion		= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_PRODUCT_VERSION);
	g_APIVars.ServerAddress		= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_SERVER_ADDRESS);
	g_APIVars.ServerPort		= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_SERVER_PORT);
	g_APIVars.ServerName		= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_SERVER_NAME);
	g_APIVars.NumPlayers		= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_NUM_PLAYERS);
	g_APIVars.MaxPlayers		= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_MAX_PLAYERS);
	g_APIVars.PasswordStatus	= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_PASSWORD_PROTECTED);
	g_APIVars.MapType			= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_MAP_TYPE);
	g_APIVars.GameType			= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_GAME_TYPE);
	g_APIVars.ProtocolString	= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_PROTOCOL);
	g_APIVars.Flags				= (char *)pGameList->GetDataField( gameID, GAMELIST_KEY_FLAGS);

	if (g_APIVars.ProtocolString)
		g_APIVars.Protocol		= atoi(g_APIVars.ProtocolString);
	else
		g_APIVars.Protocol		= -1;

	if (g_APIVars.Flags)
	{
		g_APIVars.ConnectionType	= atoi(g_APIVars.Flags) & NETFLAGS_CONNECTION_TYPE_MASK;
		g_APIVars.Dedicated			= !!(atoi(g_APIVars.Flags) & NETFLAGS_DEDICATED_FLAG);
		g_APIVars.StatsTracking		= !!(atoi(g_APIVars.Flags) & NETFLAGS_STATSTRACKING_FLAG);
		g_APIVars.PureServer		= !!(atoi(g_APIVars.Flags) & NETFLAGS_PURESERVER_FLAG);
		g_APIVars.Locked			= !!(atoi(g_APIVars.Flags) & NETFLAGS_LOCKED_FLAG);
	}
	else
	{
		g_APIVars.ConnectionType	= 0;
		g_APIVars.Dedicated			= 0;
		g_APIVars.StatsTracking		= 0;
		g_APIVars.PureServer		= 0;
		g_APIVars.Locked			= 0;
	}


	RESET_NULL_TO_EMPTY(g_APIVars.GameVersion);
	RESET_NULL_TO_EMPTY(g_APIVars.ServerAddress);
	RESET_NULL_TO_EMPTY(g_APIVars.ServerPort);
	RESET_NULL_TO_EMPTY(g_APIVars.ServerName);
	RESET_NULL_TO_EMPTY(g_APIVars.NumPlayers);
	RESET_NULL_TO_EMPTY(g_APIVars.MaxPlayers);
	RESET_NULL_TO_EMPTY(g_APIVars.PasswordStatus);
	RESET_NULL_TO_EMPTY(g_APIVars.MapType);
	RESET_NULL_TO_EMPTY(g_APIVars.GameType);

	pGameList->Unlock();
	return 1;
}

////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Obtain the current sort information from the connection.  This fills in the
//       SortColumName, SortType, SortIsDescending, and SortColumnID registered vars
//       for use by the script.
//
//  Parameters:
//       [GetSortInfo] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100600  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(GetSortInfo)
{
    strcpy(SortType, conDefault.sortType);
    strcpy(SortColumnName, conDefault.sortColumnName);
    SortColumnID = conDefault.sortColumn;
    SortDescending = conDefault.sortDescending;

    return 1;
}

////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Saves the sort order information for all of the columns.  Also saves which
//       column is currently sorted.
//
//  Parameters:
//       [SaveSortInfo] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100500  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(SaveSortInfo)
{
    SaveConnection( &conDefault );
    return 1;
}

//========================================================================
// Clear all filters on the game list.
//========================================================================
SCRIPTCALLBACK(ClearFilters)
{
	Browse::TableItemFilter * filter =
		ServerBrowser::GetGameList()->GetIndexedView()->GetFilter();

	if ( !filter )
	{
		return -1;
	}
	filter->ClearAllFilters();
    // jcem begin
    filter = NULL;
    ServerBrowser::GetGameList()->GetIndexedView()->SetFilter( *filter );
    // jcem end



	return 0;
}


////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Save the connection to disk, thus saving the filter values.
//
//  Parameters:
//       [SaveFilters] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100400  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(SaveFilters)
{
    // Save the connection to disk so that the filter settings are stored.
    SaveConnection( &conDefault );
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Reverts the filter settings by reloading the connection from disk.
//
//  Parameters:
//       [RevertFilters] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100400  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(RevertFilters)
{
	LoadConnection(&conDefault, ListOfConnections[ConnectionIndex], true);
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Pushes the filter settings currently found in the connection to the game list.
//
//  Parameters:
//       [ApplyFilters] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100400  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(ApplyFilters)
{
    return PushFiltersToGameList();
}

////////////////////////////////////////////////////////////////////////////////////////
//  PushFiltersToGameList()
//  Purpose:
//       Pushes the condefault filter settings out to the filter that is being used
//       for the game list.  This is the function to call when the user click's ok and
//       wants to accept the changes made to the filter settings.
//
//  Parameters:
//       [void] :
//
//  Returns:  int
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100400  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
int PushFiltersToGameList( void )
{
	// push the filter variables out to the gamelist filter
	Browse::GameList * pGameList = ServerBrowser::GetGameList();

	if ( !pGameList )
	{
		PAUSE(( "Invalid to call ApplyFilters when no game list has been created." ));
		return -1;
	}

	gosASSERT(pGameList->GetIndexedView());

	Browse::GameListFilter * pFilter = (Browse::GameListFilter *)
			pGameList->GetIndexedView()->GetFilter();


	if ( !pFilter )
	{
		PAUSE(( "ApplyFilters called but no GameListFilter found on indexed view." ));
		return -1;
	}

	// set the booleans
	pFilter->EnablePingFilter( conDefault.bPingFilterOn ? true : false );
	pFilter->EnableGameTypeFilter( conDefault.bGameTypeFilterOn ? true : false );
	pFilter->EnablePlayerFilter( conDefault.bPlayerFilterOn ? true : false );
	pFilter->EnableClanFilter( conDefault.bClanFilterOn ? true : false );
	pFilter->EnableActiveFilter( conDefault.bActiveFilterOn ? true : false );
	pFilter->EnableAvailableFilter( conDefault.bAvailableFilterOn ? true : false );
	pFilter->EnableCurVerOffFilter( conDefault.bCurVerOff ? true : false );
	pFilter->EnableNewVerOffFilter( conDefault.bNewVerOff ? true : false );
	pFilter->EnableOldVerOffFilter( conDefault.bOldVerOff ? true : false );

	// set the values
	pFilter->SetPingFilter( 0, conDefault.PingVal );
	pFilter->SetGameTypeFilter( conDefault.szGameType );

	Browse::IndexedTableView::VersionOrderType versionOrder = Browse::IndexedTableView::NO_VERSION;
	switch (conDefault.VersionSortVal)
	{
	case 0:
		versionOrder = Browse::IndexedTableView::NO_VERSION;
		break;
	case 1:
		versionOrder = Browse::IndexedTableView::CUR_OLD_NEW_VERSION;
		break;
	case 2:
		versionOrder = Browse::IndexedTableView::CUR_NEW_OLD_VERSION;
		break;
	case 3:
		versionOrder = Browse::IndexedTableView::OLD_CUR_NEW_VERSION;
		break;
	case 4:
		versionOrder = Browse::IndexedTableView::OLD_NEW_CUR_VERSION;
		break;
	case 5:
		versionOrder = Browse::IndexedTableView::NEW_OLD_CUR_VERSION;
		break;
	case 6:
		versionOrder = Browse::IndexedTableView::NEW_CUR_OLD_VERSION;
		break;
	}
	Verify(versionOrder <= Browse::IndexedTableView::TOTAL_VERSION);

	// apply the filter!
	pGameList->GetIndexedView()->Filter( versionOrder );

	return 0;
}



////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Gets the filter parameter requested.  If the parameter value is an integer,
//       it is returned as the value of the function.  If the parameter is a string
//       value, it is returned in the registered variable FilterParamVal.
//
//  Parameters:
//       [GetFilterParam] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100500  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(GetFilterParam)
{
    if ( args != 1 )
    {
        return -1;
    }

    char * param = (char *) arg[0];

    if ( !param ) return -1;

    if ( !stricmp(param, "pingon") )
    {
        return conDefault.bPingFilterOn;
    }
    else if ( !stricmp(param, "gametypeon") )
    {
        return conDefault.bGameTypeFilterOn;
    }
    else if ( !stricmp(param, "playeron") )
    {
        return conDefault.bPlayerFilterOn;
    }
    else if ( !stricmp(param, "clanon") )
    {
        return conDefault.bClanFilterOn;
    }
    else if ( !stricmp(param, "activeon") )
    {
        return conDefault.bActiveFilterOn;
    }
    else if ( !stricmp(param, "availableon") )
    {
        return conDefault.bAvailableFilterOn;
    }
    else if ( !stricmp(param, "curveroff")  )
    {
        return conDefault.bCurVerOff;
    }
    else if ( !stricmp(param, "oldveroff")  )
    {
        return conDefault.bOldVerOff;
    }
    else if ( !stricmp(param, "newveroff")  )
    {
        return conDefault.bNewVerOff;
    }
	else if ( !stricmp(param, "versionsort") )
	{
		return conDefault.VersionSortVal;
	}
    else if ( !stricmp(param, "ping")  )
    {
        return conDefault.PingVal;
    }
    else if ( !stricmp(param, "gametype") )
    {
        strcpy(FilterParamVal, conDefault.szGameType);
    }
    else
    {
        return -1; // error
    }
    return 0; // success
}


////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Set a filter property.  First param is the name of the property to set, and
//       the second param is a string indicating the value of the parameter.
//
//  Parameters:
//       [SetFilterParam] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          100400  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(SetFilterParam)
{
    if ( args != 2 )
    {
        return -1;
    }

    char * param = (char *) arg[0];
    int iVal = (int) arg[1];
    char * val = NULL;

    if ( iVal < -2 ||
         iVal > 9999 )
    {
        val = *(char **) arg[1];
        iVal = atoi(val);
    }

    if ( !stricmp(param, "pingon") )
    {
        conDefault.bPingFilterOn = !!iVal;
    }
    else if ( !stricmp(param, "gametypeon") )
    {
        conDefault.bGameTypeFilterOn = !!iVal;
    }
    else if ( !stricmp(param, "playeron") )
    {
        conDefault.bPlayerFilterOn = !!iVal;
    }
    else if ( !stricmp(param, "clanon") )
    {
        conDefault.bClanFilterOn = !!iVal;
    }
    else if ( !stricmp(param, "activeon") )
    {
        conDefault.bActiveFilterOn = !!iVal;
    }
    else if ( !stricmp(param, "availableon") )
    {
        conDefault.bAvailableFilterOn = !!iVal;
    }
    else if ( !stricmp(param, "curveroff")  )
    {
        conDefault.bCurVerOff = !!iVal;
    }
    else if ( !stricmp(param, "oldveroff")  )
    {
        conDefault.bOldVerOff = !!iVal;
    }
    else if ( !stricmp(param, "newveroff")  )
    {
        conDefault.bNewVerOff = !!iVal;
    }
	else if ( !stricmp(param, "versionsort")  )
	{
		if ( iVal < 1 || iVal > 6 )
		{
            PAUSE(( "Invalid version sorting filter setting '%s'.  Should be a number between 1 and 6.\n", val ? val : "NULL" ));
            return -1;
		}
		conDefault.VersionSortVal = iVal;
	}
    else if ( !stricmp(param, "ping")  )
    {
        if ( iVal < 0 || iVal > 9999 )
        {
            PAUSE(( "Invalid ping filter setting '%s'.  Should be a number between 0 and 1000.\n", val ? val : "NULL" ));
            return -1;
        }
        conDefault.PingVal = iVal;
    }
    else if ( !stricmp(param, "gametype") )
    {
        if ( !val )
        {
            PAUSE(( "Val is NULL inside SetFilterParam.\n" ));
            return -1;
        }

        strncpy(conDefault.szGameType, val, MAX_FILTER_STRING-1);
        conDefault.szGameType[MAX_FILTER_STRING-1] = 0;
    }
    else
    {
        return -1; // error
    }
    return 0; // success
}


//========================================================================
// Start the ping server.  This should only be invoked by the game when
// it is hosting.
//========================================================================
SCRIPTCALLBACK(StartPingServer)
{
	return Browse::GameList::StartPingServer();
}

//========================================================================
// Start the ping client.  This will start pinging any games that are
// in ServerBrowser::GetGameList().
//========================================================================
SCRIPTCALLBACK(StartPingClient)
{
	return Browse::GameList::StartPingClient( ZONE_PING_INTERVAL );
}

//========================================================================
// Shutdown the ping service.  THis should be called when joining a game.
// THis should also be called to shutdown client pinging before calling
// StartPingServer() when hosting a game.
//========================================================================
SCRIPTCALLBACK(ShutdownPing)
{
	Browse::GameList::ShutdownPing();
	return 1;
}

//========================================================================
// returns the ping time of the game server at the indicated index.
//========================================================================
SCRIPTCALLBACK(GetPing)
{
    int retval = -1;
    int index = -1;

	if ( args != 1 )
	{
        return retval;
	}

    Browse::GameList::Lock();
	if ( !ServerBrowser::GetGameList() )
	{
		goto CLEANUP;
	}

	index = *((int *) arg[0]);

	if ( index > ServerBrowser::GetGameList()->GetIndexedView()->GetCount() )
	{
		index = (unsigned int) atoi( (char *) arg[0] );
		if ( index > ServerBrowser::GetGameList()->GetIndexedView()->GetCount() )
		{
            goto CLEANUP;
		}
	}

    retval = ServerBrowser::GetGameList()->GetPing(index);

    if ( retval < 0 )
    {
        strcpy(PingTimeStr, "-");
    }
    else if ( retval == 0 )
    {
        strcpy(PingTimeStr, "N/A");
    }
    else
    {
        sprintf(PingTimeStr, "%d", retval);
    }

CLEANUP:

    Browse::GameList::Unlock();
    return retval;
}

// mdm - modified so that if -1 is the index, then there are two args
// expected and the second is expected to be a gameid
//========================================================================
//========================================================================
SCRIPTCALLBACK(GetPlayerList)
{
	int i;
	NumberOfPlayers = 0;
	char * gameID = 0;
	Browse::PlayerList * pList = 0;
	int count = 0;
	Browse::IndexedTableView * indexView = 0;

    if ( args != 1 && args != 2)
    {
        return -1;
    }


	ServerBrowser::GetGameList()->Lock(); // enter crit section

    if ( (int)arg[0] == -1 )
    {
        gameID = *((char **)arg[1]);
    }
    else
    {
        int index = *((int *) arg[0]);

        if ( ServerBrowser::GetGameList() == NULL )
        {
            ServerBrowser::GetGameList()->Unlock(); // yuck.
            return -1;
        }
        indexView = ServerBrowser::GetGameList()->GetIndexedView();

        if ( indexView->GetIndex( index, &gameID ) == false )
        {
            ServerBrowser::GetGameList()->Unlock(); // yuck.
            return -1;
        }
    }

	if ( !gameID )
	{
		// not able to find the game named in GameName variable
		goto CLEANUP;
	}

	pList = ServerBrowser::GetGameList()->GetPlayerList( gameID );
	const char *p;

	int iNumPlayers;
	int iNumBots;
	int iMaxPlayers;

	p = ServerBrowser::GetGameList()->GetDataField(gameID, GAMELIST_KEY_NUM_PLAYERS);
	iNumPlayers = (p) ? atoi(p) : 0;
	if (iNumPlayers > 16)
		iNumPlayers = 16;

	p = ServerBrowser::GetGameList()->GetDataField(gameID, GAMELIST_KEY_NUM_BOTS);
	iNumBots = (p) ? atoi(p) : 0;
	if (iNumBots > iNumPlayers)
		iNumBots = iNumPlayers;

	p = ServerBrowser::GetGameList()->GetDataField(gameID, GAMELIST_KEY_MAX_PLAYERS);
	iMaxPlayers = (p) ? atoi(p) : 0;

	indexView = pList->GetIndexedView();

	for (i = 0; i < indexView->GetCount(); i++)
	{
		char * playerID;

		if ( indexView->GetIndex( i, &playerID ) == false )
		{
			PAUSE(( "Unable to find playerID for index %d", i ));
			continue;
		}

		const char * playerName = pList->GetDataField(playerID, PLAYERLIST_KEY_PLAYER_NAME );
		if ( playerName )
		{
			strncpy(ListOfPlayers[count], playerName, 19);
			ListOfPlayers[count][19] = 0;

			// mdm - clan name support - temporary
			const char * clanName = pList->GetDataField(playerID, PLAYERLIST_KEY_CLAN_NAME );
			ListOfClans[count][0] = 0;
			if ( clanName )
			{
				strncpy(ListOfClans[count], clanName, 19);
				ListOfClans[count][19] = 0;
			}

			count++;
		}
		if (count >= 16)
		{
			break;
		}
	}
	for ( ; i < (iNumPlayers-iNumBots) ; i++)
	{
		strncpy(ListOfPlayers[count], "Unknown Human", 19);
		ListOfPlayers[count][19] = 0;

		strncpy(ListOfClans[count], "Unknown Clan", 19);
		ListOfClans[count][19] = 0;

		count++;
		
		if (count >= 16)
		{
			break;
		}
	}
	for ( ; i < iNumPlayers ; i++)
	{
		strncpy(ListOfPlayers[count], "Unknown Bot", 19);
		ListOfPlayers[count][19] = 0;

		strncpy(ListOfClans[count], "Unknown Clan", 19);
		ListOfClans[count][19] = 0;

		count++;
		
		if (count >= 16)
		{
			break;
		}
	}


	if (count > 16)
		count = 16;

	NumberOfPlayers = count;

CLEANUP:
	ServerBrowser::GetGameList()->Unlock(); // leave critical section

	return 0;
}

//========================================================================
// Returns the total number of games known to exist, even those that
// are currently filtered out of the list.
//========================================================================
SCRIPTCALLBACK(GetTotalGameCount)
{
    if ( ServerBrowser::GetGameList() == NULL )
    {
        return 0;
    }
    return ServerBrowser::GetGameList()->GetTotalCount();
}

//========================================================================
// Update the list of GUN games.  This should only be called by
// the GUNTech scripts, LAN scripts should invoke UpdateGameList.
//========================================================================
SCRIPTCALLBACK(UpdateGUNGameList)
{
	if (ServerBrowser::GetGameList() == NULL)
		return 0;


	ServerBrowser::GetGameList()->Lock(); // enter crit section

	Browse::IndexedTableView * indexView = ServerBrowser::GetGameList()->GetIndexedView();
	gosASSERT(indexView);
	NumberOfGames = indexView->GetCount();
	ServerBrowser::GetGameList()->Unlock(); // leave crit. section

	return 1;

}


////========================================================================
//// Update the list of games - if GunTech don't use this, use
//// UpdateGUNGameList instead.
////========================================================================
//SCRIPTCALLBACK(UpdateGameList)
//{
//	NumberOfGames=(DWORD)gos_NetInformation( gos_NumberOfGames );
//
//	if( NumberOfGames>19 )
//		NumberOfGames=19;
//
//	//
//	// get the LAN games
//	//
//	for( int t0=0; t0<NumberOfGames; t0++ )
//	{
//		//
//		// Get the name of the game
//		//
//		strncpy( ListOfGameNames[t0], (char*)gos_NetInformation( gos_NameOfGame, t0 ), 19 );
//		ListOfGameNames[t0][19]=0;
//
//		//
//		// Get the game specific data and decode it
//		//
//		ListOfDescriptions[t0][0]=0;
//		if( Environment.DecodeGameInfo )
//		{
//			strncpy( ListOfDescriptions[t0], Environment.DecodeGameInfo((char*)gos_NetInformation( gos_InformationAboutGame, 0, (char*)gos_NetInformation( gos_NameOfGame, t0 ) )), 19 );
//			ListOfDescriptions[t0][19]=0;
//		}
//
//		//
//		// Get the number of players and the maximum number of players
//		//
//		char Buffer[32];
//		if( gos_NetInformation( gos_IsGameSecure, 0, (char*)gos_NetInformation(gos_NameOfGame, t0) ))
//		{
//			ListOfNumPlayers[t0][0]=0;
//		}
//		else
//		{
//			if( gos_NetInformation( gos_IsGamePassworded, 0, (char*)gos_NetInformation(gos_NameOfGame, t0) ) )
//			{
//				sprintf( Buffer, "?/%d", (DWORD)gos_NetInformation( gos_MaxPlayersInGame, 0, (char*)gos_NetInformation( gos_NameOfGame )));
//				strncpy( ListOfNumPlayers[t0], Buffer, 20 );
//			}
//			else
//			{
//				sprintf( Buffer, "%d/%d", (DWORD)gos_NetInformation( gos_NumberOfPlayersInGame, 0, (char*)gos_NetInformation( gos_NameOfGame, t0 )), (DWORD)gos_NetInformation( gos_MaxPlayersInGame, 0, (char*)gos_NetInformation( gos_NameOfGame )));
//				strncpy( ListOfNumPlayers[t0], Buffer, 20 );
//			}
//		}
//
//		//
//		// Passworded?
//		//
//		Buffer[1]=0;
//		Buffer[0]=(gos_NetInformation( gos_IsGamePassworded, 0, (char*)gos_NetInformation( gos_NameOfGame, t0 ) ) ? 'X' : ' ' );
//		strncpy( ListOfPassworded[t0], Buffer, 20 );
//
//		//
//		// Locked?
//		//
//		Buffer[0]=(gos_NetInformation( gos_IsGameLocked, 0, (char*)gos_NetInformation( gos_NameOfGame, t0 ) ) ? 'X' : ' ' );
//		strncpy( ListOfLocked[t0], Buffer, 20 );
//
//		//
//		// Secure?
//		//
//		Buffer[0]=(gos_NetInformation( gos_IsGameSecure, 0, (char*)gos_NetInformation( gos_NameOfGame, t0 ) ) ? 'X' : ' ' );
//		strncpy( ListOfSecure[t0], Buffer, 20 );
//	}
//
//	return 1;
//}
//
//
//






//========================================================================
//
// Create a game.
//
// 0=OK
// 1=Bad game name
// 2=Bad player name
// 3=Failed
// 4=Waiting for answer
//
//extern GUID gos_NetSessionInstance;
typedef struct
{
	DWORD	dwSize;
	DWORD	dwFlags;
	GUID	guidInstance;
	GUID	guidApplication;
	DWORD	dwMaxPlayers;
	DWORD	dwCurrentPlayers;
	char *	lpszSessionNameA;
	char *	lpszPasswordA;
	DWORD	dwReserved1;
	DWORD	dwReserved2;
	DWORD	dwUser1;
	DWORD	dwUser2;
	DWORD	dwUser3;
	DWORD	dwUser4;
} DPSESSIONDESC2;
extern DPSESSIONDESC2 CurrentSession;
#if !defined(BOOL)
#define BOOL int
#if !defined(TRUE)
#define TRUE 1
#define FALSE 0
#endif // !defined(TRUE)
#endif // !defined(BOOL)
extern "C" __declspec(dllimport) BOOL __stdcall GetComputerNameA(char *lpBuffer, DWORD *nSize);


//========================================================================
// Sets the global variable 'GameName' to the default game name.
//========================================================================
SCRIPTCALLBACK(SetGameNameDefault)
{
	DWORD dwSize = 256;
	FREE_PTR(GameName);
	GameName = (char *) gos_Malloc(dwSize);

	NotationFile startup_ini(OPTIONS_INI, NotationFile::Standard, true);
	Page *page = startup_ini.SetPage(OPTIONS_SERVER_SECTION);

	char *s;
	if (page->GetEntry(OPTION_DEFAULTSERVERNAME, (const char **)&s, false))
	{
		strcpy(GameName, s);
	}
	else
	{
		sprintf(GameName, Application::GetInstance()->GetLocString(IDS_NETUI_GAMENAME), (char *)MWApplication::GetInstance()->m_pilotName);
	}

	startup_ini.Save();

	return 0;
}

//========================================================================
// Sets the global variable 'PlayerName' to the default player name.
//========================================================================
SCRIPTCALLBACK(SetPlayerNameDefault)
{
	char szPlayerName[256];
	szPlayerName[0]=0;

	if (true)
	{
#if 0
		//
		// prepare to read from options file
		//
		NotationFile startup_ini(OPTIONS_INI, NotationFile::Standard, true);
		Page *page = startup_ini.SetPage(OPTIONS_SECTION);

		char *s;
		// player name
		if (page->GetEntry(OPTION_PLAYERNAME, (const char **)&s, false))
		{
			strcpy(szPlayerName, s);
		}
		else
		{
			strcpy(szPlayerName, MWApplication::GetInstance()->m_pilotName);
			//DWORD dwSize = sizeof(szPlayerName);
			//GetComputerNameA(szPlayerName, &dwSize);
		}
#endif
		strcpy(szPlayerName, (char *)MW4Shell::Instance->m_optionsObject->m_playerName);

#ifdef LAB_ONLY
		// 8/9/2000 MJL
		// removing this, because we can now change player names, so it
		// is no longer necessary for you to need extra random characters
		// added to your name
#ifdef MLYONS

		if (true)
		{
			char			szRandomNumber[12];
			unsigned int	low_ticks;

			//
			// I basically want a random number here, so I get the low 32 bits
			// of the time stamp counter, a number that increments once for every
			// tick the CPU makes.
			//
			__asm
			{
				lea		ecx, low_ticks			; load a pointer to the variable
				rdtsc							; read time-stamp counter
				mov		ds:[ecx+0], eax			; store the value
				//mov		ds:[ecx+4], edx			; in the variable
			}

			//
			// now, I use that tick count to make two random letters
			//
			sprintf(szRandomNumber, "_%c%c", 'a' + low_ticks % 26, 'a' + (low_ticks/26)%26);
			strcat(szPlayerName, szRandomNumber);
		}
#endif
#endif


	}

	StringPurgeAndDuplicate(PlayerName, szPlayerName);
	return 0;
}

int MechMessageBoxWin32(char *szTitle, char *szMessage, unsigned int uType=0);
//========================================================================
//========================================================================
void MechMessageBox(char *szTitle, char *szMessage)
{
	if (!MWApplication::GetInstance()->Win32DedicatedServer) {
		SCRIPTVAR_STR(MessageBoxTitle);
		SCRIPTVAR_STR(MessageBoxMessage);
		
		
		MessageBoxTitle = (char *)gos_Malloc(1024);
		MessageBoxMessage = (char *)gos_Malloc(1024);
		
		strncpy(MessageBoxTitle, szTitle, 1024);
		strncpy(MessageBoxMessage, szMessage, 1024);
		
		gosScript_RegisterVariable( "MessageBoxTitle", &MessageBoxTitle, GOSVAR_STRING, 0, 0);
		gosScript_RegisterVariable( "MessageBoxMessage", &MessageBoxMessage, GOSVAR_STRING, 0, 0);
	gosScript_ExecuteScript(SHELLSCRIPTS_PATH"MessageBox.script", 0x2000);
		gosScript_UnregisterVariable( "MessageBoxTitle", 0);
		gosScript_UnregisterVariable( "MessageBoxMessage", 0);
	}

	else {
		::MechMessageBoxWin32(szMessage, szTitle);
	}
}


//========================================================================
//========================================================================
int __stdcall Mech4CreateGame(char *szGameName, char *szPlayerName, char *szPassword)
{
	if (true)
	{
		//
		// load the default connection
		//
		if (AdvertiseThisGame)
		{
			if (!ServerBrowser::IPX)
			{
#ifdef USE_GAMESPY
#ifdef NEW_GAMESPY
				if (conDefault.bBrowseGameSpy)
#endif
					InitGameSpyServerAdvertiser(NULL);
#endif
				if (conDefault.bBrowseGUN)
					InitGUNServerAdvertiser();

#ifdef USE_GAMESPY
				for (int i=0 ; i<conDefault.iNumTCPIP ; i++)
				{
					if (conDefault.szTCPIPAddress[i][0])
					{
						InitGameSpyServerAdvertiser(conDefault.szTCPIPAddress[i]);
					}
				}
#endif

			}
		}
		// always advertise on LAN, dammit!!
		InitLANServerAdvertiser();
	}

	DWORD dwFlags = 0;
	dwFlags |= (conDefault.connectiontype & NETFLAGS_CONNECTION_TYPE_MASK);

	int param;
	int *pp=&param;
	param=DEDICATED_SERVER_PARAMETER;
	if (MW4Shell::GetLocalNetworkMissionParamater(0, 0, (void **)&pp))
		dwFlags |= NETFLAGS_DEDICATED_FLAG;

	param=REPORTSTATS_PARAMETER;
	if (MW4Shell::GetLocalNetworkMissionParamater(0, 0, (void **)&pp))
		dwFlags |= NETFLAGS_STATSTRACKING_FLAG;

    param=CLOSED_GAME_PARAMETER;
	if (MW4Shell::GetLocalNetworkMissionParamater(0, 0, (void **)&pp))
		dwFlags |= NETFLAGS_LOCKED_FLAG;

    // mdm - by default, modems and isdn don't want clients to ping them

	//
	// bPingOverriden indicates whether we should override our own decision
	// of whether or not to allow clients to ping us.
	//
	// bPing indicates whether pings are allowed, but is only relevant if
	// bPingOverridden is true
	//
	bool bPingOverridden = false;
	bool bAllowPing = false;

	if (true)
	{
		const char *	szOverridePingDecision;
		const char *	szAllowPing;
		Page *			page;
		NotationFile	options_ini(OPTIONS_INI, NotationFile::Standard, true);

		page = options_ini.FindPage(OPTIONS_SERVER_SECTION);
		if (page)
		{
			// the page is present in the ini file
			if (page->GetEntry("OverridePingDecision", &szOverridePingDecision))
			{
				// the OverridePingDecision setting is present in the ini file, check the value
				// set the value to true if the numerical value is not zero
				bPingOverridden = (atoi(szOverridePingDecision) != 0);

				//
				// now, if it's true, go ahead and see whether we should allow pings
				if (bPingOverridden)
				{
					if (page->GetEntry("AllowPing", &szAllowPing))
					{
						// Allow pings if the numerical value is not zero
						bAllowPing = (atoi(szAllowPing) != 0);
					}
					else
					{
						// the AllowPing setting isn't present, so go ahead
						// and set the bPingOverride value back to false so that
						// we can choose whether to allow Pings.
						bPingOverridden = false;
					}
				}
			}
		}
	}
		
	//
	// mdm - this comment outlines what this code should be if there is the ability
	//       for an override of ping time behavior when hosting in the options.ini
	//
	if ( bPingOverridden )
	{
		if ( bAllowPing == false )
			dwFlags |= NETFLAGS_NOPING_FLAG;
	}
	else
	{
		// enabled code below inside the else
		if ( conDefault.connectiontype < MechWarrior4::MWApplication::xDSL )
		{
			 // mdm - turn off pings if connection type is modem or isdn
			dwFlags |= NETFLAGS_NOPING_FLAG;
		}
	}


	//dwFlags |= NETFLAGS_PURESERVER_FLAG;
	int result = gos_CreateGame( szGameName, szPlayerName, Environment.NetworkMaxPlayers, szPassword, gInSecureGame!=0,NGPassword, dwFlags );


	if ( result == 0 )
	{
		// create game went ok -- check if any advertising problems
		if ( ServerAdvertiser::GetAdvertiseOK() == false )
		{
			MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_ADVERTISE_ERROR));
		}
	}
	else
	{
		// create game failed!  Script will display an error dialog, we just need to clean up and return

		// mdm - must remove the server advertisers from the list
		ServerAdvertiser::ReleaseAll();

		return result;
	}

	if (gos_NetInformation(gos_MyIPAddress))
		StringPurgeAndDuplicate(LocalIPAddress, (char *)gos_NetInformation(gos_MyIPAddress));
	else
		LocalIPAddress[0]=0;

	// mdm - host must advertise his clan name manually since he doesn't get a RequestConnectionMessageHandler callback
	const char *my_clan_name = "\0";
	NotationFile options_ini(OPTIONS_SECTION, NotationFile::Standard, true);
	Page *page = options_ini.FindPage(OPTIONS_SECTION);
	if (page)
	{
		page->GetEntry("TeamName", &my_clan_name);
	}

	int size = strlen(my_clan_name)+1;
	Max_Clamp(size, 255);

	// get our dplay id
	int myID = (DWORD) gos_NetInformation( gos_MyID, 0, NULL );
	gosASSERT(myID);
	ServerAdvertiser::AdvertiseItem( myID, PLAYERLIST_KEY_CLAN_NAME, my_clan_name);

	return result;
}



//========================================================================
//========================================================================
int __stdcall Mech4ReconnectGame()
{
	
	
	
	if (AdvertiseThisGame)
	{
		if (!ServerBrowser::IPX)
		{
			if (conDefault.bBrowseGUN)
			{
				ServerAdvertiser::ReleaseAll();
				InitGUNServerAdvertiser();
				InitLANServerAdvertiser();
				
			}
			else
				return true;
		}
		else 
			return true;
	}
	else
		return true;


		DWORD dwFlags = 0;
	dwFlags |= (conDefault.connectiontype & NETFLAGS_CONNECTION_TYPE_MASK);

	int param;
	int *pp=&param;
	param=DEDICATED_SERVER_PARAMETER;
	if (MW4Shell::GetLocalNetworkMissionParamater(0, 0, (void **)&pp))
		dwFlags |= NETFLAGS_DEDICATED_FLAG;

	param=REPORTSTATS_PARAMETER;
	if (MW4Shell::GetLocalNetworkMissionParamater(0, 0, (void **)&pp))
		dwFlags |= NETFLAGS_STATSTRACKING_FLAG;

    param=CLOSED_GAME_PARAMETER;
	if (MW4Shell::GetLocalNetworkMissionParamater(0, 0, (void **)&pp))
		dwFlags |= NETFLAGS_LOCKED_FLAG;

    // mdm - by default, modems and isdn don't want clients to ping them

	//
	// bPingOverriden indicates whether we should override our own decision
	// of whether or not to allow clients to ping us.
	//
	// bPing indicates whether pings are allowed, but is only relevant if
	// bPingOverridden is true
	//
	bool bPingOverridden = false;
	bool bAllowPing = false;

	if (true)
	{
		const char *	szOverridePingDecision;
		const char *	szAllowPing;
		Page *			page;
		NotationFile	options_ini(OPTIONS_INI, NotationFile::Standard, true);

		page = options_ini.FindPage(OPTIONS_SERVER_SECTION);
		if (page)
		{
			// the page is present in the ini file
			if (page->GetEntry("OverridePingDecision", &szOverridePingDecision))
			{
				// the OverridePingDecision setting is present in the ini file, check the value
				// set the value to true if the numerical value is not zero
				bPingOverridden = (atoi(szOverridePingDecision) != 0);

				//
				// now, if it's true, go ahead and see whether we should allow pings
				if (bPingOverridden)
				{
					if (page->GetEntry("AllowPing", &szAllowPing))
					{
						// Allow pings if the numerical value is not zero
						bAllowPing = (atoi(szAllowPing) != 0);
					}
					else
					{
						// the AllowPing setting isn't present, so go ahead
						// and set the bPingOverride value back to false so that
						// we can choose whether to allow Pings.
						bPingOverridden = false;
					}
				}
			}
		}
	}
		
	//
	// mdm - this comment outlines what this code should be if there is the ability
	//       for an override of ping time behavior when hosting in the options.ini
	//
	if ( bPingOverridden )
	{
		if ( bAllowPing == false )
			dwFlags |= NETFLAGS_NOPING_FLAG;
	}
	else
	{
		// enabled code below inside the else
		if ( conDefault.connectiontype < MechWarrior4::MWApplication::xDSL )
		{
			 // mdm - turn off pings if connection type is modem or isdn
			dwFlags |= NETFLAGS_NOPING_FLAG;
		}
	}

	gos_ReConnectGame( dwFlags );

	if ( ServerAdvertiser::GetAdvertiseOK() == false )
	{
		ServerAdvertiser::ReleaseAll();
		return false;
	}

	if (gos_NetInformation(gos_MyIPAddress))
		StringPurgeAndDuplicate(LocalIPAddress, (char *)gos_NetInformation(gos_MyIPAddress));
	else
		LocalIPAddress[0]=0;

	// mdm - host must advertise his clan name manually since he doesn't get a RequestConnectionMessageHandler callback
	const char *my_clan_name = "\0";
	NotationFile options_ini(OPTIONS_SECTION, NotationFile::Standard, true);
	Page *page = options_ini.FindPage(OPTIONS_SECTION);
	if (page)
	{
		page->GetEntry("TeamName", &my_clan_name);
	}

	int size = strlen(my_clan_name)+1;
	Max_Clamp(size, 255);

	// get our dplay id
	int myID = (DWORD) gos_NetInformation( gos_MyID, 0, NULL );
	gosASSERT(myID);
	ServerAdvertiser::AdvertiseItem( myID, PLAYERLIST_KEY_CLAN_NAME, my_clan_name);


	MWApplication *app = MWApplication::GetInstance();

#if 0
	for (int i = 1; i < Maximum_Connection_Numbers; i++)
	{
		Connection * pConnectObj = Network::GetInstance()->GetConnection(i);
    	
		if (pConnectObj)
		{
			ServerAdvertiser::AddPlayerAll(pConnectObj->GetNetworkAddress(), pConnectObj->GetConnectionName());

			Check_Object(pConnectObj);

			// all players are registered with ServerAdvertisers in GameOS when the dplay
			// AddPlayer message arrives.  GUN registers the player using their dplay ID
			// as their unique identifier.

			// this if check is to avoid multithreading problem.
			if (app->servedConnectionData[i].clanName != NULL)
			{
				ServerAdvertiser::AdvertiseItem( pConnectObj->GetNetworkAddress(), // player ID; 0 = server
												 PLAYER_CLAN_NAME_KEY,  // key name
												 app->servedConnectionData[i].clanName); // key val
			}
		}

	}
#else

	// Need to add back all the players AND bots
	for (int connection = 0; connection < Maximum_Players; ++connection)
	{
		if (app->servedConnectionData[connection].clientConnected)
		{
			ServerAdvertiser::AddPlayerAll(connection, app->servedConnectionData[connection].pilotName);

			// this if check is to avoid multithreading problem.
			if (app->servedConnectionData[connection].clanName != NULL)
			{
                if (!CTCL_IsConsole()) {
				gos_NetSetAdvertItem( connection, // player ID; 0 = server
									 PLAYER_CLAN_NAME_KEY,  // key name
									 app->servedConnectionData[connection].clanName); // key val
                }
			}
		}
	}

	// Now add back the bots
	for (connection = 0; connection < Maximum_Lancemates; ++connection)
	{

		if (app->lancemateConnectionData[connection].lancemateConnected)
		{
			ServerAdvertiser::AddPlayerAll(connection+256, app->lancemateConnectionData[connection].lancemateName);
			
			// this if check is to avoid multithreading problem.
			if (app->lancemateConnectionData[connection].lancemateClan != NULL)
			{
                if (!CTCL_IsConsole()) {
				gos_NetSetAdvertItem( connection+256, // player ID; 0 = server
									 PLAYER_CLAN_NAME_KEY,  // key name
									 app->lancemateConnectionData[connection].lancemateClan); // key val
                }
			}
		}
	}

#endif
	return true;
}

//========================================================================
//
//========================================================================
SCRIPTCALLBACK(CreateSession)
{
	if (!GameName)
	{
		SetGameNameDefault(NULL,0,NULL);

		Environment.NetworkMaxPlayers = 4;
		GamePassword = NULL;
		gInSecureGame = false;
	}
	else
	{
		//
		// save the game name in the options.ini file
		//
		NotationFile startup_ini(OPTIONS_INI, NotationFile::Standard, true);
		Page *page = startup_ini.SetPage(OPTIONS_SERVER_SECTION);

		page->SetEntry(OPTION_DEFAULTSERVERNAME, GameName);

		startup_ini.Save();
	}
	if ( !PlayerName )
	{
		SetPlayerNameDefault( NULL, 0, NULL );
	}

	return Mech4CreateGame(GameName, PlayerName, GamePassword);
}


//========================================================================
// Join a game (On a serial or modem game, enumerate the current game and join that)
//
//  0=OK
//  1=Bad game name (or waiting for game on modem/serial)
//  2=Bad player name
//  3=Failed to connect
//  4=No dial tone
//  5=Invalid password
//  6=Too many players in the game
//========================================================================
SCRIPTCALLBACK(JoinSelected)
{
	// test code to be used until the new UI is all ready to go
	if (!PlayerName)
	{
		SetPlayerNameDefault( NULL, 0, NULL );
	}

	int result=gos_JoinGame( GameName, PlayerName, GamePassword, NGPassword);

	switch (result)
	{
	case 0:
		break;


	case 2:
		MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_JOIN_NOPLAYERNAME_ERROR));
		break;

	case 1:
	case 3:
	case 4:
		MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_JOIN_ERROR));
		break;

		break;

	case 5:
		MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_JOIN_PASSWORD_ERROR));
		break;

	case 6:
		MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_JOIN_GAMELOCKED_ERROR));
		break;

	case 7:
		MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_ICS));
		break;

	}

	return result;
}




//========================================================================
// Hang up the line or disconnect a network game
//========================================================================
SCRIPTCALLBACK(Disconnect)
{
	if ( ServerBrowser::GetGameList() )
	{
		ServerBrowser::GetGameList()->ShutdownPing();
	}
	ServerBrowser::ReleaseAll();
	ServerAdvertiser::ReleaseAll();
	gos_Disconnect();
	return true;
}


//========================================================================
// Open a TCPIP and ZoneMatch connection
//========================================================================
SCRIPTCALLBACK(CheckZoneMatch)
{
    return CheckForZoneMatch();
}


//========================================================================
// Open a TCPIP and ZoneMatch connection
//========================================================================
SCRIPTCALLBACK(CreateBrowsers)
{
	//
	// load the default connection
	//
	if (conDefault.bBrowseLAN)
	{
		InitTCPIPServerBrowser();
		InitIPXServerBrowser();
	}

	for (int i=0 ; i<conDefault.iNumTCPIP ; i++)
	{
		if (conDefault.szTCPIPAddress[i][0])
		{
			InitTCPIPServerBrowser(conDefault.szTCPIPAddress[i]);
#ifdef USE_GAMESPY
			InitGameSpyServerBrowser(conDefault.szTCPIPAddress[i]);
#endif
		}
	}

	if (conDefault.bBrowseGUN && CheckForZoneMatch() )
	{
		InitGUNServerBrowser();
	}

#ifdef USE_GAMESPY
#ifdef NEW_GAMESPY
	if (conDefault.bBrowseGameSpy)
#endif
	{
		InitGameSpyServerBrowser(NULL);
	}
#endif

    if ( ServerBrowser::GetBrowserCount() == 0 )
    {
        // no server browsers available!  return error
        return -1;
    }

    // push the current connection's filter settings to the gamelist
    PushFiltersToGameList();

    // register the variables for the scripts to use to control the filtering.

	return 1;
}






//========================================================================
// Allocate String
//========================================================================
void _inline AllocString(char * &sptr)
{
	sptr = (char *)gos_Malloc(STRING_SIZE);
	sptr[0] = 0;
}

//========================================================================
// Free String
//========================================================================
void _inline FreeString(char * &sptr)
{
	FREE_PTR(sptr);
}

//========================================================================
// Allocate Array
//========================================================================
void _inline AllocArray(char ** &aptr)
{
	aptr = (char **)gos_Malloc(NUM_ELEMENTS*sizeof(char *));
	for (int i=0 ; i<NUM_ELEMENTS ; i++)
	{
		aptr[i] = (char *)gos_Malloc(STRING_SIZE);
		aptr[i][0] = 0;
	}
}

//========================================================================
// Free Array
//========================================================================
void _inline FreeArray(char ** &aptr)
{
	if (aptr)
	{
		for (int i=0 ; i<NUM_ELEMENTS ; i++)
			FREE_PTR(aptr[i]);
		FREE_PTR(aptr);
	}
}

//========================================================================
// Allocate Irray
//========================================================================
void _inline AllocIrray(int * &iptr)
{
	iptr = (int *)gos_Malloc(NUM_ELEMENTS*sizeof(int));
}

//========================================================================
// Free Irray
//========================================================================
void _inline FreeIrray(int * &iptr)
{
	FREE_PTR(iptr);
}

//========================================================================
// Allocate memory for all the script variables
//========================================================================
void RegisterData(void)
{
	UnRegisterData();

	AllocString(DUNUserName);
	AllocString(DUNPassword);
	DUNUserName[0] = 0;
	DUNPassword[0] = 0;

	AllocArray(ListOfPlayers);
	AllocArray(ListOfClans);
	AllocArray(ListOfModems);
	AllocArray(ListOfSerialPorts);
	AllocArray(ListOfConnections);
	AllocArray(ListOfIPAddresses);
	AllocArray(ListOfServers);
	AllocArray(ListOfDUN);

	AllocArray(ListOfTCPIPAddresses);


    AllocString(GameDataID);
    AllocString(SortColumnName);
    AllocString(SortType);
    AllocString(FilterParamVal);
    AllocString(PingTimeStr);
	AllocString(GamePassword);
	AllocString(ErrorMsg);
    AllocString(ReferenceVersion);

	AllocString(klds07);
	AllocString(GameSpyAddress);

}

//========================================================================
// Remove all script variables
//========================================================================
void UnRegisterData(void)
{
	extern bool ScriptsRunning;
	if (ScriptsRunning)
		gosScript_UnregisterAll( NetworkInstance );

	FREE_PTR(PlayerName);
	FREE_PTR(ServerIPAddress);
	FREE_PTR(GameName);
	FREE_PTR(NGPassword);
	FREE_PTR(DUNUserName);
	FREE_PTR(DUNPassword);

	FreeArray(ListOfPlayers);
	FreeArray(ListOfClans);
	FreeArray(ListOfModems);
	FreeArray(ListOfSerialPorts);
	FreeArray(ListOfConnections);
	FreeArray(ListOfIPAddresses);
	FreeArray(ListOfServers);
	FreeArray(ListOfDUN);

	FreeArray(ListOfTCPIPAddresses);


    FreeString(GameDataID);
    FreeString(SortColumnName);
    FreeString(SortType);
    FreeString(FilterParamVal);
    FreeString(PingTimeStr);
	FreeString(GamePassword);
	FreeString(ErrorMsg);
	FreeString(klds07);
	FreeString(GameSpyAddress);
    FreeString(ReferenceVersion);
}


//========================================================================
// Update - Update the entire list of servers in the server browser
// screen.
//========================================================================
SCRIPTCALLBACK(UpdateServerList)
{
	ServerBrowser::Update();
	return 0;
}
//========================================================================
// Refresh - refresh the list of displayed servers and re-apply the
// selected filters
//========================================================================
SCRIPTCALLBACK(RefreshServerInfo)
{
	ServerBrowser::RefreshList();
	return 0;
}


//
//
// Return values:
// 0 - serverinfo pending
// 1 - success
// 2 - error obtaining info
// 3 - server doesn't exist
//
//
SCRIPTCALLBACK(GetServerInfoStatus)
{
    int retval = 0;
    const char * queryResult = 0;

    if ( args != 1 )
    {
        return atoi(GAMELIST_VALUE_SERVER_INFO_STATUS_ERROR);
    }

    if ( ServerBrowser::GetGameList() == NULL )
    {
        PAUSE(( "No game list object when GetServerInfo called.\n" ));
        return atoi(GAMELIST_VALUE_SERVER_INFO_STATUS_NOSERVER);
    }

    char * gameID = *((char **) arg[0]);

    Browse::GameList::Lock();

    queryResult = ServerBrowser::GetGameList()->GetDataField( gameID, GAMELIST_KEY_SERVER_INFO_STATUS );

    if ( queryResult )
    {
        int qr = atoi(queryResult);
        retval = qr;
    }
    else
    {
        // couldn't find server
        retval = atoi(GAMELIST_VALUE_SERVER_INFO_STATUS_NOSERVER);
    }

CLEANUP:

    Browse::GameList::Unlock();
    return retval;
}

//========================================================================
// GetServerInfo - get information for the selected server. This will
// get player information
//========================================================================
SCRIPTCALLBACK(GetServerInfo)
{
    if ( args != 1 )
    {
        return -1;
    }

    if ( ServerBrowser::GetGameList() == NULL )
    {
        PAUSE(( "No game list object when GetServerInfo called.\n" ));
        return -1; // no game list object!
    }

    char * gameID = *(( char **) arg[0]);

    Browse::GameList::Lock();

    bool retval = ServerBrowser::ServerInfo( gameID );
    if (retval == false )
    {
        // somehow, none of the browsers responded to the request for server info
        // for the game
        Browse::GameList::Unlock();
        return -1;
    }

    Browse::GameList::Unlock();
    return 0;
}


//========================================================================
// GetZMStatus
// Get status information on the ZoneMatch connection.
// argv[0] == 1 -> return current operational phase
// argv[0] == 2 -> return current net status
// argv[0] == 3 -> return last known error
//========================================================================
SCRIPTCALLBACK(GetZMStatus)
{
	if ( args != 1 )
	{
		PAUSE(( "Invalid number of arguments (%d) to GetZMStatus().", args ));
		return 0;
	}

	int queryMode = (int)arg[0];
	switch (queryMode)
	{
	case 1:
		// return current operational phase
		return GetGUNStatus();
		break;
	case 2:
		// return current net status
		return GetGUNNetStatus();
		break;
	case 3:
		// return last known error
		{
			int lastError = GetGUNLastError();

			const char * errorMsg = GetGUNErrorMessage();
			if ( errorMsg && ErrorMsg )
			{
				strncpy(ErrorMsg, errorMsg, 254);
				ErrorMsg[255] = 0;
			}
			else if ( ErrorMsg )
			{
				ErrorMsg[0] = 0;
			}
			return lastError;
		}
		break;
	default:
		return -1;
		break;
	}
}

////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Returns the total number of game servers to be downloaded for the current
//       update, or -1 if not known.
//
//  Parameters:
//       [GetGUNDownloadSize] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          092200  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(GetGUNDownloadSize)
{
	int tableSize, progressCount;

	GetGUNDownloadStats(&tableSize, &progressCount);

	return tableSize;
}


////////////////////////////////////////////////////////////////////////////////////////
//  SCRIPTCALLBACK()
//  Purpose:
//       Returns the total number of game servers currently received for the current
//       download, or -1 if not known.
//
//  Parameters:
//       [GetGUNDownloadProgress] :
//
//  Returns:  none
//
//  Change Log
//       Author                 MMDDYY  Description
//       --------------------   ------  ------------------------------------------------
//       Michael Moore          092200  Initial Version
//
//
////////////////////////////////////////////////////////////////////////////////////////
SCRIPTCALLBACK(GetGUNDownloadProgress)
{
	int tableSize, progressCount;

	GetGUNDownloadStats(&tableSize, &progressCount);

	return progressCount;
}


//========================================================================
// GetZMStatus
// Get status information on the ZoneMatch connection.
// argv[0] == 1 -> return current operational phase
// argv[0] == 2 -> return current net status
// argv[0] == 3 -> return last known error
//========================================================================
SCRIPTCALLBACK(GetGameSpyStatus)
{
	if ( args != 1 )
	{
		PAUSE(( "Invalid number of arguments (%d) to GetZMStatus().", args ));
		return 0;
	}

	int queryMode = (int)arg[0];
	switch (queryMode)
	{
	case 1:
		// return current operational phase
		return GameSpy::GetStatus();
		break;
	case 2:
		// return current net status
		return GameSpy::GetNetStatus();
		break;
	case 3:
		// return last known error
		return GameSpy::GetLastError();
		break;
	default:
		return -1;
		break;
	}
}



//========================================================================
//========================================================================
SCRIPTCALLBACK(LoadMPConnectionSettings)
{
	conDefault.dwVersion = (DWORD)-1;

	char *szFile;

	ConnectionIndex = 0;
	NumConnections = 0;

	if ((szFile=gos_FindFiles("m4c*.m4c")) != NULL)
	{
		ConnectionIndex = 0;
		do
		{
			StringPurgeAndDuplicate(ListOfConnections[NumConnections], szFile+3);
			ListOfConnections[NumConnections][strlen(ListOfConnections[NumConnections])-4] = 0;

			LoadConnection(&conDefault, ListOfConnections[NumConnections], false);
			if (conDefault.dwVersion == CONNECTION_FILE_VERSION)
				NumConnections++;

			if (NumConnections >= NUM_ELEMENTS)
				break;

		} while ((szFile=gos_FindFilesNext()) != NULL);

		gos_FindFilesClose();
	}

	//
	// see if we have a default connection
	//
	if (true)
	{
		NotationFile startup_ini(OPTIONS_INI, NotationFile::Standard, true);
		Page *page = startup_ini.FindPage(OPTIONS_SECTION);
		if (!page)
			page = startup_ini.AddPage(OPTIONS_SECTION);

		char *s;
		if (page->GetEntry(OPTION_CONNECTIONNAME, (const char **)&s, false))
		{
			for ( ; ConnectionIndex < NumConnections ; ConnectionIndex++)
			{
				if (!strcmp(ListOfConnections[ConnectionIndex], s))
					break;
			}

			if (ConnectionIndex == NumConnections)
				ConnectionIndex = 0;
		}

		startup_ini.Save();
	}

	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(SaveMPConnectionSettings)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(InitMainMPScreen)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(InitNewConnectionScreen)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(InitBrowseChoiceScreen)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(InitServerListScreen)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(AddServer)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(SelectServer)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(JoinGame)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(HostGame)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(GetDialupConnectionStatus)
{
	if (conDefault.bAlreadyConnected)
		return 3;

	return RAS::GetStatus(DialupConnectionStatus);
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(PreConnect)
{
	LoadConnection(&conDefault, ListOfConnections[ConnectionIndex], true);

	BrowseGameSpy						= conDefault.bBrowseGameSpy;
	BrowseGUN							= conDefault.bBrowseGUN;
	BrowseLAN							= conDefault.bBrowseLAN;
	BrowseIPAddresses					= conDefault.iNumTCPIP;
	kldi61								= conDefault.bAlreadyConnected;
	MWApplication::MyConnectionSpeed	= conDefault.bandwidth;
	MWApplication::MyConnectionType		= conDefault.connectiontype;

	if (conDefault.bAlreadyConnected == 0)
		RAS::Dial(conDefault.szPhonebookEntryName, conDefault.szUserName, conDefault.szPassword);

	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(CancelDialup)
{
	return RAS::HangUp();
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(RemoveConnection)
{
	//
	// don't remove if there's only one connection
	//
	if (NumConnections < 2)
		return -1;

	//
	// step 1: remove the file
	//
	char szFileName[256];

	strcpy(szFileName, "m4c");
	strcat(szFileName, ListOfConnections[ConnectionIndex]);
	strcat(szFileName, ".m4c");

	gos_DeleteFile(szFileName);

	//
	// step 2: adjust the list by moving every name beyond this
	// connection down one
	//
	for (int i=ConnectionIndex ; i+1<NumConnections ; i++)
	{
		strcpy(ListOfConnections[i], ListOfConnections[i+1]);
	}

	//
	// step 3: adjust the number of connections
	//
	NumConnections--;
	if (ConnectionIndex == NumConnections)
		ConnectionIndex--;

	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(CreateNewPhonebookEntry)
{
	if (!RAS::CreateNewEntry())
	{
		MechMessageBox(Application::GetInstance()->GetLocString(IDS_NETUI_ERROR), Application::GetInstance()->GetLocString(IDS_NETUI_NODIALUP_ERROR));
	}
	NumDUN = RAS::GetListOfEntries(ListOfDUN);
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(QuickJoin)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(GetHostOptions)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(GetFilterOptions)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(RefreshGameList)
{
    return ServerBrowser::RefreshList();
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(UpdateGameList)
{
    if ( args == 1 )
    {
        int handle = (int) arg[0];
        if ( handle < -1 || handle > 9999)
        {
            handle = *( int *) arg[0];
        }
        ServerBrowser::Update( handle );
    }
    else
    {
    	ServerBrowser::Update();
    }
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(CancelActivity)
{
	ServerBrowser::CancelAllActivity();
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(IsGameListUpdating)
{
	return (int)ServerBrowser::StillBusy();
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(ChatSend)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(FillPlayerRosterMechType)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(FillMechTypes)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(FillGameSettings)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(GetRASEntryUserNameAndPassword)
{
	FreeString(DUNUserName);
	FreeString(DUNPassword);
	AllocString(DUNUserName);
	AllocString(DUNPassword);
	RAS::GetUserNameAndPassword(ListOfDUN[DUNIndex], DUNUserName, DUNPassword);
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc12)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc13)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc14)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc15)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc16)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc17)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc18)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc19)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc20)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc21)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc22)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc23)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc24)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(kldc25)
{
	return 0;
}

//========================================================================
//========================================================================
SCRIPTCALLBACK(BrowseIPAddress)
{
	gosASSERT(args == 1);
	char **	szIPAddress	= (char **)arg[0];

	//
	// add the address to the default connection
	//
	if (conDefault.iNumTCPIP < ARRAY_SIZE(conDefault.szTCPIPAddress))
	{
		strncpy(conDefault.szTCPIPAddress[conDefault.iNumTCPIP], *szIPAddress, sizeof(conDefault.szTCPIPAddress[conDefault.iNumTCPIP]));
		FixSZString(conDefault.szTCPIPAddress[conDefault.iNumTCPIP]);
		conDefault.iNumTCPIP++;
		SaveConnection(&conDefault);
	}

	int handle = InitTCPIPServerBrowser(*szIPAddress);
#ifdef USE_GAMESPY
	InitGameSpyServerBrowser(*szIPAddress);
#endif
	return handle;
}


//========================================================================
// gos_NetStartGame
//
// This gets called as soon as the user clicks "Multiplayer." After this
// point, the app waits until we tell it we're ready to go.
//========================================================================
bool __stdcall gos_NetStartGame( char* GameOptionsScript, bool Secure )
{
	// avoid compiler warning
	GameOptionsScript=GameOptionsScript;

	RAS::InitializeLibrary();

	// store secure state
	gInSecureGame=Secure;

	// initialize GameOS variables
	gos_InitializeNetworking();

	// clean up anything we may have previously allocated
	UnRegisterData();

	//
	RegisterData();


	// get the ip address
	//
    FreeString(LocalIPAddress); // jcem
	AllocString(LocalIPAddress);

	if (MWApplication::GetInstance()->Win32DedicatedServer)
		return 1;
    //

	//
	// OLD UI!!
	//
	gosScript_RegisterCallback( "CheckZoneMatch",			&CheckZoneMatch,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetPlayerList",		    &GetPlayerList,           			GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "UpdateGUNGameList",		&UpdateGUNGameList,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "JoinSelected",				&JoinSelected,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetTotalGameCount",		&GetTotalGameCount,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "CreateSession",			&CreateSession,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "Disconnect",				&Disconnect,						GOSVAR_INT,		0,				NetworkInstance );

	// gamelist api callbacks
	gosScript_RegisterCallback( "GetGameData",				&GetGameData,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "SortGameList",				&SortGameList,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "Select",					&Select,							GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetSelection",				&GetSelection,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetListSize",				&GetListSize,						GOSVAR_INT,		0,				NetworkInstance );
    gosScript_RegisterCallback( "GetReferenceVersion",      &GetReferenceVersion,               GOSVAR_INT,     0,              NetworkInstance );
	// ping control callbacks
	gosScript_RegisterCallback( "StartPingServer",			&StartPingServer,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "StartPingClient",			&StartPingClient,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "ShutdownPing",				&ShutdownPing,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetPing",					&GetPing,							GOSVAR_INT,		0,				NetworkInstance );
	// misc callbacks
	gosScript_RegisterCallback( "SetGameNameDefault",		&SetGameNameDefault,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "SetPlayerNameDefault",		&SetPlayerNameDefault,				GOSVAR_INT,		0,				NetworkInstance );

	gosScript_RegisterCallback( "InitConnectionWizard",		&InitConnectionWizard,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "TermConnectionWizard",		&TermConnectionWizard,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "LaunchDUNWizard",			&LaunchDUNWizard,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetDialupConnectionStatus",&GetDialupConnectionStatus,			GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "PreConnect",				&PreConnect,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "CancelDialup",				&CancelDialup,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "CreateNewPhonebookEntry",	&CreateNewPhonebookEntry,			GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetZMStatus",				&GetZMStatus,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetGameSpyStatus",			&GetGameSpyStatus,					GOSVAR_INT,		0,				NetworkInstance );
    gosScript_RegisterCallback( "GetServerInfo",            &GetServerInfo,                     GOSVAR_INT,     0,              NetworkInstance );
    gosScript_RegisterCallback( "GetServerInfoStatus",      &GetServerInfoStatus,               GOSVAR_INT,     0,              NetworkInstance );
	gosScript_RegisterCallback( "GetGUNDownloadSize",		&GetGUNDownloadSize,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "GetGUNDownloadProgress",	&GetGUNDownloadProgress,			GOSVAR_INT,		0,				NetworkInstance );

	//
	// Callbacks for Filter support
	//
	gosScript_RegisterCallback( "ApplyFilters",				&ApplyFilters,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterCallback( "SaveFilters",				&SaveFilters,						GOSVAR_INT,		0,				NetworkInstance );
    gosScript_RegisterCallback( "RevertFilters",            &RevertFilters,                     GOSVAR_INT,     0,              NetworkInstance );
    gosScript_RegisterCallback( "ClearFilters",             &ClearFilters,                      GOSVAR_INT,     0,              NetworkInstance );
    gosScript_RegisterCallback( "SetFilterParam",           &SetFilterParam,                    GOSVAR_INT,     0,              NetworkInstance );
    gosScript_RegisterCallback( "GetFilterParam",           &GetFilterParam,                    GOSVAR_INT,     0,              NetworkInstance );
    //
    // Callbacks for Sorting support
    //
    gosScript_RegisterCallback( "SaveSortInfo",             &SaveSortInfo,                      GOSVAR_INT,     0,              NetworkInstance );
    gosScript_RegisterCallback( "GetSortInfo",              &GetSortInfo,                       GOSVAR_INT,     0,              NetworkInstance );


    gosScript_RegisterCallback( "BrowseIPAddress",			&BrowseIPAddress,					GOSVAR_INT,		0,				NetworkInstance );

	//
	// Integers passed between the UI and GameOS
	//
	gosScript_RegisterVariable( "gConnectionType",			&gConnectionType,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "NumberOfGames",			&NumberOfGames,						GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "NumberOfPlayers",			&NumberOfPlayers,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "Available",				&Available,							GOSVAR_INT,		0,				NetworkInstance );

	// gamelist scripting API int variables
	gosScript_RegisterVariable( "ServerPort",				&g_APIVars.ServerPort,				GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "AdvertiseThisGame",		&AdvertiseThisGame,					GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "LocalIPAddress",			&LocalIPAddress,					GOSVAR_STRING,	0,				NetworkInstance );
    gosScript_RegisterVariable( "LocalGameVersion",         &Environment.version,               GOSVAR_STRING,  0,              NetworkInstance );


	//
	// Strings
	//
    gosScript_RegisterVariable( "ReferenceVersion",         &ReferenceVersion,                  GOSVAR_STRING,  0,              NetworkInstance );
	gosScript_RegisterVariable( "GameName",					&GameName,							GOSVAR_STRING,	0,				NetworkInstance );
//		gosScript_RegisterVariable( "PlayerName",				&PlayerName,						GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "ServerIPAddress",			&ServerIPAddress,					GOSVAR_STRING,	0,				NetworkInstance );
//		gosScript_RegisterVariable( "NGPassword",				&NGPassword,						GOSVAR_STRING,	0,				NetworkInstance );

	// gamelist scripting API string variables
	gosScript_RegisterVariable( "NumPlayers",				&g_APIVars.NumPlayers,				GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "MaxPlayers",				&g_APIVars.MaxPlayers,				GOSVAR_STRING,	0,				NetworkInstance );

    gosScript_RegisterVariable( "GameID",                   &GameDataID,                        GOSVAR_STRING,  0,              NetworkInstance );
	gosScript_RegisterVariable( "GameVersion",				&g_APIVars.GameVersion,				GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "ServerAddress",			&g_APIVars.ServerAddress,			GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "ServerName",				&g_APIVars.ServerName,				GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "PasswordStatus",			&g_APIVars.PasswordStatus,			GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "MapType",					&g_APIVars.MapType,					GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "GameType",					&g_APIVars.GameType,				GOSVAR_STRING,	0,				NetworkInstance );
	
	gosScript_RegisterVariable( "Protocol",					&g_APIVars.Protocol,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "ConnectionType",			&g_APIVars.ConnectionType,			GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "Dedicated",				&g_APIVars.Dedicated,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "StatsTracking",			&g_APIVars.StatsTracking,			GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "PureServer",				&g_APIVars.PureServer,				GOSVAR_INT,		0,				NetworkInstance );
	gosScript_RegisterVariable( "Locked",					&g_APIVars.Locked,					GOSVAR_INT,		0,				NetworkInstance );


	//
	// Arrays of strings
	//
	gosScript_RegisterVariable( "ListOfPlayers",			&ListOfPlayers,						GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance );
	gosScript_RegisterVariable( "ListOfClans",				&ListOfClans,						GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance );

	gosScript_RegisterCallback( "LoadMPConnectionSettings",	&LoadMPConnectionSettings,			GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "CreateBrowsers",			&CreateBrowsers,					GOSVAR_INT,		0,				NetworkInstance);
	
	gosScript_RegisterVariable( "ConnectionIndex",			&ConnectionIndex,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "NumConnections",			&NumConnections,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "AmIOnDialUpDefault",		&AmIOnDialUpDefault,				GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "BrowseGameSpy",			&BrowseGameSpy,						GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "BrowseGUN",				&BrowseGUN,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "BrowseLAN",				&BrowseLAN,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "BrowseIPAddresses",		&BrowseIPAddresses,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "NumIPAddresses",			&NumIPAddresses,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "NumServers",				&NumServers,						GOSVAR_INT,		0,				NetworkInstance);

	gosScript_RegisterVariable( "ListOfConnections",		&ListOfConnections,					GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance);
	gosScript_RegisterVariable( "ListOfIPAddresses",		&ListOfIPAddresses,					GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance);
	gosScript_RegisterVariable( "ListOfServers",			&ListOfServers,						GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance);
	gosScript_RegisterVariable( "ServerInfo",				&ServerInfo,						GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance);

	gosScript_RegisterVariable( "UseDUN",					&UseDUN,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "NumDUN",					&NumDUN,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "ListOfDUN",				&ListOfDUN,							GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance);
	gosScript_RegisterVariable( "DUNIndex",					&DUNIndex,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "DUNUserName",				&DUNUserName,						GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "DUNPassword",				&DUNPassword,						GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "DialupConnectionStatus",	&DialupConnectionStatus,			GOSVAR_STRING,	0,				NetworkInstance );

	gosScript_RegisterVariable( "ZoneServerAddress",		&Environment.ZoneMatchServerIP,		GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "GameSpyServerAddress",		&GameSpyAddress,					GOSVAR_STRING,	0,				NetworkInstance );
	gosScript_RegisterVariable( "MaxPlayerLimit",			&Environment.NetworkMaxPlayers,		GOSVAR_INT,		0,				NetworkInstance );

	//////////////////////////////////
	// mdm
	// Variables for the filter screen
	//////////////////////////////////

	gosScript_RegisterVariable( "kldi02",					&iDedicated,						GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "kldi03",					&bPasswordProtected,				GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "kldi30",					&kldi30,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "kldi61",					&kldi61,							GOSVAR_INT,		0,				NetworkInstance);
	
    // sort and filter registered vars
    gosScript_RegisterVariable( "SortColumnID",             &SortColumnID,                      GOSVAR_INT,     0,              NetworkInstance);
    gosScript_RegisterVariable( "SortDescending",           &SortDescending,                    GOSVAR_INT,     0,              NetworkInstance);
    gosScript_RegisterVariable( "SortColumnName",           &SortColumnName,                    GOSVAR_STRING,  0,              NetworkInstance);
    gosScript_RegisterVariable( "SortType",                 &SortType,                          GOSVAR_STRING,  0,              NetworkInstance);
    gosScript_RegisterVariable( "FilterParamVal",           &FilterParamVal,                    GOSVAR_STRING,  0,              NetworkInstance);
    gosScript_RegisterVariable( "PingTimeStr",              &PingTimeStr,                       GOSVAR_STRING,  0,              NetworkInstance);
	gosScript_RegisterVariable( "GamePassword",				&GamePassword,						GOSVAR_STRING,	0,				NetworkInstance);
	gosScript_RegisterVariable( "ErrorMsg",					&ErrorMsg,							GOSVAR_STRING,	0,				NetworkInstance);


	gosScript_RegisterVariable( "klds07",					&klds07,							GOSVAR_STRING,	0,				NetworkInstance);

	gosScript_RegisterVariable( "klda18",					&ListOfTCPIPAddresses,				GOSVAR_STRING,	NUM_ELEMENTS,	NetworkInstance);

	gosScript_RegisterCallback( "kldc01",					&RemoveConnection,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc02",					&QuickJoin,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc03",					&GetHostOptions,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc04",					&GetFilterOptions,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "RefreshGameList",			&RefreshGameList,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "UpdateGameList",			&UpdateGameList,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "CancelActivity",	    	&CancelActivity,				    GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "IsGameListUpdating",		&IsGameListUpdating,				GOSVAR_INT,		0,				NetworkInstance);

	gosScript_RegisterCallback( "kldc07",					&ChatSend,							GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc08",					&FillPlayerRosterMechType,			GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc09",					&FillMechTypes,						GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc10",					&FillGameSettings,					GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterCallback( "kldc11",					&GetRASEntryUserNameAndPassword,	GOSVAR_INT,		0,				NetworkInstance);

	gosScript_RegisterVariable( "bandwidth",				&conDefault.bandwidth,				GOSVAR_INT,		0,				NetworkInstance);
	gosScript_RegisterVariable( "NetHardware"	,			&conDefault.connectiontype,			GOSVAR_INT,		0,				NetworkInstance);

    // jcem - start
    if (CTCL_IsConsole() || g_bCOOP) {
		CancelDialup(NetworkInstance, 0, NULL);
		LoadMPConnectionSettings(NetworkInstance, 0, NULL);
		InitConnectionWizard(NetworkInstance, 0, NULL);

        ConnectionIndex = 0;
        PreConnect(NetworkInstance, 0, NULL);
#if 0
        gosScript_ExecuteScript( SHELLSCRIPTS_PATH"Multiplayer\\Hostgame1.script", 0x1000, NetworkInstance);
	    gosScript_ExecuteScript( SHELLSCRIPTS_PATH"Mouse.script", 0x1700);
#endif
    } else if (CTCL_GetType() != _ECTCL_None) {
        // game or cameraship
    } else {
    // jcem - end
	gosScript_ExecuteScript( SHELLSCRIPTS_PATH"Multiplayer\\MultiplayerConsole.script", 0x1200, NetworkInstance);
	gosScript_ExecuteScript( SHELLSCRIPTS_PATH"Mouse.script", 0x1700);
    // jcem - start
    }
    // jcem - end

	return 1;//gConnectionType!=-1;
}

//========================================================================
//========================================================================
void __stdcall gos_NetEndGame()
{
	RAS::TerminateLibrary();

	ServerBrowser::ReleaseAll();
	ServerAdvertiser::ReleaseAll();
	UnRegisterData();
	gos_ShutdownNetwork();
	FreeString(LocalIPAddress);
}


bool __stdcall gos_NetDoneStartGame()
{
	UnRegisterData();
	return 1;
}


//========================================================================
//========================================================================
bool StringPurgeAndDuplicate(char * &szDest, const char *szSrc)
{
	gosASSERT(szSrc != NULL);

	if (szDest)
	{
		gos_Free(szDest);
		szDest=NULL;
	}

	int size=strlen(szSrc);
	szDest = (char *)gos_Malloc(size+1);
	if (szDest)
	{
		strcpy(szDest, szSrc);
		return true;
	}

	return false;
}


//========================================================================
//========================================================================
bool __stdcall PrepareDefaultServerAdvertisers(void)
{
	UnRegisterData();
	RegisterData();
	LoadMPConnectionSettings(NULL, 0, NULL);
	InitConnectionWizard(NULL, 0, NULL);
	return true;
}
