home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / developer_install / ReplicaNetFreewareV5_4.exe / data1.cab / Program_Executable_Files / Example4 / Network.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-30  |  13.3 KB  |  464 lines

  1. /* START_LICENSE_HEADER
  2.  
  3. Copyright (C) 2000 Martin Piper, original design and program code
  4. Copyright (C) 2001-2005 Replica Software
  5.  
  6. This program file is copyright (C) Replica Software and can only be used under license.
  7. For more information visit: http://www.replicanet.com/
  8. Or email: info@replicanet.com
  9.  
  10. END_LICENSE_HEADER */
  11. /*
  12. This allocates a new ReplicaNet session and also handles the dialog displayed at the start of the application.
  13. The dialog displays a list of found game session for the user to join or allows a new game session to be created.
  14. */
  15. #include <windows.h>
  16. #include "Network.h"
  17. #include "Resource.h"
  18.  
  19. #include "RNReplicaNet/Inc/ReplicaNet.h"
  20. #include "RNXPURL/Inc/XPURL.h"
  21. #include "RNPlatform/Inc/PlatformHeap.h"
  22. #include "RNPlatform/Inc/ThreadClass.h"
  23.  
  24. using namespace RNReplicaNet;
  25.  
  26. extern HINSTANCE ghInst;
  27.  
  28. static bool failed_to = true;
  29.  
  30. static bool canBeMaster = true;
  31. static bool canSpider = true;
  32. static bool canAcceptMigrationObjects = true;
  33. static ReplicaNet::OnError onError = ReplicaNet::OnError::kMigrateObjects;
  34.  
  35. MyReplicaNet *Network::mNetwork = 0;
  36. bool Network::mDedicatedServer = false;
  37. bool Network::mRenderModels = true;
  38. bool Network::mDoRecord = false;
  39. bool Network::mDoPlayback = false;
  40. std::string Network::mRecordingFileName;
  41.  
  42. // Windows dialog variables
  43. static OPENFILENAME ofn;
  44. static TCHAR sFileName[MAX_PATH];
  45.  
  46. static void CreateGame(void)
  47. {
  48.     std::string url;
  49.  
  50.     // Lets set it so that our latency is recalculated a bit quicker just to show we can. :)
  51.     Network::mNetwork->SetLatencyRecalculationDelay(0.5f);
  52.  
  53.     Network::mNetwork->SetCanBecomeMaster(canBeMaster);
  54.     Network::mNetwork->SetCanSpider(canSpider);
  55.     Network::mNetwork->SetCanAcceptObjects(canAcceptMigrationObjects);
  56.  
  57.     Network::HandleRecording();
  58.     Network::mNetwork->SessionCreate("Example4");
  59.     url = Network::mNetwork->SessionExportURL();
  60.     OutputDebugString(url.c_str());
  61.     OutputDebugString("\n");
  62. }
  63.  
  64. // This utility function starts recording or playback if it is configured.
  65. void Network::HandleRecording(void)
  66. {
  67.     // If recording or playback is enabled then configure ReplicaNet
  68.     if (Network::mDoRecord && Network::mRecordingFileName != "")
  69.     {
  70.         FILE *fp = fopen(Network::mRecordingFileName.c_str(),"wb");
  71.         if (fp)
  72.         {
  73.             Network::mNetwork->SetRecordingFilePointer(fp);
  74.             Network::mNetwork->BeginSessionRecord();
  75.         }
  76.     }
  77.  
  78.     if (Network::mDoPlayback && Network::mRecordingFileName != "")
  79.     {
  80.         FILE *fp = fopen(Network::mRecordingFileName.c_str(),"rb");
  81.         if (fp)
  82.         {
  83.             Network::mNetwork->SetRecordingFilePointer(fp);
  84.             Network::mNetwork->BeginSessionPlayback();
  85.             // We are playing back a recording, so do not try to join or create a game.
  86.             return;
  87.         }
  88.     }
  89. }
  90. void Network::Network_Init(std::string url)
  91. {
  92.     Network::mNetwork = new MyReplicaNet;
  93.     Network::mNetwork->SetManualPoll();                            // Make ReplicaNet use the manual poll method.
  94.     Network::mNetwork->SetPollLayerBelow(false);                // Allow the XPsession/XPURL threads to use automatic scheduling.
  95.     Network::mNetwork->SetPollLayerBelowForXPSession(false);
  96.     Network::mNetwork->SetAutomaticPollXPSession();
  97.     Network::mNetwork->SetAutomaticPollXPURL();
  98.  
  99.     if (url != "")
  100.     {
  101.         Network::mNetwork->SessionJoin(url);
  102.     }
  103.     else
  104.     {
  105.         Network::Network_Dialog();
  106.  
  107.         if (failed_to)
  108.         {
  109.             Network::mNetwork->SetCanBecomeMaster(canBeMaster);
  110.             Network::mNetwork->SetCanSpider(canSpider);
  111.             Network::mNetwork->SetCanAcceptObjects(canAcceptMigrationObjects);
  112.  
  113.             Network::mNetwork->SessionFind();
  114.             // Wait a while
  115.             Sleep(500);
  116.             url = Network::mNetwork->SessionEnumerateFound();
  117.  
  118.             // Check for our game name so we get the right game session in the list
  119.             if (url.find("Example4") == std::string::npos)
  120.             {
  121.                 url = "";
  122.             }
  123.  
  124.             if (url != "")
  125.             {
  126.                 char buffer[256];
  127.                 sprintf(buffer,"Trying to join %s\n",url.c_str());
  128.                 OutputDebugString(buffer);
  129.                 HandleRecording();
  130.                 Network::mNetwork->SessionJoin(url);
  131.             }
  132.             else
  133.             {
  134.                 CreateGame();
  135.             }
  136.         }
  137.     }
  138. }
  139.  
  140. // Windows code to handle the create/join dialog.
  141. static BOOL CALLBACK Dlg_JoinOrNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  142. {
  143.     std::string url;
  144.  
  145.     switch (msg)
  146.     {
  147.         case WM_INITDIALOG:
  148.             SetTimer(hwndDlg,1,500,0);
  149.             SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_RESETCONTENT, 0, 0);
  150.  
  151.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK1), BM_SETCHECK, BST_CHECKED, 0);
  152.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK2), BM_SETCHECK, BST_CHECKED, 0);
  153.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK3), BM_SETCHECK, BST_CHECKED, 0);
  154.  
  155.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK4), BM_SETCHECK, BST_CHECKED, 0);
  156.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK5), BM_SETCHECK, BST_UNCHECKED, 0);
  157.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK6), BM_SETCHECK, BST_UNCHECKED, 0);
  158.  
  159.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK7), BM_SETCHECK, BST_UNCHECKED, 0);
  160.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK8), BM_SETCHECK, BST_CHECKED, 0);
  161.  
  162.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK9), BM_SETCHECK, BST_UNCHECKED, 0);
  163.             SendMessage(GetDlgItem(hwndDlg, IDC_CHECK10), BM_SETCHECK, BST_UNCHECKED, 0);
  164.  
  165.             EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT2),FALSE);
  166.             EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2),FALSE);
  167.  
  168. // This is the address of a test machine which lives behind a DSL connection and firewall that sometimes runs this example application.
  169. // It can be set to display this address in the dialog to make it easier to test the multiplayer code across a realistic internet connection.
  170. //            SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT1),"SESSION://UDP@217.39.30.241:2000/");
  171.  
  172.             SendMessage(hwndDlg,WM_COMMAND,IDC_REFRESH,0);
  173.  
  174.             SetFocus(GetDlgItem(hwndDlg,IDC_NEW));
  175.  
  176.             memset(&ofn,0,sizeof(ofn));
  177.             ofn.lStructSize = sizeof(ofn);
  178.             ofn.hwndOwner = 0;
  179.             ofn.lpstrFilter = "ReplicaNet recording\0*.repnet\0All Files\0*.*\0\0";
  180.             ofn.lpstrFile = sFileName;
  181.             sFileName[0] =0;
  182.             ofn.nMaxFile = sizeof(sFileName)/sizeof(sFileName[0]);
  183.             return 0;
  184.             break;
  185.         case WM_TIMER:
  186.             do
  187.             {
  188.                 url = Network::mNetwork->SessionEnumerateFound();
  189.                 // Check for our game name so we get the right game session in the list
  190.                 if (url.find("Example4") == std::string::npos)
  191.                 {
  192.                     url = "";
  193.                 }
  194.                 if (url != "")
  195.                 {
  196.                     SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_ADDSTRING, 0, (LPARAM) url.c_str());
  197.                 }
  198.             } while (url != "");
  199.             break;
  200.         case WM_COMMAND:
  201.         switch (LOWORD(wParam))
  202.         {
  203.             case IDC_LIST2:
  204.             {
  205.                 int sel = SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_GETCURSEL,0,0);
  206.                 if (sel != LB_ERR)
  207.                 {
  208.                     char buffer[256];
  209.                     int ret = SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_GETTEXT,sel,(LPARAM) buffer);
  210.                     if (ret != LB_ERR)
  211.                     {
  212.                         SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT1),buffer);
  213.                     }
  214.                     SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_SETCURSEL,sel,0);
  215.  
  216.                 }
  217.                 break;
  218.             }
  219.             case IDC_CHECK1:
  220.             {
  221.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK1), BM_GETCHECK ,0, 0);
  222.                 if (value == BST_CHECKED)
  223.                 {
  224.                     canSpider = true;
  225.                 }
  226.                 else
  227.                 {
  228.                     canSpider = false;
  229.                 }
  230.                 break;
  231.             }
  232.             case IDC_CHECK2:
  233.             {
  234.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK2), BM_GETCHECK ,0, 0);
  235.                 if (value == BST_CHECKED)
  236.                 {
  237.                     canBeMaster = true;
  238.                 }
  239.                 else
  240.                 {
  241.                     canBeMaster = false;
  242.                 }
  243.                 break;
  244.             }
  245.             case IDC_CHECK3:
  246.             {
  247.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK3), BM_GETCHECK ,0, 0);
  248.                 if (value == BST_CHECKED)
  249.                 {
  250.                     canAcceptMigrationObjects = true;
  251.                 }
  252.                 else
  253.                 {
  254.                     canAcceptMigrationObjects = false;
  255.                 }
  256.                 break;
  257.             }
  258.  
  259.             case IDC_CHECK4:
  260.             {
  261.                 onError = ReplicaNet::OnError::kMigrateObjects;
  262.  
  263.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK4), BM_SETCHECK, BST_CHECKED, 0);
  264.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK5), BM_SETCHECK, BST_UNCHECKED, 0);
  265.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK6), BM_SETCHECK, BST_UNCHECKED, 0);
  266.                 break;
  267.             }
  268.  
  269.             case IDC_CHECK5:
  270.             {
  271.                 onError = ReplicaNet::OnError::kDeleteObjects;
  272.  
  273.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK4), BM_SETCHECK, BST_UNCHECKED, 0);
  274.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK5), BM_SETCHECK, BST_CHECKED, 0);
  275.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK6), BM_SETCHECK, BST_UNCHECKED, 0);
  276.                 break;
  277.             }
  278.  
  279.             case IDC_CHECK6:
  280.             {
  281.                 onError = ReplicaNet::OnError::kLeaveObjects;
  282.  
  283.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK4), BM_SETCHECK, BST_UNCHECKED, 0);
  284.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK5), BM_SETCHECK, BST_UNCHECKED, 0);
  285.                 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK6), BM_SETCHECK, BST_CHECKED, 0);
  286.                 break;
  287.             }
  288.  
  289.             case IDC_CHECK7:
  290.             {
  291.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK7), BM_GETCHECK ,0, 0);
  292.                 if (value == BST_CHECKED)
  293.                 {
  294.                     Network::mDedicatedServer = true;
  295.                 }
  296.                 else
  297.                 {
  298.                     Network::mDedicatedServer = false;
  299.                 }
  300.                 break;
  301.             }
  302.  
  303.             case IDC_CHECK8:
  304.             {
  305.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK8), BM_GETCHECK ,0, 0);
  306.                 if (value == BST_CHECKED)
  307.                 {
  308.                     Network::mRenderModels = true;
  309.                 }
  310.                 else
  311.                 {
  312.                     Network::mRenderModels = false;
  313.                 }
  314.                 break;
  315.             }
  316.  
  317.             case IDC_CHECK9:
  318.             {
  319.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK9), BM_GETCHECK ,0, 0);
  320.                 if (value == BST_CHECKED)
  321.                 {
  322.                     Network::mDoRecord = true;
  323.                     Network::mDoPlayback = false;
  324.                     SendMessage(GetDlgItem(hwndDlg, IDC_CHECK10), BM_SETCHECK, BST_UNCHECKED, 0);
  325.  
  326.                     EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT2),TRUE);
  327.                     EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2),TRUE);
  328.                 }
  329.                 else
  330.                 {
  331.                     Network::mDoRecord = false;
  332.                     Network::mDoPlayback = false;
  333.                     EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT2),FALSE);
  334.                     EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2),FALSE);
  335.                 }
  336.                 break;
  337.             }
  338.             case IDC_CHECK10:
  339.             {
  340.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK10), BM_GETCHECK ,0, 0);
  341.                 if (value == BST_CHECKED)
  342.                 {
  343.                     Network::mDoRecord = false;
  344.                     Network::mDoPlayback = true;
  345.                     SendMessage(GetDlgItem(hwndDlg, IDC_CHECK9), BM_SETCHECK, BST_UNCHECKED, 0);
  346.  
  347.                     EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT2),TRUE);
  348.                     EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2),TRUE);
  349.                 }
  350.                 else
  351.                 {
  352.                     Network::mDoRecord = false;
  353.                     Network::mDoPlayback = false;
  354.                     EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT2),FALSE);
  355.                     EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2),FALSE);
  356.                 }
  357.                 break;
  358.             }
  359.             case IDC_BUTTON2:
  360.             {
  361.                 ofn.Flags = OFN_EXPLORER | OFN_LONGNAMES;
  362.                 int value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK9), BM_GETCHECK ,0, 0);
  363.                 if (value == BST_CHECKED)
  364.                 {
  365. //                    ofn.Flags |= OFN_CREATEPROMPT;
  366.                     if (GetSaveFileName(&ofn))
  367.                     {
  368.                         if (strstr(sFileName,".") == 0)
  369.                         {
  370.                             strcat(sFileName,".repnet");
  371.                         }
  372.                         Network::mRecordingFileName = sFileName;
  373.                         SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT2),sFileName);
  374.                     }
  375.                 }
  376.                 value = SendMessage(GetDlgItem(hwndDlg,IDC_CHECK10), BM_GETCHECK ,0, 0);
  377.                 if (value == BST_CHECKED)
  378.                 {
  379.                     ofn.Flags |= OFN_FILEMUSTEXIST;
  380.                     if (GetOpenFileName(&ofn))
  381.                     {
  382.                         Network::mRecordingFileName = sFileName;
  383.                         SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT2),sFileName);
  384.                         SendMessage (hwndDlg, WM_CLOSE, 0, -1L);
  385.                     }
  386.                 }
  387.                 break;
  388.             }
  389.  
  390.  
  391.             case IDC_EDIT1:
  392.                 SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_SETCURSEL, -1, 0);
  393.                 break;
  394.             case IDC_REFRESH:
  395.                 SendMessage(GetDlgItem(hwndDlg, IDC_LIST2), LB_RESETCONTENT, 0, 0);
  396.                 Network::mNetwork->SessionFind();
  397.                 break;
  398.             case IDC_JOIN:
  399.             {
  400.                 Network::mNetwork->SetCanBecomeMaster(canBeMaster);
  401.                 Network::mNetwork->SetCanSpider(canSpider);
  402.                 Network::mNetwork->SetCanAcceptObjects(canAcceptMigrationObjects);
  403.                 char buffer[256];
  404.                 int ret = GetWindowText(GetDlgItem(hwndDlg,IDC_EDIT1),buffer,sizeof(buffer));
  405.                 if (ret > 0)
  406.                 {
  407.                     Network::HandleRecording();
  408.                     Network::mNetwork->SessionJoin(std::string(buffer));
  409.                     failed_to = false;
  410.                     SendMessage (hwndDlg, WM_CLOSE, 0, -1L);
  411.                     break;
  412.                 }
  413.                 break;
  414.             }
  415.             case IDC_NEW:
  416.             case IDOK:
  417.                 CreateGame();
  418.  
  419.                 failed_to = false;
  420.                 SendMessage (hwndDlg, WM_CLOSE, 0, -1L);
  421.                 break;
  422.             case IDCANCEL:
  423.                 SendMessage (hwndDlg, WM_CLOSE, 0, -1L);
  424.                 break;
  425.         }
  426.         break;
  427.         case WM_CLOSE:
  428.             EndDialog (hwndDlg, lParam);
  429.             KillTimer(hwndDlg,1);
  430.             break;
  431.         default:
  432.             return 0;
  433.     }
  434.  
  435.     return 1;
  436. }
  437.  
  438. void Network::Network_Dialog(void)
  439. {
  440.     DialogBox(ghInst,MAKEINTRESOURCE(IDD_JOINORNEW),0,&Dlg_JoinOrNew);
  441. }
  442.  
  443. void Network::Network_Shutdown(void)
  444. {
  445.     // This demonstrates the nice way to disconnect from a network session
  446.     // None of this is strictly required by ReplicaNet because using delete on the ReplicaNet class also disconnects,
  447.     // however it does perform a very graceful disconnect.
  448.  
  449.     // First disconnect
  450.     mNetwork->Disconnect();
  451.  
  452.     // After deleting ReplicaNet it is not a good idea to use ReplicaNet functions on ReplicaObject derived classes
  453.     delete mNetwork;
  454.     mNetwork = 0;
  455.  
  456.     // We can shutdown the network here. Not strictly necessary but it demonstrates the graceful shutdown procedure.
  457.     RNReplicaNet::XPURL::ShutdownNetwork();
  458.  
  459.     // This force frees all remaining, one time allocated memory, from the ReplicaNet library. This memory usually exists
  460.     // for the lifetime of the application.
  461.     RNReplicaNet::PlatformHeap::ForceFree();
  462. }
  463.  
  464.