/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
--- HISTORICAL COMMENTS FOLLOW ---
* $Logfile: /DescentIII/Main/mtclient/mtclient.cpp $
* $Revision: 1.1.1.1 $
* $Date: 2003-08-26 03:58:40 $
* $Author: kevinb $
*
* Mastertracker Client DLL
*
* $Log: not supported by cvs2svn $
*
* 127 10/03/01 12:44a Kevin
* Smaller version of pxo packets
*
* 126 3/26/00 10:30p Kevin
* MOD Downloader for 1.4 patch.
*
* 125 3/20/00 12:29p Matt
* Merge of Duane's post-1.3 changes.
* Deleted Mac-only stricmp() function.
*
* 124 2/18/00 11:33p Kevin
* Fixed crash when sorting ping list bug, and clear the game list when
* joining a private lobby.
*
* 123 9/07/99 2:21p Kevin
* more CR/LF issues for the mac
*
* 122 9/07/99 10:24a Kevin
* Macintosh fixes!
*
* 121 9/02/99 3:16p Kevin
* Macintosh byte ordering fixes
*
* 120 8/24/99 5:47p Kevin
* Macintosh crap
*
* 119 8/24/99 10:39a Kevin
* Hopefully fixed the PXO return to chat bug
*
* 118 8/17/99 3:35p Kevin
* inverse sorts wouldn't show the last item! Doh!
*
* 117 8/17/99 1:52p Kevin
* fixed potential crash bugs as well as formatting for "CS Team Anarchy"
*
* 116 8/12/99 10:15a Kevin
* debugging stuff
*
* 115 8/10/99 12:53p Kevin
* fixed bug with return to chat & sorted gamelist
*
* 114 7/30/99 1:20p Kevin
* Fixed problems with sorted game list
*
* 113 7/26/99 11:45a Kevin
* possible return to chat crash fix
*
* 112 7/21/99 9:11a Kevin
* bandwidth reduction act #1
*
* 111 7/12/99 4:15p Kevin
* Changed the way we determine if we should report stats or not in PXO
*
* 110 7/07/99 3:38p Kevin
* Sorting in PXO gamelist!
*
* 109 7/06/99 5:52p Kevin
* PXO & multiplayer fixes for the patch
*
* 108 5/23/99 3:04a Jason
* fixed bug with player rankings not being updated correctly
*
* 107 5/23/99 2:38a Kevin
* fixed text overlapping thingy
*
* 106 5/20/99 9:17p Kevin
* removed invisible hotspot
*
* 105 5/17/99 5:19p Samir
* added ability for edit box to autoselect when hitting the max number of
* characters typable.
*
* 104 5/08/99 11:32a Kevin
* increased the gamelist update interval from pxo
*
* 103 5/05/99 5:23p Kevin
* fixed some bugs on the gamelist
*
* 102 5/05/99 11:04a Kevin
* added defer call to game over (previously it was only happening while
* writing stats
*
* 101 5/04/99 10:16p Kevin
* Fixed problem with 'set default screen'
*
* 100 5/04/99 5:39p Kevin
* connection dll & pxo game tracking improvements (added server type to
* list)
*
* 99 4/28/99 6:39p Kevin
* Build 182 fixes
*
* 98 4/27/99 1:54p Kevin
* Added pilot name to stats dialog
*
* 97 4/27/99 10:23a Kevin
* nifty titles for dialogs
*
* 96 4/25/99 5:02p Kevin
* Bunches of multiplayer UI improvements
*
* 95 4/24/99 11:59p Kevin
* game info dialog stuff
*
* 94 4/23/99 11:49p Kevin
*
* 93 4/22/99 3:43p Kevin
* Training missions show controls on screen
*
* 92 4/20/99 8:57p Jeff
* compile for Linux
*
* 91 4/19/99 7:56p Kevin
* ifdef'd out some win32 specific stuff
*
* 90 4/18/99 1:18p Kevin
* Demo2 build changes
*
* 89 4/17/99 3:44p Kevin
* Demo2 changes & fixes
*
* 88 4/16/99 6:00p Kevin
* Bunches of Demo stuff
*
* 87 4/14/99 1:37a Jeff
* fixed case mismatched #includes
*
* 86 4/02/99 12:19p Kevin
* Fixed chat server failed to connect
*
* 85 3/25/99 3:26p Kevin
* Made PXO games be based on your chat channel
*
* 84 3/17/99 4:08p Kevin
* Changed the way games appear and timeout in the game list.
*
* 83 3/05/99 11:35a Kevin
* new screens
*
* 82 3/04/99 12:07p Kevin
* Fixed stupid bug if you cancel out of connecting.
*
* 81 3/02/99 5:50p Kevin
* Ouch. Duplicate structures existed and were conflicting.
*
* 80 2/19/99 5:21p Kevin
* Fixed some connection DLLs and a Direct Sound bug with threads.
*
* 79 2/15/99 7:47p Jeff
* new pilot file class and read/write system checked in...should be more
* robust than old
*
* 78 2/03/99 4:20p Kevin
* Got multiplayer working with .mn3 files, and setup autodownloading
*
* 77 2/02/99 7:06p Jason
* added ranking system
*
* 76 1/23/99 3:20p Kevin
* Made gamelist boxes not sort
*
* 75 1/11/99 12:29p Jeff
* changes made not to call the module library directly
*
* 74 1/07/99 11:51a Kevin
* Added support for joining servers on alternate ports and hosting behind
* a proxy/firewall
*
* 73 1/04/99 5:43p Kevin
* new command line args
*
* 72 12/30/98 5:24p Kevin
* Added +name to specify a default pilot (for gamespy) fixed a gamespy
* bug, and improved the pxo dll game list screen
*
* 71 12/30/98 12:16p Kevin
* Auto Mission Download system
*
* 70 12/23/98 6:38p Kevin
* All UDP data (except gamespy) now uses one (registered) port number
*
* 69 12/14/98 10:53a Jason
* added bright player ships option
*
* 68 12/04/98 4:37p Kevin
* Fixed selection being reset in game lists...
*
* 67 12/01/98 12:47p Jason
* got rid of NF_DROPMISORDERED and added NF_USE_SMOOTHING
*
* 66 11/18/98 3:26p Kevin
* Put multiplayer options into con_dll.h
*
* 65 11/03/98 9:27a Kevin
* Added PXO message of the day
*
* 64 10/30/98 11:25a Kevin
* Message of the day for PXO
*
* 63 10/23/98 10:12a Kevin
* fixed bug when you hit cancel in the login screen
*
* 62 10/22/98 10:14a Kevin
* Made Stats dialog bigger
*
* 61 10/20/98 5:46p Kevin
* Gunboy and other fixes
*
* 60 10/20/98 2:07p Kevin
* changed tab order of login dialog, and changed strings
*
* 59 10/19/98 11:07p Kevin
* fixed bug
*
* 58 10/19/98 2:48p Kevin
* Added accurate weapon thingy for Chris
*
* 57 10/19/98 11:24a Kevin
* Fixed problem with help
*
* 56 10/17/98 2:32p Kevin
* FIxed problem with banned users getting stuck on the ban message
* screen.
*
* 55 10/17/98 12:46p Kevin
* Beta 4 fixes
*
* 54 10/15/98 3:29p Kevin
* Fixed dlls to not require runtime debug libraries in release builds
*
* 53 10/15/98 12:08p Kevin
* Changed game list to line up differently
*
* 52 10/13/98 3:42p Kevin
* bug fixes
*
* 51 10/12/98 8:39p Kevin
* removed mprintf's and fixed some smallish bugs
*
* 50 10/12/98 11:02a Kevin
* Changed directory of mtav file
*
* 49 10/09/98 2:56p Kevin
* Changed IP addresses for PXO demo
*
* 48 10/08/98 3:37p Jeff
* removed time_left from Netgame
*
* 47 10/05/98 11:00a Kevin
* Fixed bug with uninitialized variable
*
* 46 10/01/98 11:37a Kevin
* UI fixes and stuff
*
* 45 9/30/98 12:33p Kevin
* Added web launching support
*
* 44 9/29/98 2:23p Kevin
* More UI tweaks
*
* 43 9/28/98 4:55p Kevin
*
* 42 9/28/98 4:21p Kevin
* Redesigned game list menus
*
* 41 9/28/98 11:10a Kevin
* fuxed returning onf uninitialized variable
*
* 40 9/28/98 9:53a Kevin
* Fixing misc UI problems, and fixed some bugs that VC 6 found
*
* 39 9/25/98 11:07a Kevin
* fixed columns to line up and cleaned up some PXO bugs
*
* 38 9/24/98 12:50p Kevin
* Added UI for rotational velocity and drop out of order packets in net
* games
*
* 37 9/23/98 6:33p Kevin
* Fixed load settings
*
* 36 9/23/98 2:55p Kevin
* Saved multi config and changed UI to conform
*
* 35 9/22/98 3:55p Kevin
* Removed obsolete function
*
* 34 9/22/98 2:29p Kevin
* moved ships allowed code out of dll and into main app. Also added
* powerup exclusions
*
* 33 9/21/98 11:19a Kevin
* check protocol before entering multiplayer screens
*
* 32 9/16/98 8:06p Jason
* got mastertracker working with the dedicated server
*
* 31 9/14/98 12:34p Kevin
* Fixed problems with using strtok and grtext functions.
*
* 30 9/09/98 12:41p Kevin
* Fixed up some UI issues
*
* 29 9/04/98 1:51p Kevin
* implemented asyncronous gethostbyname
*
* 28 9/02/98 6:54p Kevin
* Fixed general directplay support up, and got modem-modem working
*
* 27 8/31/98 10:14a Kevin
* Misc. multi-UI fixes
*
* 26 8/27/98 5:03p Kevin
* Prettied up multiplayer screens and fixed some bugs.
*
* 25 8/26/98 3:28p Samir
* put focus thing back in
*
* 24 8/25/98 6:33p Kevin
* PXO screens
*
* 23 8/24/98 5:04p Kevin
* Made msn files have the option to not be playable in multiplayer
*
* 22 8/24/98 10:42a Kevin
* Updated DLL for directplay and PXO background
*
* 21 8/19/98 11:50a Kevin
* Got DirectPlay IPX working, and localized connection DLLs
*
* 20 8/17/98 2:26p Kevin
* fixed auto update dll directory
*
* 19 8/17/98 11:00a Kevin
* Moved DLLs into subdirectories
*
* 18 8/07/98 12:39p Jeff
* added "allowed ships" to multiplayer options
*
* 17 7/27/98 5:31p Kevin
* Sound/Bitmap exchange system
*
* 16 7/22/98 4:34p Kevin
* fixed bug in MT gamelist with >10 games
*
* 15 7/21/98 1:49p Kevin
* IPX support and peer-peer option for multi
*
* 14 7/20/98 2:34p Kevin
* Re-wrote the DLL wrapper, to allow for better expandability
*
* 11 6/30/98 3:20p Kevin
* fixed ping time
*
* 10 6/25/98 10:03a Kevin
* Minor chat fixes in PXO
*
* 9 6/24/98 6:40p Kevin
* Added help to main dll menu
*
* 8 6/24/98 3:24p Kevin
* Updated PXO screens with chat, etc.
*
* 7 6/18/98 4:49p Kevin
* Updated multiplayer menus
*
* 6 6/11/98 1:56p Jeff
* looks for d3m files instead of dll
*
* 5 6/05/98 2:16p Jeff
* Changes made so Dynamic loading of DLLs done through module library
*
* 4 6/05/98 12:40p Kevin
*
* 3 6/01/98 3:52p Kevin
* changed listbox item to be white
*
* 2 6/01/98 10:10a Kevin
* Added DLL connection interface and auto update DLL
*
* 1 5/18/98 12:47p Kevin
*
* $NoKeywords: $
*/
#include "ui.h"
#include "newui.h"
#include "grdefs.h"
#include "player.h"
#include "game.h"
#include "pilot.h"
#include "ddio_common.h"
#include "gamefont.h"
#include "mt_net.h"
#include "mtgametrack.h"
#include "module.h"
#include "inetgetfile.h"
#include "chat_api.h"
#include "mtstrings.h"
#define TXT_DLL_SAVESETTINGS TXT(79)
#define TXT_DLL_LOADSETTINGS TXT(80)
#define TXT_GEN_MPLYROPTIONS TXT_PXO_MPLYROPTIONS
#define TXT_GEN_TIMELIMIT TXT_PXO_TIMELIMIT
#define TXT_GEN_KILLGOAL TXT_PXO_KILLGOAL
#define TXT_GEN_PPS TXT_PXO_PPS
#define TXT_GEN_RESPAWNRATE TXT_PXO_RESPAWNRATE
#define TXT_GEN_MAXPLAYERS TXT_PXO_MAXPLAYERS
#define TXT_GEN_PREVMENU TXT_PXO_PREVMENU
#define TXT_GEN_CANCEL TXT_PXO_CANCEL
#define TXT_GEN_CFGALLOWEDSHIP TXT_PXO_CFGALLOWEDSHIP
#define TXT_GEN_USEROTVEL TXT_PXO_USEROTVEL
#define TXT_GEN_USEROTVEL TXT_PXO_USEROTVEL
#define TXT_GEN_USESMOOTHING TXT_PXO_USESMOOTHING
#define TXT_GEN_CLIENTSERVER TXT_PXO_CLIENTSERVER
#define TXT_GEN_PEERPEER TXT_PXO_PEERPEER
#define TXT_GEN_ACC_WEAP_COLL TXT_PXO_ACC_WEAP_COLL
#define TXT_GEN_BRIGHT_PLAYERS TXT_PXO_BRIGHT_PLAYERS
#define MULTI_USE_ALL_OPTIONS 1
#include "mtclient.h"
#include "mtpilottrack.h"
#include "DLLUiItems.h"
char Ourlobby[50] = "";
bool Login_aborted = false;
bool Auto_start=false;
int Bypass_chat = 0;
int ChatStarted = 0;
extern int Motd_version;
d3_net_game_data_tiny DLLD3_tracker_info;
#define MTADDNEWURL TXT_PXO_REGURL
#define MAX_GAMELIST_ITEMS 300
pxo_game_list PXOGamelist[MAX_GAMELIST_ITEMS];
int NextGameItemNo = 0;
ushort DLLPXOPort = 0;
void AutoLoginAndStartGame ();
int GetGameByHandle(unsigned int handle)
{
int j;
for(j=0;j<*DLLNum_network_games_known;j++)
{
if(DLLNetwork_games[j].handle==handle)
{
return j;
}
}
return -1;
}
int GetPXOItemByHandle(unsigned int handle)
{
int i;
for(i=0;iSERVER_TYPE_MAX_LEN)
{
server_type[game_type_pos] = 0;
game_type_pos--;
}
sprintf(fmt,"%.20s\t\x02\x02b%s\x02\x45%.15s\x02\x63%d\x02\x6d%d/%d\x02\x7e%.3f",DLLNetwork_games[k].name,server_type,DLLNetwork_games[k].mission_name,
DLLNetwork_games[k].level_num,DLLNetwork_games[k].curr_num_players,DLLNetwork_games[k].max_num_players,
DLLNetwork_games[k].server_response_time);
}
void UpdateGamelist(void *lb)
{
int i,j;
//Look for items that we need to remove
for(i=0;iname);
//strcpy(DLLD3_tracker_info.mission_name,DLLNetgame->mission);
strcpy(DLLD3_tracker_info.lobby,DLLPXO_hosted_lobby_name);
StartTrackerGame(&DLLD3_tracker_info);
break;
case MT_EVT_GAME_OVER:
DoMTGameOver();
/*
if(!All_ok)
break;
//menu.... start a game, or join a game
if(MainMultiplayerMenu())
{
*DLLMultiGameStarting = 1;
}
else
{
*DLLMultiGameStarting = 0;
}
*/
break;
case MT_AUTO_LOGIN:
if(!DLLTCP_active)
{
DLLDoMessageBox(TXT_PXO_ERROR,TXT_PXO_NO_TCPIP,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
*DLLMultiGameStarting = 0;
break;
}
InitMTSockets();
if(!All_ok)
{
*DLLMultiGameStarting = 0;
return;
}
AutoLoginAndJoinGame();
break;
case MT_AUTO_START:
InitMTSockets();
if(!All_ok)
{
*DLLMultiGameStarting = 0;
return;
}
Auto_start=true;
AutoLoginAndStartGame();
break;
case MT_RETURN_TO_GAME_LIST:
Bypass_chat = 1;
//menu.... start a game, or join a game
if(MainMultiplayerMenu())
{
*DLLMultiGameStarting = 1;
}
else
{
*DLLMultiGameStarting = 0;
}
break;
}
}
#ifdef MACINTOSH
#pragma export off
#endif
int LoginMasterTracker(void)
{
void * title_text = DLLCreateNewUITextItem(TXT_PXO_LOGINMASTERTRKR,UICOL_WINDOW_TITLE);
void * cancel_on_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_HI);
void * login_on_text = DLLCreateNewUITextItem(TXT_PXO_LOGIN,UICOL_HOTSPOT_HI);
void * cancel_off_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_LO);
void * login_off_text = DLLCreateNewUITextItem(TXT_PXO_LOGIN,UICOL_HOTSPOT_LO);
void * login_id_text = DLLCreateNewUITextItem(TXT_PXO_LOGINID,UICOL_TEXT_NORMAL);
void * tracker_id_text = DLLCreateNewUITextItem(TXT_PXO_TRACKERID,UICOL_TEXT_NORMAL);
void * password_text = DLLCreateNewUITextItem(TXT_PXO_PASSWORD,UICOL_TEXT_NORMAL);
void * new_prof_on_text = DLLCreateNewUITextItem(TXT_PXO_CREATENEWPROFILE,UICOL_HOTSPOT_HI);
void * new_prof_off_text = DLLCreateNewUITextItem(TXT_PXO_CREATENEWPROFILE,UICOL_HOTSPOT_LO);
void * blank_text = DLLCreateNewUITextItem(TXT_PXO_BLANK,GR_BLACK);
int exit_menu=0;
int ret=0;
int loginlen = LOGIN_LEN;
int trackerlen = TRACKER_ID_LEN;
int passlen = PASSWORD_LEN;
void * main_wnd = DLLNewUIGameWindowCreate(TRACKER_MENU_X, TRACKER_MENU_Y, TRACKER_MENU_W, TRACKER_MENU_H, UIF_PROCESS_ALL | UIF_CENTER | NUWF_TITLEMED );
void * title = DLLTextCreate(main_wnd,title_text,0,7,UIF_CENTER);
void * password = DLLTextCreate(main_wnd,password_text,30,130,UIF_CENTER);
void * login_id = DLLTextCreate(main_wnd,login_id_text,50,80,UIF_CENTER);
void * pass_edit = DLLEditCreate(main_wnd,UID_OK,100,140,130,15,UIF_CENTER|UIED_PASSWORD);
void * login_hs = DLLHotSpotCreate(main_wnd,UID_OK,KEY_ENTER,login_off_text,login_on_text,60,TRACKER_MENU_H-80, 60, 20,0);
void * cancel_hs = DLLHotSpotCreate(main_wnd,UID_CANCEL,KEY_ESC,cancel_off_text,cancel_on_text,130,TRACKER_MENU_H-80, 60, 20,0);
void * new_id_hs = DLLHotSpotCreate(main_wnd,4,KEY_N,new_prof_off_text,new_prof_on_text,0,45,120,20,UIF_CENTER|UIF_FIT);
void * login_edit = DLLEditCreate(main_wnd,3,100,90,130,15,UIF_CENTER);
//Read defaults
DLLDatabaseRead("TrackerLogin",szloginid,&loginlen);
DLLDatabaseRead("TrackerPassword",szpassword,&passlen);
DLLEditSetText(login_edit,szloginid);
DLLEditSetText(pass_edit,szpassword);
DLLNewUIGameWindowOpen(main_wnd);
while (!exit_menu)
{
int res;
res = DLLDoUI();
// handle all UI results.
switch(res)
{
case 3:
DLLmprintf((0,"Got event 3!\n"));
break;
case 4:
#ifdef WIN32
ShellExecute( NULL,"open",MTADDNEWURL,NULL,NULL,SW_SHOW);
#endif
break;
case UID_OK:
{
DLLEditGetText(login_edit,szloginid,LOGIN_LEN);
DLLEditGetText(pass_edit,szpassword,PASSWORD_LEN);
DLLDatabaseWrite("TrackerLogin",szloginid,strlen(szloginid)+1);
DLLDatabaseWrite("TrackerPassword",szpassword,strlen(szpassword)+1);
if((!*szloginid) || (!*szpassword))
{
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_BADLOGIN,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
break;
}
//Fill out the validate struct and send off the packet
validate_id_request val_user;
strcpy(val_user.tracker_id,sztrackerid);
strcpy(val_user.login,szloginid);
strcpy(val_user.password,szpassword);
DLLCreateSplashScreen(TXT_PXO_CONNECTING,1);
int valret = ValidateUser(&val_user,sztrackerid);
while(valret==0)
{
valret = ValidateUser(NULL,NULL);
res = DLLPollUI();
if(res==99)
{
valret = -2;
}
DLLDescentDefer();
}
DLLCloseSplashScreen();
if(valret == 1)
{
//User was validated
DLLmprintf ((0,"Mastertracker user validated!\n"));
//Run this to make sure we properly ACK the server.
for(int j=0;j<10;j++) PollPTrackNet();
strcpy(DLLTracker_id,sztrackerid);
strcpy(DLLMPlayers[DLLPlayer_num].tracker_id,sztrackerid);
exit_menu = 1;
ret = 1;
break;
}
else if(valret == -1)
{
//User invalid!
DLLmprintf ((0,"Mastertracker user not validated!\n"));
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_BADLOGIN,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
//Run this to make sure we properly ACK the server.
for(int j=0;j<10;j++) PollPTrackNet();
break;
}
else
{
//timeout waiting for tracker!
DLLmprintf ((0,"Mastertracker timeout!\n"));
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_TIMEOUTMT,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
//Run this to make sure we properly ACK the server.
for(int j=0;j<10;j++) PollPTrackNet();
break;
}
}
case UID_CANCEL:
exit_menu = 1;
ret = 0;
break;
}
}
DLLNewUIGameWindowClose(main_wnd);
DLLNewUIGameWindowDestroy(main_wnd);
DLLRemoveUITextItem(title_text);
DLLRemoveUITextItem(cancel_on_text);
DLLRemoveUITextItem(login_on_text);
DLLRemoveUITextItem(cancel_off_text);
DLLRemoveUITextItem(login_off_text);
DLLRemoveUITextItem(login_id_text);
DLLRemoveUITextItem(tracker_id_text);
DLLRemoveUITextItem(password_text);
DLLRemoveUITextItem(new_prof_on_text);
DLLRemoveUITextItem(new_prof_off_text);
DLLRemoveUITextItem(blank_text);
DLLDeleteUIItem(main_wnd);
DLLDeleteUIItem(title);
DLLDeleteUIItem(cancel_hs);
DLLDeleteUIItem(login_hs);
DLLDeleteUIItem(new_id_hs);
DLLDeleteUIItem(login_edit);
DLLDeleteUIItem(password);
DLLDeleteUIItem(login_id);
DLLDeleteUIItem(pass_edit);
return ret;
}
// The first multiplayer menu that the user will see...all multiplayer stuff is
// reached from this menu
// Returns true if we're starting a multiplayer game
#define CONNECT_PXO_TIMEOUT 60.0
#define MAX_CHAT_SEND_LEN 200
#define MAX_CHAT_CHANNELS 50
#define CHAT_INFO_LEN 200
#define CHAT_COUNT_LEN 10
#define CHAT_MAX_USERLIST 200
#define CHAT_USER_REFRESH_TIME 5
#define CHAT_LIST_REFRESH_TIME 10
struct
{
char name[CHAT_INFO_LEN];
char origname[CHAT_INFO_LEN];
char topic[CHAT_INFO_LEN];
char count[CHAT_COUNT_LEN];
char games[CHAT_COUNT_LEN];
}chan_info[MAX_CHAT_CHANNELS];
int MainMultiplayerMenu ()
{
DLLmprintf((0,"%d",DESCENT3_BLOCK_SIZE));
if(!ShowMessageOfTheDay())
{
return 0;
}
DLLmprintf((0,"Inside MainMultiplayerMenu()\n"));
if(Bypass_chat && !ChatStarted)
{
int rcode1 = SearchMasterTrackerGameMenu();
if(rcode1==-1)
rcode1 = 0;
return rcode1;
}
DLLToggleUICallback(0);
ChatStarted = 1;
void * title_text = DLLCreateNewUITextItem(TXT_PXO_CONNECTING,UICOL_WINDOW_TITLE);
void * cancel_on_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_HI);
void * cancel_off_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_LO);
void * exit_on_text = DLLCreateNewUITextItem(TXT_PXO_EXIT,UICOL_HOTSPOT_HI);
void * exit_off_text = DLLCreateNewUITextItem(TXT_PXO_EXIT,UICOL_HOTSPOT_LO);
void * priv_msg_on_text = DLLCreateNewUITextItem(TXT_PXO_SENDPRIV,UICOL_HOTSPOT_HI);
void * priv_msg_off_text = DLLCreateNewUITextItem(TXT_PXO_SENDPRIV,UICOL_HOTSPOT_LO);
void * join_lobby_on_text = DLLCreateNewUITextItem(TXT_PXO_JOINPRIV,UICOL_HOTSPOT_HI);
void * join_lobby_off_text = DLLCreateNewUITextItem(TXT_PXO_JOINPRIV,UICOL_HOTSPOT_LO);
void * join_chan_on_text = DLLCreateNewUITextItem(TXT_PXO_JOINCHAN,UICOL_HOTSPOT_HI);
void * join_chan_off_text = DLLCreateNewUITextItem(TXT_PXO_JOINCHAN,UICOL_HOTSPOT_LO);
void * find_pilot_on_text = DLLCreateNewUITextItem(TXT_PXO_FINDPILOT,UICOL_HOTSPOT_HI);
void * find_pilot_off_text = DLLCreateNewUITextItem(TXT_PXO_FINDPILOT,UICOL_HOTSPOT_LO);
void * get_pilot_on_text = DLLCreateNewUITextItem(TXT_PXO_GETPILOTINFO,UICOL_HOTSPOT_HI);
void * get_pilot_off_text = DLLCreateNewUITextItem(TXT_PXO_GETPILOTINFO,UICOL_HOTSPOT_LO);
void * game_on_text = DLLCreateNewUITextItem(TXT_PXO_JOINSTARTGAME,UICOL_HOTSPOT_HI);
void * game_off_text = DLLCreateNewUITextItem(TXT_PXO_JOINSTARTGAME,UICOL_HOTSPOT_LO);
void * send_on_text = DLLCreateNewUITextItem(TXT_PXO_SEND,UICOL_HOTSPOT_HI);
void * send_off_text = DLLCreateNewUITextItem(TXT_PXO_SEND,UICOL_HOTSPOT_LO);
char fmtlobbytext[200];
sprintf(fmtlobbytext,TXT_PXO_YOUAREINLOBBY,Ourlobby);
void * lobby_text = DLLCreateNewUITextItem(fmtlobbytext,UICOL_TEXT_AUX);
void * blank_text = DLLCreateNewUITextItem(TXT_PXO_BLANK,UICOL_TEXT_AUX);
char sendline[MAX_CHAT_SEND_LEN];
int exit_menu=0;
int ret=0;
int res;
char *p;
int i;
float lastlisttime = 0;
float lastchanlisttime = 0;
void *chan_ti[MAX_CHAT_CHANNELS];
void *user_ti[CHAT_MAX_USERLIST];
char selpilot[MAX_CHAT_SEND_LEN];
char oldselchan[200];
for(i=0;iCONNECT_PXO_TIMEOUT) )
{
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_CANTCONNECT,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
//Go ahead to the game screen.
//SearchMasterTrackerGameMenu();
int rcode1 = SearchMasterTrackerGameMenu();
if(rcode1==-1)
rcode1 = 0;
ret = rcode1;
exit_menu = 1;
DLLCloseSplashScreen();
DLLNewUIWindowClose(main_wnd);
goto shutdownpxo;
//gotcancel = 1;
break;
}
res = DLLPollUI();
if(res==99)
{
SearchMasterTrackerGameMenu();
gotcancel = 1;
}
}while((!gotcancel) && (chat_connected==0));
DLLCloseSplashScreen();
if(gotcancel)
{
ret = 0;
exit_menu = 1;
DLLNewUIWindowClose(main_wnd);
goto shutdownpxo;
}
DLLmprintf((0,"Connected to chat server!\n"));
if(!JoinNewLobby("#autoselect"))
{
ret = 0;
exit_menu = 1;
}
SendChatString("/list");
//DLLNewUIWindowSetFocusOnEditGadget(send_edit,main_wnd);
while (!exit_menu)
{
//Handle commands...
cmd = GetChatCommandFromQueue();
if(cmd)
{
switch(cmd->command)
{
case CC_USER_JOINING:
case CC_USER_LEAVING:
case CC_KICKED:
case CC_NICKCHANGED:
// We will ignore all these things for now
break;
case CC_YOURCHANNEL:
{
strcpy(Ourlobby,cmd->data);
char fmtlobbytext[200];
char cleanlobby[50];
memset(cleanlobby,0,29);
strcpy(cleanlobby,Ourlobby+1);
for(int l=0;l<18;l++)
{
if(cleanlobby[l]=='_') cleanlobby[l] = ' ';
//if(cleanlobby[l]==NULL) cleanlobby[l]= ' ';
}
sprintf(fmtlobbytext,TXT_PXO_YOUAREINLOBBY,cleanlobby);
DLLRemoveUITextItem(lobby_text);
DLLGadgetDestroy(lobby_txt_gadget);
DLLDeleteUIItem(lobby_txt_gadget);
lobby_text = DLLCreateNewUITextItem(fmtlobbytext,UICOL_TEXT_AUX);
lobby_txt_gadget = DLLTextCreate(main_wnd,lobby_text,0,450,UIF_CENTER);
//Now update the text on the bottom of the screen
}
break;
case CC_DISCONNECTED:
//Display a message box letting the user know we are disconnected.
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_CHATDISCONNECTED,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
DLLNewUIWindowClose(main_wnd);
exit_menu = 1;
break;
default:
DLLmprintf((0,"Warning: Received an unknown chat command!\n"));
break;
}
}
if(exit_menu)
break;
p = GetChatText();
if(p)
{
DLLUIConsoleGadgetputs(console_item,p);
DLLUIConsoleGadgetputs(console_item,"\x0a\x0d");
}
//refresh the userlist
if((DLLtimer_GetTime()-lastlisttime)>CHAT_USER_REFRESH_TIME)
{
lastlisttime = DLLtimer_GetTime();
p = GetChatUserList();
if(p)
{
char * oldsel = DLLOldListGetItem(user_list,DLLOldListGetSelectedIndex(user_list));
oldseluser[0] = 0;
if(oldsel)
strcpy(oldseluser,oldsel);
void *old_ti = NULL;// = DLLCreateNewUITextItem(TXT_PXO_JOINSTARTGAME,GR_WHITE);
//int oldsel = DLLOldListGetSelectedIndex(user_list);
//void * old_ti =
DLLOldListRemoveAll(user_list);
for(i=0;iCHAT_LIST_REFRESH_TIME)
{
lastchanlisttime = DLLtimer_GetTime();
SendChatString("/list");
}
p = GetChannelList();
if(p)
{
char * pchanlist;
pchanlist = (char *)DLLmem_malloc(strlen(p)+1);
memset(pchanlist,0,strlen(p));
strcpy(pchanlist,p);
char seps[] = "$";
char *tokp=NULL;
char *nexttok;
//tokp = strtok(pchanlist,seps);
nexttok = strchr(pchanlist,'$');
if(nexttok)
{
*nexttok = NULL;
nexttok++;
tokp = nexttok;
if(nexttok)
{
nexttok = strchr(nexttok,'$');
if(nexttok)
{
*nexttok = NULL;
nexttok++;
}
}
}
if(tokp)
{
//Remove all previous items
DLLmprintf((0,"Refreshing channel list\n"));
//get the text of the currently selected channel.
//char * oldsel = DLLOldListGetItem(chan_list,DLLOldListGetSelectedIndex(chan_list));
//
int selitem = DLLOldListGetSelectedIndex(chan_list);
char * oldsel = NULL;
oldselchan[0] = 0;
if( (selitem>0) && (selitem < MAX_CHAT_CHANNELS) )
{
oldsel = chan_info[selitem].origname;
strcpy(oldselchan,oldsel);
}
DLLOldListRemoveAll(chan_list);
for(i=0;iname,net2->name);
}
break;
case SORT_GAMETYPE:
{
return stricmp(net1->scriptname,net2->scriptname);
}
break;
case SORT_MISSION:
{
return stricmp(net1->mission_name,net2->mission_name);
}
break;
case SORT_LEVEL:
{
if(net1->level_num==net2->level_num)
return 0;
else
return (net1->level_num - net2->level_num);
}
break;
case SORT_PLAYERS:
{
if(net1->curr_num_players==net2->curr_num_players)
return 0;
else
return (net1->curr_num_players - net2->curr_num_players);
}
break;
case SORT_PING:
{
if(net1->server_response_time==net2->server_response_time)
return 0;
else
return (net1->server_response_time < net2->server_response_time)?1:-1;
}
break;
}
return 0;
}
void ResortGameList(void *lb,int type, bool invert)
{
if(!*DLLNum_network_games_known)
{
return;
}
//Make a copy of the games list
network_game *net_game_copy;
net_game_copy = (network_game *)DLLmem_malloc(sizeof(network_game)*(*DLLNum_network_games_known));
memcpy(net_game_copy,&DLLNetwork_games[0],sizeof(network_game)*(*DLLNum_network_games_known));
//Set the sort type
sort_type = type;
//Do the actual sort
qsort(net_game_copy,*DLLNum_network_games_known,sizeof(network_game),net_game_compare);
//Now populate the list in the order sorted...
NextGameItemNo = 0;
DLLListRemoveAll(lb);
int i;
if(!invert)
{
for(i=0;i<*DLLNum_network_games_known;i++)
{
int pxo_item = GetPXOItemByHandle(net_game_copy[i].handle);
if(pxo_item!=-1)
{
PXOGamelist[pxo_item].lb_no = NextGameItemNo;
NextGameItemNo++;
DLLListAddItem(lb,PXOGamelist[pxo_item].ti);
}
}
}
else
{
for(i=*DLLNum_network_games_known;i>=0;i--)
{
int pxo_item = GetPXOItemByHandle(net_game_copy[i].handle);
if(pxo_item!=-1)
{
PXOGamelist[pxo_item].lb_no = NextGameItemNo;
NextGameItemNo++;
DLLListAddItem(lb,PXOGamelist[pxo_item].ti);
}
}
}
DLLmem_free(net_game_copy);
}
#define GET_MT_GAME_TIME 5
#define REQ_GAME_LIST_INTERVAL 8
#define GET_INFO_ID 50
int SearchMasterTrackerGameMenu ()
{
int exit_menu=0;
int cury=40;
int ret=0;
int res;
game_list *games = NULL;
int i=0;
float last_req_time;
char selgame[200];
void * selti = NULL;
void * return_text_on = DLLCreateNewUITextItem(TXT_PXO_RETURNTOCHAT,UICOL_HOTSPOT_HI);
void * return_text_off = DLLCreateNewUITextItem(TXT_PXO_RETURNTOCHAT,UICOL_HOTSPOT_LO);
void * game_head_text = DLLCreateNewUITextItem(TXT_PXO_GAMELISTHDR,UICOL_TEXT_NORMAL);
void * exit_on_text = DLLCreateNewUITextItem(TXT_PXO_EXIT,UICOL_HOTSPOT_HI);
void * exit_off_text = DLLCreateNewUITextItem(TXT_PXO_EXIT,UICOL_HOTSPOT_LO);
void * join_on_text = DLLCreateNewUITextItem(TXT_PXO_JOINSEL,UICOL_HOTSPOT_HI);
void * join_off_text = DLLCreateNewUITextItem(TXT_PXO_JOINSEL,UICOL_HOTSPOT_LO);
void * start_on_text = DLLCreateNewUITextItem(TXT_PXO_STARTNEW,UICOL_HOTSPOT_HI);
void * start_off_text = DLLCreateNewUITextItem(TXT_PXO_STARTNEW,UICOL_HOTSPOT_LO);
void * gname_on_text = DLLCreateNewUITextItem(TXT_PXO_GAMENAME2,UICOL_HOTSPOT_HI);
void * gname_off_text = DLLCreateNewUITextItem(TXT_PXO_GAMENAME2,UICOL_HOTSPOT_LO);
void * gtype_on_text = DLLCreateNewUITextItem(TXT_PXO_GAMETYPE,UICOL_HOTSPOT_HI);
void * gtype_off_text = DLLCreateNewUITextItem(TXT_PXO_GAMETYPE,UICOL_HOTSPOT_LO);
void * msn_on_text = DLLCreateNewUITextItem(TXT_PXO_MISSION,UICOL_HOTSPOT_HI);
void * msn_off_text = DLLCreateNewUITextItem(TXT_PXO_MISSION,UICOL_HOTSPOT_LO);
void * lvl_on_text = DLLCreateNewUITextItem(TXT_PXO_LEVEL,UICOL_HOTSPOT_HI);
void * lvl_off_text = DLLCreateNewUITextItem(TXT_PXO_LEVEL,UICOL_HOTSPOT_LO);
void * plrs_on_text = DLLCreateNewUITextItem(TXT_PXO_PLAYERS,UICOL_HOTSPOT_HI);
void * plrs_off_text = DLLCreateNewUITextItem(TXT_PXO_PLAYERS,UICOL_HOTSPOT_LO);
void * ping_on_text = DLLCreateNewUITextItem(TXT_PXO_PING,UICOL_HOTSPOT_HI);
void * ping_off_text = DLLCreateNewUITextItem(TXT_PXO_PING,UICOL_HOTSPOT_LO);
char fmt_textstr[200];
sprintf(fmt_textstr,TXT_PXO_MAKEGAMEDEFAULT,28);
void * default_on_text = DLLCreateNewUITextItem(fmt_textstr,UICOL_HOTSPOT_HI);
sprintf(fmt_textstr,TXT_PXO_MAKEGAMEDEFAULT,28);
void * default_off_text = DLLCreateNewUITextItem(fmt_textstr,UICOL_HOTSPOT_LO);
void * game_hdr_text = DLLCreateNewUITextItem(TXT_PXO_GAME_HDR,UICOL_WINDOW_TITLE);
void * info_on_text = DLLCreateNewUITextItem("",UICOL_HOTSPOT_HI);
void * info_off_text = DLLCreateNewUITextItem("",UICOL_HOTSPOT_LO);
memset (PXOGamelist,0,sizeof(PXOGamelist));
NextGameItemNo = 0;
void *return_hs;
void * set_dft_hs;
void * net_game_txt_items[MAX_NET_GAMES];
int a;
bool hardexit = false;
for(a=0;agame_name[i];
if(games->game_type==GT_D3TNG)
{
DLLSearchForGamesPXO(games->game_server[i],games->game_port[i]);
}
else
{
if(games->game_server[i] && games->game_port[i])
{
DLLmprintf((0,"Bad bad bad!!!!\n"));
DLLSearchForGamesPXO(games->game_server[i],games->game_port[i]);
}
}
}
games = NULL;
}
if((DLLtimer_GetTime()-last_req_time)>REQ_GAME_LIST_INTERVAL)
{
last_req_time=DLLtimer_GetTime();
RequestGameList();
*DLLMulti_Gamelist_changed = true;
int selno = DLLListGetSelectedIndex(game_list);
if(selno>=0)
{
strcpy(selgame,DLLNetwork_games[selno].name);
}
else
{
selgame[0] = NULL;
}
}
DLLUpdateAndPackGameList();
if((itemp = DLLSearchForGamesPXO(0,0))||*DLLMulti_Gamelist_changed)
{
UpdateGamelist(game_list);
}
if(res==-1)
{
continue;
}
// handle all UI results.
switch(res)
{
case 5:
// Hard exit. Don't return to chat if in bypass chat mode
hardexit = true;
DLLNewUIWindowClose(main_wnd);
exit_menu = 1;
break;
case 6:
//Double click on listbox, or join selected hit.
if(*DLLNum_network_games_known)
{
//Get the appropriate game address
int gameno;
gameno = DLLListGetSelectedIndex(game_list);
int gameid = GetGameByLBNo(gameno);
if(gameid==-1)
break;
gameno = gameid;
DLLmprintf((0,"Selected item is %s\n",DLLNetwork_games[gameno].name));
network_address s_address;
s_address.connection_type = NP_TCP;
memcpy (&s_address.address,&DLLNetwork_games[gameno].addr,sizeof(network_address));
s_address.port=DLLNetwork_games[gameno].addr.port;
*DLLGame_is_master_tracker_game = 1;
DLLMultiStartClient (NULL);
if(DLLDoPlayerMouselookCheck(DLLNetwork_games[gameno].flags))
{
char script_file[500];
sprintf(script_file,"%s.d3m",DLLNetwork_games[gameno].scriptname);
if(DLLCheckGetD3M(script_file))
{
//Check to see if this mission exists!
if(DLLmsn_CheckGetMission(&s_address,DLLNetwork_games[gameno].mission))
{
if ((DLLTryToJoinServer (&s_address)))
{
DLLmprintf ((0,"Menu: Game joined!\n"));
DLLNewUIWindowClose(main_wnd);
exit_menu=1;
ret=1;
}
else
{
DLLNewUIWindowClose(main_wnd);
DLLNewUIWindowOpen(main_wnd);
}
}
}
}
}
else
{
DLLListRemoveAll(game_list);
last_req_time = DLLtimer_GetTime() - (REQ_GAME_LIST_INTERVAL*2);
DLLDoMessageBox(TXT_PXO_ERROR,TXT_PXO_NO_GAMES,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
}
break;
case 7:
//Start a new game
DLLNewUIWindowClose(main_wnd);
*DLLGame_is_master_tracker_game = 1;
if (StartMultiplayerGameMenu())
{
exit_menu=1;
ret=1;
}
else
{
DLLNewUIWindowOpen(main_wnd);
}
break;
case 8:
// We just want to return to chat, not totally exit PXO
DLLNewUIWindowClose(main_wnd);
exit_menu = 1;
ret = 0;
break;
case 9:
// Change the current selection
{
int bypass_chat_curr_val;
DLLDatabaseReadInt("BypassChat",&bypass_chat_curr_val);
DLLRemoveUITextItem(default_on_text);
DLLRemoveUITextItem(default_off_text);
DLLGadgetDestroy(set_dft_hs);
DLLDeleteUIItem(set_dft_hs);
if(bypass_chat_curr_val)
{
bypass_chat_curr_val = 0;
DLLDatabaseWriteInt("BypassChat",bypass_chat_curr_val);
sprintf(fmt_textstr,TXT_PXO_MAKEGAMEDEFAULT,28);
default_on_text = DLLCreateNewUITextItem(fmt_textstr,UICOL_HOTSPOT_HI);
sprintf(fmt_textstr,TXT_PXO_MAKEGAMEDEFAULT,28);
default_off_text = DLLCreateNewUITextItem(fmt_textstr,UICOL_HOTSPOT_LO);
set_dft_hs = DLLHotSpotCreate(main_wnd,9,0,default_off_text,default_on_text,490,setdfty,300,15,UIF_CENTER);
}
else
{
bypass_chat_curr_val = 1;
DLLDatabaseWriteInt("BypassChat",bypass_chat_curr_val);
sprintf(fmt_textstr,TXT_PXO_MAKEGAMEDEFAULT,29);
default_on_text = DLLCreateNewUITextItem(fmt_textstr,UICOL_HOTSPOT_HI);
sprintf(fmt_textstr,TXT_PXO_MAKEGAMEDEFAULT,29);
default_off_text = DLLCreateNewUITextItem(fmt_textstr,UICOL_HOTSPOT_LO);
set_dft_hs = DLLHotSpotCreate(main_wnd,9,0,default_off_text,default_on_text,490,setdfty,300,15,UIF_CENTER);
}
}
break;
case GET_INFO_ID:
{
if(*DLLNum_network_games_known)
{
int gameno;
gameno = DLLListGetSelectedIndex(game_list);
int gameid = GetGameByLBNo(gameno);
gameno = gameid;
if(gameid==-1)
break;
DLLmprintf((0,"Selected item is %s\n",DLLNetwork_games[gameno].name));
DLLShowNetgameInfo(&DLLNetwork_games[gameno]);
}
}
break;
case SORT_GAMENAME:
{
DLLmprintf((0,"Sorting by game name.\n"));
invert_sort_gamename = !invert_sort_gamename;
ResortGameList(game_list,res,invert_sort_gamename);
}
break;
case SORT_GAMETYPE:
{
DLLmprintf((0,"Sorting by game type.\n"));
invert_sort_gametype = !invert_sort_gametype;
ResortGameList(game_list,res,invert_sort_gametype);
}
break;
case SORT_MISSION:
{
DLLmprintf((0,"Sorting by mission.\n"));
invert_sort_mission = !invert_sort_mission;
ResortGameList(game_list,res,invert_sort_mission);
}
break;
case SORT_LEVEL:
{
DLLmprintf((0,"Sorting by level.\n"));
invert_sort_levels = !invert_sort_levels;
ResortGameList(game_list,res,invert_sort_levels);
}
break;
case SORT_PLAYERS:
{
DLLmprintf((0,"Sorting by players.\n"));
invert_sort_players = !invert_sort_players;
ResortGameList(game_list,res,invert_sort_players);
}
break;
case SORT_PING:
{
DLLmprintf((0,"Sorting by ping.\n"));
invert_sort_ping = !invert_sort_ping;
ResortGameList(game_list,res,invert_sort_ping);
}
break;
}
}
DLLNewUIWindowDestroy(main_wnd);
*DLLNewUIWindow_alpha = oldalpha;
//Look for items that we need to remove
for(i=0;iMT_DATA_UPDATE_INTERVAL)
{
UpdateGameData(&DLLD3_tracker_info);
LastTrackerDataUpdate = DLLtimer_GetTime();
}
if(DLLNetgame->flags & NF_TRACK_RANK)
{
//Loop through all DLLMNetPlayers looking to see if we need to send or receive
if(MTWritingPilot!=-1)
{
//We are already sending a pilot
rcode = SendD3PilotData(NULL);
if(rcode!=0)
{
if(rcode==1)
{
//Copy data from the DLLMTPilotinfo[MTReadingPilot] struct here
DLLMNetPlayers[MTWritingPilot].flags &= ~NPF_MT_WRITING_PILOT;
DLLmprintf ((0,"Pilot data wrote to the Mastertracker for Player[%d] %s (tid=%s).\n",MTWritingPilot,DLLMTPilotinfo[MTWritingPilot].pilot_name,DLLMTPilotinfo[MTWritingPilot].tracker_id));
MTWritingPilot = -1;
}
else
{
DLLMNetPlayers[MTWritingPilot].flags &= ~NPF_MT_WRITING_PILOT;
DLLmprintf ((0,"Pilot write to the mastertracker failed. Error code %d.\n",rcode));
MTWritingPilot = -1;
}
}
}
else
{
//See if se need to look for another
for (i=0;ilocal_role!=LR_SERVER)
{
return;
}
//Send all player info to the mastertracker
for (i=0;iIsFileError())
{
//Error here
DLLmprintf ((0,"Mastertracker update DLL not received. Error code: %d.\n",inetfile->GetErrorCode()));
DLLmod_FreeModule(&MTAVDLLHandle);
return 0;
}
if(inetfile->IsFileReceived())
{
DLLmprintf ((0,"Mastertracker update DLL received.\n"));
DLLmod_FreeModule(&MTAVDLLHandle);
DLLddio_MakePath(szolddll,DLLLocalD3Dir,"mtav.dll",NULL);
DLLddio_MakePath(szbakdll,DLLLocalD3Dir,"mtav.bak",NULL);
//We have the file, now backup & copy it and try to reload.
CopyFile(szolddll,szbakdll,FALSE);
CopyFile(sznewdll,szolddll,FALSE);
return 0;
}
};
}
else
{
DLLmprintf ((0,"Mastertracker says we are up to date\n"));
//Here is where we call into the DLL so it can do it's magic
DLLAVInit(0);
DLLmod_FreeModule(&MTAVDLLHandle);
return 1;
}
}
else
{
DLLmprintf ((0,"Mastertracker timeout while getting version\n"));
DLLmod_FreeModule(&MTAVDLLHandle);
return 0;
}
#endif
return 1;
}
int JoinNewLobby(char *lobby)
{
int rcode;
char *p;
DLLmprintf((0,"Entering new lobby"));
void * title_text = DLLCreateNewUITextItem(TXT_PXO_ENTERINGLOBBY,UICOL_WINDOW_TITLE);
void * cancel_on_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_HI);
void * cancel_off_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_LO);
void * main_wnd = DLLNewUIGameWindowCreate(0,256,128,128,UIF_CENTER|UIF_PROCESS_ALL|NUWF_TITLEMED);
void * title = DLLTextCreate(main_wnd,title_text,0,7,UIF_CENTER);
void * cancel_hs = DLLHotSpotCreate(main_wnd,5 ,KEY_ESC,cancel_off_text ,cancel_on_text , 20,100,70,15,UIF_CENTER);
DLLNewUIGameWindowOpen(main_wnd);
do
{
rcode = SetNewChatChannel(lobby);
p = GetChatText();
if(p && pconsole)
{
DLLUIConsoleGadgetputs(pconsole,p);
DLLUIConsoleGadgetputs(pconsole,"\x0a\x0d");
}
}while(rcode==0);
DLLNewUIGameWindowClose(main_wnd);
DLLNewUIGameWindowDestroy(main_wnd);
if(rcode==1)
{
strcpy(DLLPXO_hosted_lobby_name,lobby);
return 1;
}
else
{
DLLmprintf((0,"Unable to join lobby: %d\n",rcode));
char txtmessage[200];
char cleanlobby[50];
memset(cleanlobby,0,29);
strcpy(cleanlobby,lobby+1);
for(int l=0;l<18;l++)
{
if(cleanlobby[l]=='_') cleanlobby[l] = ' ';
}
sprintf(txtmessage,TXT_PXO_CANTJOINLOBBY,cleanlobby);
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,txtmessage,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
return 0;
}
DLLDeleteUIItem(main_wnd);
DLLDeleteUIItem(title);
DLLDeleteUIItem(cancel_hs);
DLLRemoveUITextItem(title_text);
DLLRemoveUITextItem(cancel_on_text);
DLLRemoveUITextItem(cancel_off_text);
}
char *SendWhisper(char *name)
{
int exit_menu = 0;
char *p;
char message[MAX_CHAT_SEND_LEN];
char pilot_name[MAX_CHAT_SEND_LEN];
static char fmt_msg[MAX_CHAT_SEND_LEN*2];
void * title_text = DLLCreateNewUITextItem(TXT_PXO_PRIVATEMESSAGE,UICOL_WINDOW_TITLE);
void * cancel_on_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_HI);
void * cancel_off_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_LO);
void * send_on_text = DLLCreateNewUITextItem(TXT_PXO_SEND,UICOL_HOTSPOT_HI);
void * send_off_text = DLLCreateNewUITextItem(TXT_PXO_SEND,UICOL_HOTSPOT_LO);
void * pilot_text = DLLCreateNewUITextItem(TXT_PXO_PILOTNAME,UICOL_TEXT_NORMAL);
void * message_text = DLLCreateNewUITextItem(TXT_PXO_MESSAGE,UICOL_TEXT_NORMAL);
void * main_wnd = DLLNewUIGameWindowCreate(0, 0, 384, 256, UIF_PROCESS_ALL | UIF_CENTER| NUWF_TITLEMED);
void * title = DLLTextCreate(main_wnd,title_text,0,7,UIF_CENTER);
void * pilot = DLLTextCreate(main_wnd,pilot_text,50,55,0);
void * message_t = DLLTextCreate(main_wnd,message_text,50,110,0);
void * user_edit = DLLEditCreate(main_wnd,10,50,75,130,15,0);
void * msg_edit = DLLEditCreate(main_wnd,3,50,130,200,15,0);
//HotSpotCreate(int item,int parentitem, int id, int key, int txtitemoff, int txtitemon, int x, int y, int w, int h, int flags,int winnum)
void * cancel_hs = DLLHotSpotCreate(main_wnd,UID_CANCEL,KEY_ESC,cancel_on_text,cancel_off_text,130,256-80, 60, 20,0);
void * send_hs = DLLHotSpotCreate(main_wnd,UID_OK,KEY_ENTER,send_on_text,send_off_text,60,256-80, 60, 20,0);
DLLNewUIGameWindowOpen(main_wnd);
//DLLNewUIWindowSetFocusOnEditGadget(msg_edit,main_wnd);
DLLEditSetText(user_edit,name);
while (!exit_menu)
{
int res;
res = DLLDoUI();
// handle all UI results.
switch(res)
{
case 3:
case UID_OK:
DLLEditGetText(user_edit,pilot_name,MAX_CHAT_SEND_LEN);
DLLEditGetText(msg_edit,message,MAX_CHAT_SEND_LEN);
sprintf(fmt_msg,"/msg %s %s",pilot_name,message);
p = SendChatString(fmt_msg);
if(p&&pconsole)
{
DLLUIConsoleGadgetputs(pconsole,p);
DLLUIConsoleGadgetputs(pconsole,"\x0a\x0d");
}
exit_menu = 1;
break;
case UID_CANCEL:
exit_menu = 1;
break;
}
}
DLLNewUIGameWindowClose(main_wnd);
DLLNewUIGameWindowDestroy(main_wnd);
//Clean up
DLLRemoveUITextItem(title_text);
DLLRemoveUITextItem(cancel_on_text);
DLLRemoveUITextItem(cancel_off_text);
DLLRemoveUITextItem(send_on_text);
DLLRemoveUITextItem(send_off_text);
DLLRemoveUITextItem(pilot_text);
DLLRemoveUITextItem(message_text);
DLLDeleteUIItem(main_wnd);
DLLDeleteUIItem(title);
DLLDeleteUIItem(pilot);
DLLDeleteUIItem(message_t);
DLLDeleteUIItem(user_edit);
DLLDeleteUIItem(msg_edit);
DLLDeleteUIItem(cancel_hs);
DLLDeleteUIItem(send_hs);
return "";
}
int JoinPrivateLobby(void)
{
int exit_menu = 0;
int ret;
char message[MAX_CHAT_SEND_LEN];
char priv_channel[MAX_CHAT_SEND_LEN];
static char fmt_msg[MAX_CHAT_SEND_LEN*2];
void * title_text = DLLCreateNewUITextItem(TXT_PXO_JOINPRIV,UICOL_WINDOW_TITLE);
void * cancel_on_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_HI);
void * cancel_off_text = DLLCreateNewUITextItem(TXT_PXO_CANCEL,UICOL_HOTSPOT_LO);
void * join_on_text = DLLCreateNewUITextItem(TXT_PXO_JOIN,UICOL_HOTSPOT_HI);
void * join_off_text = DLLCreateNewUITextItem(TXT_PXO_JOIN,UICOL_HOTSPOT_LO);
void * channel_text = DLLCreateNewUITextItem(TXT_PXO_CHANNELNAME,UICOL_TEXT_NORMAL);
void * main_wnd = DLLNewUIGameWindowCreate(0, 0, 256, 256, UIF_PROCESS_ALL | UIF_CENTER | NUWF_TITLELARGE );
void * title = DLLTextCreate(main_wnd,title_text,0,7,UIF_CENTER);
void * channel_t = DLLTextCreate(main_wnd,channel_text,50,95,UIF_CENTER);
void * chan_edit = DLLEditCreate(main_wnd,3,50,115,130,15,UIF_CENTER);
//DLLNewUIWindowSetFocusOnEditGadget(chan_edit,main_wnd);
//HotSpotCreate(int item,int parentitem, int id, int key, int txtitemoff, int txtitemon, int x, int y, int w, int h, int flags,int winnum)
void * cancel_hs = DLLHotSpotCreate(main_wnd,UID_CANCEL,KEY_ESC,cancel_on_text,cancel_off_text,130,256-80, 60, 20,0);
void * join_hs = DLLHotSpotCreate(main_wnd,UID_OK,KEY_ENTER,join_on_text,join_off_text,60,256-80, 60, 20,0);
DLLNewUIGameWindowOpen(main_wnd);
while (!exit_menu)
{
int res;
res = DLLDoUI();
// handle all UI results.
switch(res)
{
case 3:
case UID_OK:
{
DLLEditGetText(chan_edit,priv_channel,MAX_CHAT_SEND_LEN);
for(unsigned int i=0;i=0 && ranking<600)
val=0;
else if (ranking>=600 && ranking<900)
val=1;
else if (ranking>=900 && ranking<1200)
val=2;
else if (ranking>=1200 && ranking<1500)
val=3;
else if (ranking>=1500 && ranking<1800)
val=4;
else if (ranking>=1800 && ranking<2100)
val=5;
else if (ranking>=2100 && ranking<2400)
val=6;
else if (ranking>=2400 && ranking<2600)
val=7;
else if (ranking>=2600 && ranking<3000)
val=8;
else if (ranking>=3000)
val=9;
return TXT(TXT_RANKING0+val);
}
int GetNextRank(float ranking)
{
int val=0;
if (ranking>=0 && ranking<600)
val=600;
else if (ranking>=600 && ranking<900)
val=900;
else if (ranking>=900 && ranking<1200)
val=1200;
else if (ranking>=1200 && ranking<1500)
val=1500;
else if (ranking>=1500 && ranking<1800)
val=1800;
else if (ranking>=1800 && ranking<2100)
val=2100;
else if (ranking>=2100 && ranking<2400)
val=2400;
else if (ranking>=2400 && ranking<2600)
val=2600;
else if (ranking>=2600 && ranking<3000)
val=3000;
else if (ranking>=3000)
val=3000;
return val;
}
int GetPilotStats(char *pilot)
{
int res;
char *p;
char *tokp;
char tid[MAX_CHAT_SEND_LEN];
char real_pilot[MAX_CHAT_SEND_LEN];
char tmp_text[MAX_CHAT_SEND_LEN];
vmt_descent3_struct d3_pilot_info;
void * eff_text;
void * time_text;
void * main_wnd;
void * title_t;
void * kill_t;
void * death_t;
void * suicide_t;
void * eff_t;
void * time_in_game_t;
void * pilot_t;
void * rank_t;
void * title_text;
void * pilot_name_text;
void * close_on_text;
void * close_off_text;
void * kills_text;
void * deaths_text;
void * suicide_text;
void * rank_text;
DLLCreateSplashScreen(TXT_PXO_GETTINGPILOTSTAT,1);
//Cancel previously active lookups
GetD3PilotData((vmt_descent3_struct *)-1,NULL,NULL);
GetTrackerIdByUser((char *)-1);
p = GetTrackerIdByUser(pilot);
while(p==NULL)
{
res = DLLPollUI();
DLLDescentDefer();
p = GetChatText();
if(p&&pconsole)
{
DLLUIConsoleGadgetputs(pconsole,p);
DLLUIConsoleGadgetputs(pconsole,"\x0a\x0d");
}
p = GetTrackerIdByUser(pilot);
if(res==99)
{
//cancel was hit
//Cancel the look
GetTrackerIdByUser((char *)-1);
DLLCloseSplashScreen();
}
}
if(p==(char *)-1)
{
DLLmprintf((0,"Timeout looking for user\n"));
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_TIMEOUTMT,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
DLLCloseSplashScreen();
return 0;
}
tokp = strchr(p,' ');
if(tokp)
{
*tokp = NULL;
tokp++;
strcpy(tid,p);
strcpy(real_pilot,tokp);
DLLmprintf((0,"Requesting pilot info for %s %s\n",tid,real_pilot));
memset(&d3_pilot_info,0,sizeof(vmt_descent3_struct));
GetD3PilotData(&d3_pilot_info,real_pilot,tid);
int iresult = 0;
while(iresult==0)
{
iresult=GetD3PilotData(NULL,NULL,NULL);
res = DLLPollUI();
if(res==99)
{
//cancel was hit
GetD3PilotData((vmt_descent3_struct *)-1,NULL,NULL);
iresult = -1;
}
DLLDescentDefer();
p = GetChatText();
if(p && pconsole)
{
DLLUIConsoleGadgetputs(pconsole,p);
DLLUIConsoleGadgetputs(pconsole,"\x0a\x0d");
}
}
if(iresult==1)
{
DLLmprintf((0,"Got pilot info for %s %s\n",tid,real_pilot));
//Do rank thingy here.
sprintf(tmp_text,"Rank: %s (%d) Next Advance at %d",GetRankString(d3_pilot_info.rank/65536),d3_pilot_info.rank/65536,GetNextRank(d3_pilot_info.rank/65536));
rank_text = DLLCreateNewUITextItem(tmp_text,UICOL_TEXT_NORMAL);
title_text = DLLCreateNewUITextItem(TXT_PXO_PILOTSTATS,UICOL_WINDOW_TITLE);
pilot_name_text = DLLCreateNewUITextItem(real_pilot,UICOL_WINDOW_TITLE,DLL_BIG_BRIEFING_FONT);
close_on_text = DLLCreateNewUITextItem(TXT_PXO_CLOSE,UICOL_HOTSPOT_HI);
close_off_text = DLLCreateNewUITextItem(TXT_PXO_CLOSE,UICOL_HOTSPOT_LO);
sprintf(tmp_text,TXT_PXO_TOTALKILLS,d3_pilot_info.kills);
kills_text = DLLCreateNewUITextItem(tmp_text,UICOL_TEXT_NORMAL);
sprintf(tmp_text,TXT_PXO_TOTALDEATHS,d3_pilot_info.deaths);
deaths_text = DLLCreateNewUITextItem(tmp_text,UICOL_TEXT_NORMAL);
sprintf(tmp_text,TXT_PXO_SUICIDES,d3_pilot_info.suicides);
suicide_text = DLLCreateNewUITextItem(tmp_text,UICOL_TEXT_NORMAL);
int leff = 0;
int cury;
if(d3_pilot_info.kills && d3_pilot_info.deaths)
{
//leff = d3_pilot_info.kills/d3_pilot_info.deaths+d3_pilot_info.suicides+d3_pilot_info.kills;
leff = (int)((float)((float)d3_pilot_info.kills/((float)d3_pilot_info.deaths+(float)d3_pilot_info.kills+(float)d3_pilot_info.suicides))*100.0);
}
sprintf(tmp_text,TXT_PXO_EFFECIENCY,leff);
eff_text = DLLCreateNewUITextItem(tmp_text,UICOL_TEXT_NORMAL);
sprintf(tmp_text,TXT_PXO_TIMEINGAME,d3_pilot_info.online_time/60);
time_text = DLLCreateNewUITextItem(tmp_text,UICOL_TEXT_NORMAL);
main_wnd = DLLNewUIGameWindowCreate(0, 0, 384, 256, UIF_PROCESS_ALL | UIF_CENTER | NUWF_TITLEMED);
title_t = DLLTextCreate(main_wnd,title_text,0,7,UIF_CENTER);
cury = 30;
pilot_t = DLLTextCreate(main_wnd,pilot_name_text,0,cury,UIF_CENTER); cury+=30;
rank_t = DLLTextCreate(main_wnd,rank_text,0,cury,UIF_CENTER); cury+=20;
kill_t = DLLTextCreate(main_wnd,kills_text,0,cury,UIF_CENTER); cury+=20;
death_t = DLLTextCreate(main_wnd,deaths_text,0,cury,UIF_CENTER); cury+=20;
suicide_t = DLLTextCreate(main_wnd,suicide_text,0,cury,UIF_CENTER); cury+=20;
eff_t = DLLTextCreate(main_wnd,eff_text,0,cury,UIF_CENTER); cury+=20;
time_in_game_t = DLLTextCreate(main_wnd,time_text,0,cury,UIF_CENTER); cury+=30;
//HotSpotCreate(int item,int parentitem, int id, int key, int txtitemoff, int txtitemon, int x, int y, int w, int h, int flags,int winnum)
DLLHotSpotCreate(main_wnd,UID_CANCEL,KEY_ESC,close_on_text,close_off_text,130,cury, 60, 20,UIF_CENTER);
DLLNewUIGameWindowOpen(main_wnd);
int exit_menu = 0;
while (!exit_menu)
{
int res;
res = DLLDoUI();
if(res==UID_CANCEL)
{
exit_menu=1;
}
}
DLLNewUIGameWindowClose(main_wnd);
DLLNewUIGameWindowDestroy(main_wnd);
//Cleanup
DLLRemoveUITextItem(rank_text);
DLLRemoveUITextItem(title_text);
DLLRemoveUITextItem(close_on_text);
DLLRemoveUITextItem(close_off_text);
DLLRemoveUITextItem(kills_text);
DLLRemoveUITextItem(deaths_text);
DLLRemoveUITextItem(suicide_text);
DLLRemoveUITextItem(eff_text);
DLLRemoveUITextItem(time_text);
DLLRemoveUITextItem(pilot_name_text);
DLLDeleteUIItem(pilot_t);
DLLDeleteUIItem(main_wnd);
DLLDeleteUIItem(title_t);
DLLDeleteUIItem(kill_t);
DLLDeleteUIItem(death_t);
DLLDeleteUIItem(suicide_t);
DLLDeleteUIItem(eff_t);
DLLDeleteUIItem(rank_t);
DLLDeleteUIItem(time_in_game_t);
}
}
DLLCloseSplashScreen();
return 1;
}
void AutoLoginAndJoinGame(void)
{
int loginlen = LOGIN_LEN;
int passlen = PASSWORD_LEN;
int valret;
unsigned short port;
unsigned long iaddr;
*DLLMultiGameStarting = 0;
DLLCreateSplashScreen(TXT_PXO_CONNECTING,0);
DLLDatabaseRead("TrackerLogin",szloginid,&loginlen);
DLLDatabaseRead("TrackerPassword",szpassword,&passlen);
if(!*DLLAuto_login_addr)
{
DLLmprintf((0,"Can't autostart because no IP address was specified!!\n"));
*DLLMultiGameStarting = 0;
goto failed_login;
}
if(*DLLAuto_login_port)
{
port = atoi(DLLAuto_login_port);
}
else
{
port = DEFAULT_GAME_PORT;
}
if(!*szloginid || !*szpassword)
{
if(LoginMasterTracker())
{
//Uh... now connect to the server
}
else
{
goto failed_login;
}
}
//Fill out the validate struct and send off the packet
validate_id_request val_user;
strcpy(val_user.tracker_id,sztrackerid);
strcpy(val_user.login,szloginid);
strcpy(val_user.password,szpassword);
valret = ValidateUser(&val_user,sztrackerid);
while(valret==0)
{
valret = ValidateUser(NULL,NULL);
DLLDescentDefer();
}
if(valret == 1)
{
//User was validated
DLLmprintf ((0,"Mastertracker user validated!\n"));
strcpy(DLLTracker_id,sztrackerid);
strcpy(DLLMPlayers[DLLPlayer_num].tracker_id,sztrackerid);
}
else if(valret == -1)
{
//User invalid!
DLLmprintf ((0,"Mastertracker user not validated!\n"));
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_BADLOGIN,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
goto failed_login;
}
else
{
//timeout waiting for tracker!
DLLmprintf ((0,"Mastertracker timeout!\n"));
DLLDoMessageBox(TXT_PXO_MASTERTRACKER,TXT_PXO_TIMEOUTMT,MSGBOX_OK,UICOL_WINDOW_TITLE,UICOL_TEXT_NORMAL);
goto failed_login;
}
//Now actually connect to the server!
network_address s_address;
iaddr = inet_addr(DLLAuto_login_addr);
memcpy (&s_address.address,&iaddr,sizeof(unsigned long));
s_address.port=port;
s_address.connection_type = NP_TCP;
*DLLGame_is_master_tracker_game = 1;
DLLMultiStartClient (NULL);
if ((DLLTryToJoinServer (&s_address)))
{
DLLmprintf ((0,"Menu: Game joined!\n"));
*DLLMultiGameStarting = 1;
}
failed_login:
//Run this to make sure we properly ACK the server.
for(int j=0;j<10;j++) PollPTrackNet();
DLLCloseSplashScreen();
}
void AutoLoginAndStartGame(void)
{
int loginlen = LOGIN_LEN;
int passlen = PASSWORD_LEN;
int valret;
*DLLMultiGameStarting = 0;
DLLDatabaseRead("TrackerLogin",szloginid,&loginlen);
DLLDatabaseRead("TrackerPassword",szpassword,&passlen);
if(!*szloginid || !*szpassword)
{
if(LoginMasterTracker())
{
//Uh... now connect to the server
}
else
{
goto failed_login;
}
}
//Fill out the validate struct and send off the packet
validate_id_request val_user;
strcpy(val_user.tracker_id,sztrackerid);
strcpy(val_user.login,szloginid);
strcpy(val_user.password,szpassword);
valret = ValidateUser(&val_user,sztrackerid);
while(valret==0)
{
valret = ValidateUser(NULL,NULL);
DLLDescentDefer();
}
if(valret == 1)
{
//User was validated
DLLmprintf ((0,"Mastertracker user validated!\n"));
DLLPrintDedicatedMessage ("Mastertracker user validated.\n");
strcpy(DLLTracker_id,sztrackerid);
strcpy(DLLMPlayers[DLLPlayer_num].tracker_id,sztrackerid);
}
else if(valret == -1)
{
//User invalid!
DLLmprintf ((0,"Mastertracker user not validated!\n"));
DLLPrintDedicatedMessage ("Mastertracker user not validated!\n");
goto failed_login;
}
else
{
//timeout waiting for tracker!
DLLmprintf ((0,"Mastertracker timeout!\n"));
DLLPrintDedicatedMessage ("Mastertracker timeout!\n");
goto failed_login;
}
*DLLMultiGameStarting = 1;
*DLLGame_is_master_tracker_game = 1;
// strcpy(DLLD3_tracker_info.game_name,DLLNetgame->name);
// strcpy(DLLD3_tracker_info.mission_name,DLLNetgame->mission);
strcpy(DLLD3_tracker_info.lobby,DLLPXO_hosted_lobby_name);
failed_login:
//Run this to make sure we properly ACK the server.
for(int j=0;j<10;j++) PollPTrackNet();
}
#define MAX_MOTD_LEN 400
#define NUM_MOTD_LINES 6
#define MOTD_WIDTH 384
#define MOTD_HEIGHT 256
extern int GetD3MOTD(char *szmotd,int maxlen);
int ShowMessageOfTheDay(void)
{
static char szlastmotd[MAX_MOTD_LEN];
static char sznewmotd[MAX_MOTD_LEN];
int motdlen = MAX_MOTD_LEN;
int res;
int rval = 0;
static void * main_wnd;
void * close_hs;
int last_motd_version = 0;
DLLDatabaseReadInt("MOTDVersion",&last_motd_version);
if(Motd_version==last_motd_version)
{
//MOTD is old....
DLLmprintf((0,"MOTD is old, skipping\n"));
return 1;
}
DLLDatabaseWriteInt("MOTDVersion",Motd_version);
void * close_on_text = DLLCreateNewUITextItem(TXT_PXO_CLOSE,UICOL_HOTSPOT_HI);
void * close_off_text = DLLCreateNewUITextItem(TXT_PXO_CLOSE,UICOL_HOTSPOT_LO);
void * motd_text = DLLCreateNewUITextItem("PXO Message of the day",UICOL_WINDOW_TITLE);
main_wnd = DLLNewUIGameWindowCreate(0, 0, MOTD_WIDTH, MOTD_HEIGHT, UIF_PROCESS_ALL | UIF_CENTER | NUWF_TITLELARGE);
void * console_item = DLLUIConsoleGadgetCreate(main_wnd, 15, 20, 30,0,40,20,0);
void * title = DLLTextCreate(main_wnd,motd_text,0,7,UIF_CENTER);
close_hs = DLLHotSpotCreate(main_wnd,UID_OK,KEY_ENTER,close_off_text,close_on_text,60,MOTD_HEIGHT-60, 60, 20,UIF_CENTER);
DLLDatabaseRead("LastMOTD",szlastmotd,&motdlen);
DLLmprintf((0,"Getting message of the day...\n"));
DLLCreateSplashScreen(TXT_PXO_CONNECTING,1);
int mcode = GetD3MOTD(sznewmotd,MAX_MOTD_LEN);
do
{
mcode = GetD3MOTD(NULL,0);
res = DLLPollUI();
if(res==99)
{
GetD3MOTD((char *)-1,0);
DLLCloseSplashScreen();
goto close_motd;
}
DLLDescentDefer();
}while(mcode==0);
DLLCloseSplashScreen();
if(mcode==1)
{
DLLmprintf((0,"Message of the day: %s\n",sznewmotd));
if(strcmp(szlastmotd,sznewmotd)!=0)
{
DLLNewUIGameWindowOpen(main_wnd);
DLLUIConsoleGadgetputs(console_item,sznewmotd);
DLLDatabaseWrite("LastMOTD",sznewmotd,strlen(sznewmotd)+1);
do
{
res = DLLPollUI();
DLLDescentDefer();
}while(res!=UID_OK);
DLLNewUIGameWindowClose(main_wnd);
rval = 1;
goto close_motd;
}
else
{
DLLmprintf((0,"Message of the day is old, ignoring!\n"));
rval = 1;
goto close_motd;
}
}
else
{
DLLmprintf((0,"Get message of the day failed (%d)!\n",mcode));
goto close_motd;
}
close_motd:
DLLmprintf((0,"Ending motd\n"));
DLLNewUIGameWindowDestroy(main_wnd);
DLLRemoveUITextItem(motd_text);
DLLRemoveUITextItem(close_on_text);
DLLRemoveUITextItem(close_off_text);
DLLDeleteUIItem(console_item);
DLLDeleteUIItem(title);
DLLDeleteUIItem(close_hs);
DLLDeleteUIItem(main_wnd);
return rval;
}