#include #include "types.h" #include "TitanInterfaceC.h" #include "ChannelFSM.h" #include "msg\ServerStatus.h" #include "debug.h" #include "multiplayergame.h" #include "strings.h" #include "titannet.h" // defines for the state of the connection to the chat server #define CS_Idle -1 #define CS_IsRoomThere 3 #define CS_RoomConnecting 4 #define CS_RoomConnected 5 #define CS_RoomCreating 6 #define CS_RoomCreate 7 #define CS_IsADefaultRoomThere 8 #define CS_CreatingGame 20 #define CS_CreatedGame 21 #define CS_StartingTitan 30 #define CS_TitanStarted 31 // function prototypes void cChannelStateMachine(void); // data sdword cChannelFSMState=-1; char channeltry[MAX_CHANNEL_NAME_LEN]; char channeldesctry[MAX_CHANNEL_DESCRIPTION_LEN]; // functions to start the state machine bool cCreateChannel(wchar_t *name, wchar_t *desc) { //titanCreateDirectory(name, desc); SetChannel(name,desc); cChannelFSMState = CS_RoomCreate; cChannelStateMachine(); return(FALSE); } bool cJoinChannelRequest(wchar_t *name, wchar_t *desc) { SetChannel(name,desc); if (cChannelFSMState != CS_Idle) { return (TRUE); } cChannelFSMState = CS_IsRoomThere; cChannelStateMachine(); titanRefreshRequest(NULL); return(FALSE); } bool cJoinADefaultRoom(void) { ChannelPassword[0] = 0; if (cChannelFSMState != CS_Idle) { return (TRUE); } cChannelFSMState = CS_IsADefaultRoomThere; cChannelStateMachine(); titanRefreshRequest(NULL); return(FALSE); } bool cCreateGame(wchar_t *name) { return(FALSE); } bool cStartTitan(void) { if (cChannelFSMState != CS_Idle) { return(TRUE); } cChannelFSMState = CS_StartingTitan; cChannelStateMachine(); return(FALSE); } void cResetFSM(void) { cChannelFSMState = CS_Idle; } void cChannelStateMachine(void) { switch (cChannelFSMState) { case CS_RoomCreating : mgDisplayMessage(strGetString(strCreatingRoom)); break; case CS_IsADefaultRoomThere: case CS_IsRoomThere : mgDisplayMessage(strGetString(strQueryingChat)); break; case CS_RoomConnecting : mgDisplayMessage(strGetString(strConnectingToChat)); chatConnect(ChannelPassword); break; case CS_RoomConnected : cChannelFSMState = CS_Idle; mgDisplayMessage(strGetString(strConnectedToChat)); break; case CS_RoomCreate : { if (!titanStartChatServer(ChannelProtectedFlag ? ChannelPassword : NULL)) { cChannelFSMState = CS_Idle; } mgDisplayMessage(strGetString(strStartingChat)); } break; case CS_Idle : break; } } #if 0 void cNotifyCurrentRoomPresent(int present) { } #endif #define FIND_DEFAULT_ROOM_TRIES 3 sdword FindADefaultRoom(void) { sdword i,tryagain; // first iteration match both language and someone criteria // second iteration just language criteria // third iteration no criteria bool languagecriteria[FIND_DEFAULT_ROOM_TRIES] = { TRUE, TRUE, FALSE }; bool someonecriteria[FIND_DEFAULT_ROOM_TRIES] = { TRUE, FALSE, FALSE }; tpchannel *tc; for (tryagain=0;tryagainroomflags & (ROOMFLAGS_ADEFAULTROOM|ROOMFLAGS_PASSWORDPROTECTED)) == (ROOMFLAGS_ADEFAULTROOM)) { if ((!languagecriteria[tryagain]) || ((tc->roomflags & ROOMFLAGS_LANGUAGE_MASK) == strCurLanguage)) { if ((!someonecriteria[tryagain]) || ((tc->roomfullness >= ROOM_MIN_THRESHOLD) && (tc->roomfullness <= ROOM_MAX_THRESHOLD))) { return i; } } } } } return -1; } void cNotifyRoomListPresent(void) { if (cChannelFSMState==CS_IsADefaultRoomThere) { // we now know that tpChannelList is ready to look at. // find an appropriate room sdword foundroom; tpLockChannelList(); foundroom = FindADefaultRoom(); if (foundroom >= 0) { SetChannel(tpChannelList.tpChannels[foundroom].ChannelName,tpChannelList.tpChannels[foundroom].ChannelDescription); } else { ResetChannel(); } tpUnLockChannelList(); } } void cNotifyCurrentRoomPresent(int present) { if (cChannelFSMState==CS_IsRoomThere) { if (present) { cChannelFSMState = CS_RoomConnecting; cChannelStateMachine(); } else { cChannelFSMState = CS_RoomCreate; cChannelStateMachine(); } } else if (cChannelFSMState == CS_IsADefaultRoomThere) { if (present) { cChannelFSMState = CS_RoomConnecting; cChannelStateMachine(); } else { // we didn't find a room. So lets just create one. SetChannel(L"Default",L"Default"); cChannelFSMState = CS_IsRoomThere; //cChannelStateMachine(); titanRefreshRequest(NULL); } } } void titanStartChatReplyReceivedCB(short theStatus) { if ((theStatus == StatusCommon_Success) || (theStatus == StatusDir_ServiceExists)) { if (cChannelFSMState == CS_RoomCreate) { cChannelFSMState = CS_RoomConnecting; cChannelStateMachine(); } } else { if (cChannelFSMState == CS_RoomCreate) { ResetChannel(); mgDisplayMessage(strGetString(strFailedToCreateChat)); } } } void cNotifyChatConnected(void) { if (cChannelFSMState == CS_RoomConnecting) { cChannelFSMState = CS_RoomConnected; cChannelStateMachine(); if (wcslen(RemoveGameRequest) >= 1) { titanRemoveGame(RemoveGameRequest); RemoveGameRequest[0] = 0; } return; } } void cNotifyDirStatus(short theStatus) { if (theStatus==StatusCommon_Success) { // obsolete, use to be callback when directory is created } } void cNotifyGameCreationStatus(short theStatus) { if (LANGame) { return; } // Called when the Routing Server replies to our game creation requests // Two possible status values: // o StatusCommon_Success: everything's great // o StatusRouting_ObjectAlreadyExists: the game name is already in use switch (theStatus) { case StatusCommon_Success: mgCreateGameConfirmed(); break; case StatusRouting_ObjectAlreadyExists: mgGameAlreadyExists(); break; default: break; } } void cNotifyChatConnectFailed(void) { ResetChannel(); if (cChannelFSMState == CS_RoomConnecting) { mgFailedToConnectToChannel(TRUE); } else { mgChatConnectionFailed(); } // else if (cChannelFSMState == CS_ChatCreateConnecting) // { // mgFailedToConnectToChannel(FALSE); // } cChannelFSMState = CS_Idle; } void cNotifyChatBadResponse(void) { ResetChannel(); cChannelFSMState = CS_Idle; }