80 lines
3.1 KiB
C#
80 lines
3.1 KiB
C#
using ProjectM.Simulation;
|
|
using Unity.Entities;
|
|
using Unity.NetCode;
|
|
using UnityEngine;
|
|
|
|
namespace ProjectM.Client
|
|
{
|
|
/// <summary>
|
|
/// Minimal IMGUI Host / Join (+ IP) panel for the M4 LAN flow — the connection entry point for player
|
|
/// builds, where there is no editor auto-host. Writes a <see cref="ConnectionConfig"/> request into the
|
|
/// relevant netcode world(s): <b>Host</b> makes the server world listen and the local client join over
|
|
/// loopback; <b>Join</b> makes the client world connect to the typed IP. Hides itself once the client
|
|
/// world has a connection. Direct IP/LAN only — Unity Relay is deferred to a later pass. In the editor
|
|
/// the <c>EditorAutoHostSystem</c> usually connects first, so this panel just shows "Connected".
|
|
/// </summary>
|
|
public class ConnectionUI : MonoBehaviour
|
|
{
|
|
[SerializeField] ushort _port = 7979;
|
|
|
|
string _ipField = "127.0.0.1";
|
|
|
|
void OnGUI()
|
|
{
|
|
if (IsClientConnected())
|
|
{
|
|
GUILayout.BeginArea(new Rect(10, 10, 220, 26));
|
|
GUILayout.Label("Net: Connected");
|
|
GUILayout.EndArea();
|
|
return;
|
|
}
|
|
|
|
GUILayout.BeginArea(new Rect(10, 10, 240, 150), GUI.skin.box);
|
|
GUILayout.Label("Project M — LAN co-op");
|
|
|
|
// Host is only possible where a server world exists (editor or a ClientServer/host build).
|
|
if (ClientServerBootstrap.ServerWorld is { IsCreated: true })
|
|
{
|
|
if (GUILayout.Button("Host"))
|
|
{
|
|
Seed(ClientServerBootstrap.ServerWorld, ConnectionMode.Host, "0.0.0.0", _port);
|
|
Seed(ClientServerBootstrap.ClientWorld, ConnectionMode.Join, "127.0.0.1", _port);
|
|
}
|
|
GUILayout.Space(6);
|
|
}
|
|
|
|
GUILayout.Label("Join host IP:");
|
|
_ipField = GUILayout.TextField(_ipField);
|
|
if (GUILayout.Button("Join"))
|
|
Seed(ClientServerBootstrap.ClientWorld, ConnectionMode.Join, _ipField, _port);
|
|
|
|
GUILayout.EndArea();
|
|
}
|
|
|
|
static bool IsClientConnected()
|
|
{
|
|
var world = ClientServerBootstrap.ClientWorld;
|
|
if (world is not { IsCreated: true })
|
|
return false;
|
|
using var q = world.EntityManager.CreateEntityQuery(ComponentType.ReadOnly<NetworkId>());
|
|
return !q.IsEmpty;
|
|
}
|
|
|
|
static void Seed(World world, ConnectionMode mode, string address, ushort port)
|
|
{
|
|
if (world is not { IsCreated: true })
|
|
return;
|
|
var em = world.EntityManager;
|
|
using var q = em.CreateEntityQuery(ComponentType.ReadWrite<ConnectionConfig>());
|
|
Entity e = q.IsEmpty ? em.CreateEntity(typeof(ConnectionConfig)) : q.GetSingletonEntity();
|
|
em.SetComponentData(e, new ConnectionConfig
|
|
{
|
|
Mode = mode,
|
|
Address = address,
|
|
Port = port,
|
|
Requested = true,
|
|
});
|
|
}
|
|
}
|
|
}
|