| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- // Copyright (c) 2008-2023 the Urho3D project
- // License: MIT
- #include <Urho3D/Audio/Audio.h>
- #include <Urho3D/Audio/Sound.h>
- #include <Urho3D/Engine/Engine.h>
- #include <Urho3D/Graphics/Zone.h>
- #include <Urho3D/Input/Input.h>
- #include <Urho3D/IO/Log.h>
- #include <Urho3D/IO/MemoryBuffer.h>
- #include <Urho3D/IO/VectorBuffer.h>
- #include <Urho3D/Network/Network.h>
- #include <Urho3D/Network/NetworkEvents.h>
- #include <Urho3D/Resource/ResourceCache.h>
- #include <Urho3D/UI/Button.h>
- #include <Urho3D/UI/Font.h>
- #include <Urho3D/UI/LineEdit.h>
- #include <Urho3D/UI/Text.h>
- #include <Urho3D/UI/UI.h>
- #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<Input>()->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<UI>()->GetRoot();
- auto* cache = GetSubsystem<ResourceCache>();
- auto* uiStyle = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
- // Set style to the UI root so that elements will inherit it
- root->SetDefaultStyle(uiStyle);
- auto* font = cache->GetResource<Font>("Fonts/Anonymous Pro.ttf");
- logHistoryText_ = root->CreateChild<Text>();
- 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<Renderer>()->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<ResourceCache>();
- auto* font = cache->GetResource<Font>("Fonts/Anonymous Pro.ttf");
- auto* button = GetSubsystem<UI>()->GetRoot()->CreateChild<Button>();
- button->SetStyleAuto();
- button->SetFixedWidth(width);
- button->SetFixedHeight(30);
- button->SetPosition(position);
- auto* buttonText = button->CreateChild<Text>();
- buttonText->SetFont(font, 12);
- buttonText->SetAlignment(HA_CENTER, VA_CENTER);
- buttonText->SetText(text);
- return button;
- }
- LineEdit* NATPunchtrough::CreateLineEdit(const String& placeholder, int width, IntVector2 pos)
- {
- auto* textEdit = GetSubsystem<UI>()->GetRoot()->CreateChild<LineEdit>("");
- textEdit->SetStyleAuto();
- textEdit->SetFixedWidth(width);
- textEdit->SetFixedHeight(30);
- textEdit->SetText(placeholder);
- textEdit->SetPosition(pos);
- return textEdit;
- }
- void NATPunchtrough::CreateLabel(const String& text, IntVector2 pos)
- {
- auto* cache = GetSubsystem<ResourceCache>();
- // Create log element to view latest logs from the system
- auto* font = cache->GetResource<Font>("Fonts/Anonymous Pro.ttf");
- auto* label = GetSubsystem<UI>()->GetRoot()->CreateChild<Text>();
- label->SetFont(font, 12);
- label->SetColor(Color(0.0f, 1.0f, 0.0f));
- label->SetPosition(pos);
- label->SetText(text);
- }
- void NATPunchtrough::ShowLogMessage(const String& row)
- {
- logHistory_.Erase(0);
- logHistory_.Push(row);
- // Concatenate all the rows in history
- String allRows;
- for (const String& row : logHistory_)
- allRows += row + "\n";
- logHistoryText_->SetText(allRows);
- }
- void NATPunchtrough::HandleSaveNatSettings(StringHash eventType, VariantMap& eventData)
- {
- // Save NAT server configuration
- GetSubsystem<Network>()->SetNATServerInfo(natServerAddress_->GetText(), ToI32(natServerPort_->GetText()));
- ShowLogMessage("Saving NAT settings: " + natServerAddress_->GetText() + ":" + natServerPort_->GetText());
- }
- void NATPunchtrough::HandleServerConnected(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Client: Server connected!");
- }
- void NATPunchtrough::HandleServerDisconnected(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Client: Server disconnected!");
- }
- void NATPunchtrough::HandleConnectFailed(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Client: Connection failed!");
- }
- void NATPunchtrough::HandleNatDisconnected(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Disconnected from NAT master server");
- }
- void NATPunchtrough::HandleStartServer(StringHash eventType, VariantMap& eventData)
- {
- GetSubsystem<Network>()->StartServer(SERVER_PORT);
- ShowLogMessage("Server: Server started on port: " + String(SERVER_PORT));
- // Connect to the NAT server
- GetSubsystem<Network>()->StartNATClient();
- ShowLogMessage("Server: Starting NAT client for server...");
- // Output our assigned GUID which others will use to connect to our server
- guid_->SetText(GetSubsystem<Network>()->GetGUID());
- serverGuid_->SetText(GetSubsystem<Network>()->GetGUID());
- }
- void NATPunchtrough::HandleConnect(StringHash eventType, VariantMap& eventData)
- {
- VariantMap userData;
- userData["Name"] = "Urho3D";
- // Attempt connecting to server using custom GUID, Scene = null as a second parameter and user identity is passed as third parameter
- GetSubsystem<Network>()->AttemptNATPunchtrough(serverGuid_->GetText(), nullptr, userData);
- ShowLogMessage("Client: Attempting NAT punchtrough to guid: " + serverGuid_->GetText());
- }
- void NATPunchtrough::HandleNatConnectionFailed(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Connection to NAT master server failed!");
- }
- void NATPunchtrough::HandleNatConnectionSucceeded(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Connection to NAT master server succeeded!");
- }
- void NATPunchtrough::HandleNatPunchtroughSucceeded(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("NAT punchtrough succeeded!");
- }
- void NATPunchtrough::HandleNatPunchtroughFailed(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("NAT punchtrough failed!");
- }
- void NATPunchtrough::HandleClientConnected(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Server: Client connected!");
- }
- void NATPunchtrough::HandleClientDisconnected(StringHash eventType, VariantMap& eventData)
- {
- ShowLogMessage("Server: Client disconnected!");
- }
|