Implement IPv6 support for server and direct connect

This commit is contained in:
jrb0001
2020-01-06 22:19:52 +01:00
committed by reaperrr
parent bd1a936c7a
commit bf397591f9
16 changed files with 328 additions and 118 deletions

View File

@@ -11,7 +11,6 @@
using System;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -49,7 +48,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
[ObjectCreator.UseCtor]
public ConnectionLogic(Widget widget, string host, int port, Action onConnect, Action onAbort, Action<string> onRetry)
public ConnectionLogic(Widget widget, ConnectionTarget endpoint, Action onConnect, Action onAbort, Action<string> onRetry)
{
this.onConnect = onConnect;
this.onAbort = onAbort;
@@ -61,18 +60,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
panel.Get<ButtonWidget>("ABORT_BUTTON").OnClick = () => { CloseWindow(); onAbort(); };
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Connecting to {0}:{1}...".F(host, port);
"Connecting to {0}...".F(endpoint);
}
public static void Connect(string host, int port, string password, Action onConnect, Action onAbort)
public static void Connect(ConnectionTarget endpoint, string password, Action onConnect, Action onAbort)
{
Game.JoinServer(host, port, password);
Action<string> onRetry = newPassword => Connect(host, port, newPassword, onConnect, onAbort);
Game.JoinServer(endpoint, password);
Action<string> onRetry = newPassword => Connect(endpoint, newPassword, onConnect, onAbort);
Ui.OpenWindow("CONNECTING_PANEL", new WidgetArgs()
{
{ "host", host },
{ "port", port },
{ "endpoint", endpoint },
{ "onConnect", onConnect },
{ "onAbort", onAbort },
{ "onRetry", onRetry }
@@ -105,10 +103,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Could not connect to {0}:{1}".F(orderManager.Host, orderManager.Port);
"Could not connect to {0}".F(orderManager.Endpoint);
var connectionError = widget.Get<LabelWidget>("CONNECTION_ERROR");
connectionError.GetText = () => orderManager.ServerError;
connectionError.GetText = () => orderManager.ServerError ?? orderManager.Connection.ErrorMessage ?? "Unknown error";
var panelTitle = widget.Get<LabelWidget>("TITLE");
panelTitle.GetText = () => orderManager.AuthenticationFailed ? "Password Required" : "Connection Failed";
@@ -165,7 +163,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
switchButton.OnClick = () =>
{
var launchCommand = "Launch.Connect=" + orderManager.Host + ":" + orderManager.Port;
var launchCommand = "Launch.URI={0}".F(new UriBuilder("tcp", orderManager.Connection.EndPoint.Address.ToString(), orderManager.Connection.EndPoint.Port));
Game.SwitchToExternalMod(orderManager.ServerExternalMod, new[] { launchCommand }, () =>
{
orderManager.ServerError = "Failed to switch mod.";

View File

@@ -10,6 +10,7 @@
#endregion
using System;
using OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -19,15 +20,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
static readonly Action DoNothing = () => { };
[ObjectCreator.UseCtor]
public DirectConnectLogic(Widget widget, Action onExit, Action openLobby, string directConnectHost, int directConnectPort)
public DirectConnectLogic(Widget widget, Action onExit, Action openLobby, ConnectionTarget directConnectEndPoint)
{
var panel = widget;
var ipField = panel.Get<TextFieldWidget>("IP");
var portField = panel.Get<TextFieldWidget>("PORT");
var last = Game.Settings.Player.LastServer.Split(':');
ipField.Text = last.Length > 1 ? last[0] : "localhost";
portField.Text = last.Length == 2 ? last[1] : "1234";
var text = Game.Settings.Player.LastServer;
var last = text.LastIndexOf(':');
if (last < 0)
{
ipField.Text = "localhost";
portField.Text = "1234";
}
else
{
ipField.Text = text.Substring(0, last);
portField.Text = text.Substring(last + 1);
}
panel.Get<ButtonWidget>("JOIN_BUTTON").OnClick = () =>
{
@@ -36,19 +46,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Game.Settings.Player.LastServer = "{0}:{1}".F(ipField.Text, port);
Game.Settings.Save();
ConnectionLogic.Connect(ipField.Text, port, "", () => { Ui.CloseWindow(); openLobby(); }, DoNothing);
ConnectionLogic.Connect(new ConnectionTarget(ipField.Text, port), "", () => { Ui.CloseWindow(); openLobby(); }, DoNothing);
};
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
if (directConnectHost != null)
if (directConnectEndPoint != null)
{
// The connection window must be opened at the end of the tick for the widget hierarchy to
// work out, but we also want to prevent the server browser from flashing visible for one tick.
widget.Visible = false;
Game.RunAfterTick(() =>
{
ConnectionLogic.Connect(directConnectHost, directConnectPort, "", () => { Ui.CloseWindow(); openLobby(); }, DoNothing);
ConnectionLogic.Connect(directConnectEndPoint, "", () => { Ui.CloseWindow(); openLobby(); }, DoNothing);
widget.Visible = true;
});
}

View File

@@ -71,8 +71,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// It's not clear why this is needed here, but not in the other places that load maps.
Game.RunAfterTick(() =>
{
ConnectionLogic.Connect(System.Net.IPAddress.Loopback.ToString(),
Game.CreateLocalServer(uid), "",
ConnectionLogic.Connect(Game.CreateLocalServer(uid), "",
() => Game.LoadEditor(uid),
() => { Game.CloseServer(); onExit(); });
});

View File

@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
});
};
Action<string> onRetry = password => ConnectionLogic.Connect(om.Host, om.Port, password, onConnect, onExit);
Action<string> onRetry = password => ConnectionLogic.Connect(om.Endpoint, password, onConnect, onExit);
var switchPanel = om.ServerExternalMod != null ? "CONNECTION_SWITCHMOD_PANEL" : "CONNECTIONFAILED_PANEL";
Ui.OpenWindow(switchPanel, new WidgetArgs()

View File

@@ -17,6 +17,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Widgets;
@@ -298,22 +299,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic
button.AttachPanel(newsPanel, () => newsOpen = false);
}
void OnRemoteDirectConnect(string host, int port)
void OnRemoteDirectConnect(ConnectionTarget endpoint)
{
SwitchMenu(MenuType.None);
Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
{
{ "onStart", RemoveShellmapUI },
{ "onExit", () => SwitchMenu(MenuType.Main) },
{ "directConnectHost", host },
{ "directConnectPort", port },
{ "directConnectEndPoint", endpoint },
});
}
void LoadMapIntoEditor(string uid)
{
ConnectionLogic.Connect(IPAddress.Loopback.ToString(),
Game.CreateLocalServer(uid),
ConnectionLogic.Connect(Game.CreateLocalServer(uid),
"",
() => { Game.LoadEditor(uid); },
() => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });
@@ -425,8 +424,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Game.Settings.Server.Map = map;
Game.Settings.Save();
ConnectionLogic.Connect(IPAddress.Loopback.ToString(),
Game.CreateLocalServer(map),
ConnectionLogic.Connect(Game.CreateLocalServer(map),
"",
OpenSkirmishLobbyPanel,
() => { Game.CloseServer(); SwitchMenu(MenuType.Main); });
@@ -460,8 +458,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
{ "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Multiplayer; } },
{ "onExit", () => SwitchMenu(MenuType.Main) },
{ "directConnectHost", null },
{ "directConnectPort", 0 },
{ "directConnectEndPoint", null },
});
}

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ServerListLogic serverListLogic;
[ObjectCreator.UseCtor]
public MultiplayerLogic(Widget widget, ModData modData, Action onStart, Action onExit, string directConnectHost, int directConnectPort)
public MultiplayerLogic(Widget widget, ModData modData, Action onStart, Action onExit, ConnectionTarget directConnectEndPoint)
{
// MultiplayerLogic is a superset of the ServerListLogic
// but cannot be a direct subclass because it needs to pass object-level state to the constructor
@@ -41,8 +41,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
{ "openLobby", OpenLobby },
{ "onExit", DoNothing },
{ "directConnectHost", null },
{ "directConnectPort", 0 },
{ "directConnectEndPoint", null },
});
};
@@ -61,7 +60,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
widget.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
if (directConnectHost != null)
if (directConnectEndPoint != null)
{
// The connection window must be opened at the end of the tick for the widget hierarchy to
// work out, but we also want to prevent the server browser from flashing visible for one tick.
@@ -72,8 +71,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
{ "openLobby", OpenLobby },
{ "onExit", DoNothing },
{ "directConnectHost", directConnectHost },
{ "directConnectPort", directConnectPort },
{ "directConnectEndPoint", directConnectEndPoint },
});
widget.Visible = true;
@@ -93,8 +91,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
{ "onStart", onStart },
{ "onExit", onExit },
{ "directConnectHost", null },
{ "directConnectPort", 0 },
{ "directConnectEndPoint", null },
});
Game.Disconnect();
@@ -116,7 +113,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var host = server.Address.Split(':')[0];
var port = Exts.ParseIntegerInvariant(server.Address.Split(':')[1]);
ConnectionLogic.Connect(host, port, "", OpenLobby, DoNothing);
ConnectionLogic.Connect(new ConnectionTarget(host, port), "", OpenLobby, DoNothing);
}
bool disposed;

View File

@@ -11,7 +11,6 @@
using System;
using System.Linq;
using System.Net;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Widgets;
@@ -199,7 +198,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Create and join the server
try
{
Game.CreateServer(settings);
var endpoint = Game.CreateServer(settings);
Ui.CloseWindow();
ConnectionLogic.Connect(endpoint, password, onCreate, onExit);
}
catch (System.Net.Sockets.SocketException e)
{
@@ -212,11 +214,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
message += "\nError is: \"{0}\" ({1})".F(e.Message, e.ErrorCode);
ConfirmationDialogs.ButtonPrompt("Server Creation Failed", message, onCancel: () => { }, cancelText: "Back");
return;
}
Ui.CloseWindow();
ConnectionLogic.Connect(IPAddress.Loopback.ToString(), Game.Settings.Server.ListenPort, password, onCreate, onExit);
}
}
}