// Copyright (c) 2008-2023 the Urho3D project // License: MIT #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "NATPunchtrough.h" // Undefine Windows macro, as our Connection class has a function called SendMessage #ifdef SendMessage #undef SendMessage #endif URHO3D_DEFINE_APPLICATION_MAIN(NATPunchtrough) NATPunchtrough::NATPunchtrough(Context* context) : Sample(context) { } void NATPunchtrough::Start() { // Execute base class startup Sample::Start(); // Enable OS cursor GetSubsystem()->SetMouseVisible(true); // Create the user interface CreateUI(); // Subscribe to UI and network events SubscribeToEvents(); // Set the mouse mode to use in the sample Sample::InitMouseMode(MM_FREE); } void NATPunchtrough::CreateUI() { SetLogoVisible(true); // We need the full rendering window UIElement* root = GetSubsystem()->GetRoot(); auto* cache = GetSubsystem(); auto* uiStyle = cache->GetResource("UI/DefaultStyle.xml"); // Set style to the UI root so that elements will inherit it root->SetDefaultStyle(uiStyle); auto* font = cache->GetResource("Fonts/Anonymous Pro.ttf"); logHistoryText_ = root->CreateChild(); logHistoryText_->SetFont(font, 12); logHistoryText_->SetPosition(20, -20); logHistoryText_->SetVerticalAlignment(VA_BOTTOM); logHistory_.Resize(20); // Create NAT server config fields int marginTop = 40; CreateLabel("1. Run NAT server somewhere, enter NAT server info and press 'Save NAT settings'", IntVector2(20, marginTop-20)); natServerAddress_ = CreateLineEdit("127.0.0.1", 200, IntVector2(20, marginTop)); natServerPort_ = CreateLineEdit("61111", 100, IntVector2(240, marginTop)); saveNatSettingsButton_ = CreateButton("Save NAT settings", 160, IntVector2(360, marginTop)); // Create server start button marginTop = 120; CreateLabel("2. Create server and give others your server GUID", IntVector2(20, marginTop-20)); guid_ = CreateLineEdit("Your server GUID", 200, IntVector2(20, marginTop)); startServerButton_ = CreateButton("Start server", 160, IntVector2(240, marginTop)); // Create client connection related fields marginTop = 200; CreateLabel("3. Input local or remote server GUID", IntVector2(20, marginTop-20)); serverGuid_ = CreateLineEdit("Remote server GUID", 200, IntVector2(20, marginTop)); connectButton_ = CreateButton("Connect", 160, IntVector2(240, marginTop)); // No viewports or scene is defined. However, the default zone's fog color controls the fill color GetSubsystem()->GetDefaultZone()->SetFogColor(Color(0.0f, 0.0f, 0.1f)); } void NATPunchtrough::SubscribeToEvents() { SubscribeToEvent(E_SERVERCONNECTED, URHO3D_HANDLER(NATPunchtrough, HandleServerConnected)); SubscribeToEvent(E_SERVERDISCONNECTED, URHO3D_HANDLER(NATPunchtrough, HandleServerDisconnected)); SubscribeToEvent(E_CONNECTFAILED, URHO3D_HANDLER(NATPunchtrough, HandleConnectFailed)); // NAT server connection related events SubscribeToEvent(E_NATMASTERCONNECTIONFAILED, URHO3D_HANDLER(NATPunchtrough, HandleNatConnectionFailed)); SubscribeToEvent(E_NATMASTERCONNECTIONSUCCEEDED, URHO3D_HANDLER(NATPunchtrough, HandleNatConnectionSucceeded)); SubscribeToEvent(E_NATMASTERDISCONNECTED, URHO3D_HANDLER(NATPunchtrough, HandleNatDisconnected)); // NAT punchtrough request events SubscribeToEvent(E_NETWORKNATPUNCHTROUGHSUCCEEDED, URHO3D_HANDLER(NATPunchtrough, HandleNatPunchtroughSucceeded)); SubscribeToEvent(E_NETWORKNATPUNCHTROUGHFAILED, URHO3D_HANDLER(NATPunchtrough, HandleNatPunchtroughFailed)); SubscribeToEvent(E_CLIENTCONNECTED, URHO3D_HANDLER(NATPunchtrough, HandleClientConnected)); SubscribeToEvent(E_CLIENTDISCONNECTED, URHO3D_HANDLER(NATPunchtrough, HandleClientDisconnected)); SubscribeToEvent(saveNatSettingsButton_, "Released", URHO3D_HANDLER(NATPunchtrough, HandleSaveNatSettings)); SubscribeToEvent(startServerButton_, "Released", URHO3D_HANDLER(NATPunchtrough, HandleStartServer)); SubscribeToEvent(connectButton_, "Released", URHO3D_HANDLER(NATPunchtrough, HandleConnect)); } Button* NATPunchtrough::CreateButton(const String& text, int width, IntVector2 position) { auto* cache = GetSubsystem(); auto* font = cache->GetResource("Fonts/Anonymous Pro.ttf"); auto* button = GetSubsystem()->GetRoot()->CreateChild