Did some more work on unity side of things

This commit is contained in:
NIMFER 2022-08-15 01:01:29 +02:00
parent 711b572fe8
commit 1957cf2bfb
19 changed files with 2642 additions and 817 deletions

View file

@ -31,7 +31,7 @@ namespace FishBait
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
GUILayout.Label(Resources.Load<Texture>("FishBait"), GUILayout.Height(50), GUILayout.Width(100)); GUILayout.Label(Resources.Load<Texture>("fishbait_Logo"), GUILayout.Height(150), GUILayout.Width(200));
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();

View file

@ -29,6 +29,8 @@ public class FishBaitDirectConnectModule : MonoBehaviour
return; return;
} }
directConnectTransport.OnRemoteConnectionState += RemoteConnectionState;
directConnectTransport.OnServerConnectionState += ServerConnectionState; directConnectTransport.OnServerConnectionState += ServerConnectionState;
directConnectTransport.OnServerReceivedData += ServerDataRecived; directConnectTransport.OnServerReceivedData += ServerDataRecived;

View file

@ -19,6 +19,9 @@ namespace FishBait
public partial class FishBaitTransport : Transport public partial class FishBaitTransport : Transport
{ {
#region Forward everything to Transport #region Forward everything to Transport
public override event Action<ClientConnectionStateArgs> OnClientConnectionState public override event Action<ClientConnectionStateArgs> OnClientConnectionState
{ {
add add
@ -187,14 +190,6 @@ namespace FishBait
{ {
transport.SetPort(port); transport.SetPort(port);
} }
public enum OpCodes
{
Default = 0, RequestID = 1, JoinServer = 2, SendData = 3, GetID = 4, ServerJoined = 5, GetData = 6, CreateRoom = 7, ServerLeft = 8, PlayerDisconnected = 9, RoomCreated = 10,
LeaveRoom = 11, KickPlayer = 12, AuthenticationRequest = 13, AuthenticationResponse = 14, Authenticated = 17, UpdateRoomData = 18, ServerConnectionData = 19, RequestNATConnection = 20,
DirectConnectIP = 21
}
} }
} }

View file

@ -0,0 +1,68 @@
using System;
using System.Net;
using System.Collections;
using UnityEngine;
using FishNet.Transporting;
namespace FishBait
{
public partial class FishBaitTransport : Transport
{
IEnumerator NATPunch(IPEndPoint remoteAddress)
{
for (int i = 0; i < 10; i++)
{
_NATPuncher.Send(_punchData, 1, remoteAddress);
yield return new WaitForSeconds(0.25f);
}
}
void RecvData(IAsyncResult result)
{
IPEndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
var data = _NATPuncher.EndReceive(result, ref newClientEP);
_NATPuncher.BeginReceive(new AsyncCallback(RecvData), _NATPuncher);
if (!newClientEP.Address.Equals(_relayPuncherIP.Address))
{
if (_isServer)
{
if (_serverProxies.TryGetByFirst(newClientEP, out SocketProxy foundProxy))
{
if (data.Length > 2)
foundProxy.RelayData(data, data.Length);
}
else
{
_serverProxies.Add(newClientEP, new SocketProxy(_NATIP.Port + 1, newClientEP));
_serverProxies.GetByFirst(newClientEP).dataReceived += ServerProcessProxyData;
}
}
if (_isClient)
{
if (_clientProxy == null)
{
_clientProxy = new SocketProxy(_NATIP.Port - 1);
_clientProxy.dataReceived += ClientProcessProxyData;
}
else
{
_clientProxy.ClientRelayData(data, data.Length);
}
}
}
}
void ServerProcessProxyData(IPEndPoint remoteEndpoint, byte[] data)
{
_NATPuncher.Send(data, data.Length, remoteEndpoint);
}
void ClientProcessProxyData(IPEndPoint _, byte[] data)
{
_NATPuncher.Send(data, data.Length, _directConnectEndpoint);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29e2405d83bb6054abaf2f3d7b19b19f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,470 @@
using FishNet.Managing;
using FishNet.Managing.Logging;
using FishNet.Serializing;
using FishNet.Transporting;
using FishNet.Utility.Extension;
using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEngine;
using FishNet.Transporting.Tugboat;
using FishNet.Managing.Transporting;
using FishNet.Transporting.Multipass;
using System.Net.Sockets;
namespace FishBait
{
public partial class FishBaitTransport : Transport
{
public bool IsAuthenticated() => _isAuthenticated;
private void Awake()
{
if (Application.platform == RuntimePlatform.WebGLPlayer)
useNATPunch = false;
else
_directConnectModule = GetComponent<FishBaitDirectConnectModule>();
if (transport is FishBaitTransport)
throw new Exception("Haha real funny... Use a different transport.");
if (_directConnectModule != null)
{
if (useNATPunch && !_directConnectModule.SupportsNATPunch())
{
Debug.LogWarning("FishBait | NATPunch is turned on but the transport used does not support it. It will be disabled.");
useNATPunch = false;
}
}
SetupCallbacks();
if (connectOnAwake)
ConnectToRelay();
InvokeRepeating(nameof(SendHeartbeat), heartBeatInterval, heartBeatInterval);
}
private void SetupCallbacks()
{
if (_callbacksInitialized)
return;
_callbacksInitialized = true;
transport.OnClientConnectionState += ClientConnectionState;
transport.OnClientReceivedData += ClientDataRecived;
}
void ClientConnectionState(ClientConnectionStateArgs args)
{
switch (args.ConnectionState)
{
case LocalConnectionState.Started:
OnConnectedToRelay();
break;
case LocalConnectionState.Stopped:
Disconnected();
break;
}
}
void ClientDataRecived(ClientReceivedDataArgs args)
{
DataReceived(args.Data, (int)args.Channel);
}
private void Disconnected()
{
_connectedToRelay = false;
_isAuthenticated = false;
disconnectedFromRelay?.Invoke();
serverStatus = "Disconnected from relay.";
}
private void OnConnectedToRelay()
{
_connectedToRelay = true;
connectedToRelay?.Invoke();
}
public void ConnectToRelay()
{
if (!useLoadBalancer)
{
if (!_connectedToRelay)
{
Connect(serverIP, serverPort);
}
else
{
Debug.LogWarning("FishBait | Already connected to relay!");
}
}
else
{
if (!_connectedToRelay)
{
StartCoroutine(RelayConnect());
}
else
{
Debug.LogWarning("FishBait | Already connected to relay!");
}
}
}
/// <summary>
/// Connects to the desired relay
/// </summary>
/// <param name="serverIP"></param>
private void Connect(string serverIP, ushort port = 7777)
{
// need to implement custom port
if (transport is FishBaitTransport)
throw new Exception("FishBait | Client to Server Transport cannot be FishBait.");
SetTransportPort(port);
this.serverIP = serverIP;
serverStatus = "Connecting to relay...";
_clientSendBuffer = new byte[transport.GetMTU(0)];
transport.SetClientAddress(serverIP);
transport.StartConnection(false);
}
public void DisconnectFromRelay()
{
if (IsAuthenticated())
{
transport.StopConnection(false);
}
}
private void SendHeartbeat()
{
if (_connectedToRelay)
{
// Send a blank message with just the opcode 200, which is heartbeat
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, 200);
transport.SendToServer(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
// If NAT Puncher is initialized, send heartbeat on that as well.
try
{
if (_NATPuncher != null)
_NATPuncher.Send(new byte[] { 0 }, 1, _relayPuncherIP);
}
catch (Exception e)
{
print(e);
}
// Check if any server-side proxies havent been used in 10 seconds, and timeout if so.
var keys = new List<IPEndPoint>(_serverProxies.GetAllKeys());
for (int i = 0; i < keys.Count; i++)
{
if (DateTime.Now.Subtract(_serverProxies.GetByFirst(keys[i]).lastInteractionTime).TotalSeconds > 10)
{
_serverProxies.GetByFirst(keys[i]).Dispose();
_serverProxies.Remove(keys[i]);
}
}
}
}
private void DataReceived(ArraySegment<byte> segmentData, int channel)
{
try
{
var data = segmentData.Array;
int pos = segmentData.Offset;
// Read the opcode of the incoming data, this allows us to know what its used for.
OpCodes opcode = (OpCodes)data.ReadByte(ref pos);
switch (opcode)
{
case OpCodes.Authenticated:
// Server authenticated us! That means we are fully ready to host and join servers.
serverStatus = "Authenticated! Good to go!";
_isAuthenticated = true;
RequestServerList();
break;
case OpCodes.AuthenticationRequest:
// Server requested that we send an authentication request, lets send our auth key.
serverStatus = "Sent authentication to relay...";
SendAuthKey();
break;
case OpCodes.GetData:
// Someone sent us a packet from their mirror over the relay
var recvData = data.ReadBytes(ref pos);
// If we are the server and the client is registered, invoke the callback
if (_isServer)
{
if (_connectedRelayClients.TryGetByFirst(data.ReadInt(ref pos), out int clientID))
OnServerDataReceived?.Invoke(clientID, new ArraySegment<byte>(recvData), channel);
}
// If we are the client, invoke the callback
if (_isClient)
OnClientDataReceived?.Invoke(new ArraySegment<byte>(recvData), channel);
break;
case OpCodes.ServerLeft:
// Called when we were kicked, or server was closed.
if (_isClient)
{
_isClient = false;
OnClientDisconnected?.Invoke();
}
break;
case OpCodes.PlayerDisconnected:
// Called when another player left the room.
if (_isServer)
{
// Get their client ID and invoke the mirror callback
int user = data.ReadInt(ref pos);
if (_connectedRelayClients.TryGetByFirst(user, out int clientID))
{
OnServerDisconnected?.Invoke(clientID);
_connectedRelayClients.Remove(user);
}
}
break;
case OpCodes.RoomCreated:
// We successfully created the room, the server also gave us the serverId of the room!
serverId = data.ReadString(ref pos);
break;
case OpCodes.ServerJoined:
// Called when a player joins the room or when we joined a room.
int clientId = data.ReadInt(ref pos);
if (_isClient)
{
// We successfully joined a room, let mirror know.
OnClientConnected?.Invoke();
}
if (_isServer)
{
// A client joined our room, let mirror know and setup their ID in the dictionary.
_connectedRelayClients.Add(clientId, _currentMemberId);
OnServerConnected?.Invoke(_currentMemberId);
_currentMemberId++;
}
break;
case OpCodes.DirectConnectIP:
// Either a client is trying to join us via NAT Punch, or we are trying to join a host over NAT punch/Direct connect.
var ip = data.ReadString(ref pos);
int port = data.ReadInt(ref pos);
bool attemptNatPunch = data.ReadBool(ref pos);
_directConnectEndpoint = new IPEndPoint(IPAddress.Parse(ip), port);
// Both client and server will send data to each other to open the hole.
if (useNATPunch && attemptNatPunch)
{
StartCoroutine(NATPunch(_directConnectEndpoint));
}
if (!_isServer)
{
// We arent the server, so lets tell the direct connect module to attempt a connection and initializing our middle man socket.
if (_clientProxy == null && useNATPunch && attemptNatPunch)
{
_clientProxy = new SocketProxy(_NATIP.Port - 1);
_clientProxy.dataReceived += ClientProcessProxyData;
}
if (useNATPunch && attemptNatPunch)
{
if (ip == LOCALHOST)
_directConnectModule.JoinServer(LOCALHOST, port + 1);
else
_directConnectModule.JoinServer(LOCALHOST, _NATIP.Port - 1);
}
else
_directConnectModule.JoinServer(ip, port);
}
break;
case OpCodes.RequestNATConnection:
// Called when the FishBait node would like us to establish a NAT puncher connection. Its safe to ignore if NAT punch is disabled.
if (useNATPunch && GetLocalIp() != null && _directConnectModule != null)
{
byte[] initalData = new byte[150];
int sendPos = 0;
initalData.WriteBool(ref sendPos, true);
initalData.WriteString(ref sendPos, data.ReadString(ref pos));
NATPunchtroughPort = data.ReadInt(ref pos);
if (_NATPuncher == null)
{
_NATPuncher = new UdpClient { ExclusiveAddressUse = false };
while (true)
{
try
{
_NATIP = new IPEndPoint(IPAddress.Parse(GetLocalIp()), UnityEngine.Random.Range(16000, 17000));
_NATPuncher.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_NATPuncher.Client.Bind(_NATIP);
break;
}
catch { } // Binding port is in use, keep trying :P
}
}
if (!IPAddress.TryParse(serverIP, out IPAddress serverAddr))
serverAddr = Dns.GetHostEntry(serverIP).AddressList[0];
_relayPuncherIP = new IPEndPoint(serverAddr, NATPunchtroughPort);
for (int attempts = 0; attempts < NAT_PUNCH_ATTEMPTS; attempts++)
_NATPuncher.Send(initalData, sendPos, _relayPuncherIP);
_NATPuncher.BeginReceive(new AsyncCallback(RecvData), _NATPuncher);
}
break;
}
}
catch (Exception e) { print(e); }
}
public void UpdateRoomName(string newServerName = "My Awesome Server!")
{
if (_isServer)
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteString(ref pos, newServerName);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
transport.SendToServer(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
}
public void UpdateRoomData(string newServerData = "Extra Data!")
{
if (_isServer)
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteString(ref pos, newServerData);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
transport.SendToServer(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
}
public void UpdateRoomVisibility(bool isPublic = true)
{
if (_isServer)
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteBool(ref pos, isPublic);
_clientSendBuffer.WriteBool(ref pos, false);
transport.SendToServer(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
}
public void UpdateRoomPlayerCount(int maxPlayers = 16)
{
if (_isServer)
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.UpdateRoomData);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, false);
_clientSendBuffer.WriteBool(ref pos, true);
_clientSendBuffer.WriteInt(ref pos, maxPlayers);
transport.SendToServer(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
}
private Room? GetServerForID(string serverID)
{
for (int i = 0; i < relayServerList.Count; i++)
{
if (relayServerList[i].serverId == serverID)
return relayServerList[i];
}
return null;
}
private void SendAuthKey()
{
int pos = 0;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.AuthenticationResponse);
_clientSendBuffer.WriteString(ref pos, authenticationKey);
transport.SendToServer(0, new ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
public enum OpCodes
{
Default = 0, RequestID = 1, JoinServer = 2, SendData = 3, GetID = 4, ServerJoined = 5, GetData = 6, CreateRoom = 7, ServerLeft = 8, PlayerDisconnected = 9, RoomCreated = 10,
LeaveRoom = 11, KickPlayer = 12, AuthenticationRequest = 13, AuthenticationResponse = 14, Authenticated = 17, UpdateRoomData = 18, ServerConnectionData = 19, RequestNATConnection = 20,
DirectConnectIP = 21
}
}
[Serializable]
public struct Room
{
public string serverName;
public int maxPlayers;
public string serverId;
public string serverData;
public int hostId;
public List<int> clients;
public int currentPlayers;
public RelayAddress relayInfo;
}
[Serializable]
public struct RelayAddress
{
public ushort port;
public ushort endpointPort;
public string address;
public FishBaitRegions serverRegion;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43b6baab83425b9438868ec7a38f7b4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,242 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
using FishNet.Transporting;
using System;
using System.Net;
using System.Net.Sockets;
namespace FishBait
{
public partial class FishBaitTransport : Transport
{
public void RequestServerList(FishBaitRegions searchRegion = FishBaitRegions.Any)
{
if (_isAuthenticated && _connectedToRelay)
StartCoroutine(GetServerList(searchRegion));
else
Debug.Log("You must be connected to Relay to request server list!");
}
IEnumerator RelayConnect()
{
string url = $"http://{loadBalancerAddress}:{loadBalancerPort}/api/join/";
serverStatus = "Waiting for LLB...";
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
// Request and wait for the desired page.
webRequest.SetRequestHeader("x-Region", ((int)region).ToString());
webRequest.SetRequestHeader("Access-Control-Allow-Credentials", "true");
webRequest.SetRequestHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
webRequest.SetRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
webRequest.SetRequestHeader("Access-Control-Allow-Origin", "*");
yield return webRequest.SendWebRequest();
var result = webRequest.downloadHandler.text;
#if UNITY_2020_1_OR_NEWER
switch (webRequest.result)
{
case UnityWebRequest.Result.ConnectionError:
case UnityWebRequest.Result.DataProcessingError:
case UnityWebRequest.Result.ProtocolError:
Debug.LogWarning("FishBait | Network Error while getting a relay to join from Load Balancer.");
break;
case UnityWebRequest.Result.Success:
var parsedAddress = JsonUtility.FromJson<RelayAddress>(result);
Connect(parsedAddress.address, parsedAddress.port);
endpointServerPort = parsedAddress.endpointPort;
break;
}
#else
if (webRequest.isNetworkError || webRequest.isHttpError)
{
Debug.LogWarning("FishBait | Network Error while getting a relay to join from Load Balancer.");
}
else
{
// join here
var parsedAddress = JsonUtility.FromJson<RelayAddress>(result);
Connect(parsedAddress.address, parsedAddress.port);
endpointServerPort = parsedAddress.endpointPort;
}
#endif
}
}
IEnumerator JoinOtherRelayAndMatch(Room? roomValue, string ID)
{
var room = new Room();
// using load balancer, we NEED the server's relay address
if (roomValue.HasValue)
room = roomValue.Value;
else
{
_serverListUpdated = false;
RequestServerList();
yield return new WaitUntil(() => _serverListUpdated);
var foundRoom = GetServerForID(ID);
if (foundRoom.HasValue)
{
room = foundRoom.Value;
}
else
{
Debug.LogWarning("FishBait | Client tried to join a server that does not exist!");
OnClientDisconnected?.Invoke();
yield break;
}
}
// Wait for disconnection
DisconnectFromRelay();
while (IsAuthenticated())
yield return null;
endpointServerPort = room.relayInfo.endpointPort;
Connect(room.relayInfo.address, room.relayInfo.port);
while (!IsAuthenticated())
yield return null;
int pos = 0;
_directConnected = false;
_clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.JoinServer);
_clientSendBuffer.WriteString(ref pos, room.serverId);
_clientSendBuffer.WriteBool(ref pos, _directConnectModule != null);
string local = GetLocalIp();
_clientSendBuffer.WriteString(ref pos, local ?? "0.0.0.0");
_isClient = true;
transport.SendToServer(0, new System.ArraySegment<byte>(_clientSendBuffer, 0, pos));
}
IEnumerator GetServerList(FishBaitRegions region)
{
if (!useLoadBalancer)
{
string uri = $"http://{serverIP}:{endpointServerPort}/api/compressed/servers";
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
webRequest.SetRequestHeader("Access-Control-Allow-Credentials", "true");
webRequest.SetRequestHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
webRequest.SetRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
webRequest.SetRequestHeader("Access-Control-Allow-Origin", "*");
// Request and wait for the desired page.
yield return webRequest.SendWebRequest();
var result = webRequest.downloadHandler.text;
#if UNITY_2020_1_OR_NEWER
switch (webRequest.result)
{
case UnityWebRequest.Result.ConnectionError:
case UnityWebRequest.Result.DataProcessingError:
case UnityWebRequest.Result.ProtocolError:
Debug.LogWarning("FishBait | Network Error while retreiving the server list!");
break;
case UnityWebRequest.Result.Success:
relayServerList?.Clear();
relayServerList = JsonUtilityHelper.FromJson<Room>(result.Decompress()).ToList();
serverListUpdated?.Invoke();
break;
}
#else
if (webRequest.isNetworkError || webRequest.isHttpError)
{
Debug.LogWarning("FishBait | Network Error while retreiving the server list!");
}
else
{
relayServerList?.Clear();
relayServerList = JsonUtilityHelper.FromJson<Room>(result.Decompress()).ToList();
serverListUpdated?.Invoke();
}
#endif
}
}
else // get master list from load balancer
{
yield return StartCoroutine(RetrieveMasterServerListFromLoadBalancer(region));
}
/// <summary>
/// Gets master list from the LB.
/// This can be optimized but for now it is it's
/// own separate method, so i can understand wtf is going on :D
/// </summary>
/// <returns></returns>
IEnumerator RetrieveMasterServerListFromLoadBalancer(FishBaitRegions region)
{
string uri = $"http://{loadBalancerAddress}:{loadBalancerPort}/api/masterlist/";
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
webRequest.SetRequestHeader("x-Region", ((int)region).ToString());
// Request and wait for the desired page.
yield return webRequest.SendWebRequest();
var result = webRequest.downloadHandler.text;
#if UNITY_2020_1_OR_NEWER
switch (webRequest.result)
{
case UnityWebRequest.Result.ConnectionError:
case UnityWebRequest.Result.DataProcessingError:
case UnityWebRequest.Result.ProtocolError:
Debug.LogWarning("FishBait | Network Error while retreiving the server list!");
break;
case UnityWebRequest.Result.Success:
relayServerList?.Clear();
relayServerList = JsonUtilityHelper.FromJson<Room>(result).ToList();
serverListUpdated?.Invoke();
_serverListUpdated = true;
break;
}
#else
if (webRequest.isNetworkError || webRequest.isHttpError)
{
Debug.LogWarning("FishBait | Network Error while retreiving the server list!");
}
else
{
relayServerList?.Clear();
relayServerList = JsonUtilityHelper.FromJson<Room>(result).ToList();
serverListUpdated?.Invoke();
_serverListUpdated = true;
}
#endif
}
}
}
private static string GetLocalIp()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return null;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f0333d1a2f560a42a6368d017e21fc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -43,13 +43,13 @@ namespace FishBait
// Server list variables // Server list variables
public UnityEvent serverListUpdated; public UnityEvent serverListUpdated;
public List<object> relayServerList { private set; get; } = new List<object>(); public List<Room> relayServerList { private set; get; } = new List<Room>();
// Current Server Information // Current Server Information
public string serverStatus = "Not Started."; public string serverStatus = "Not Started.";
public string serverId = string.Empty; public string serverId = string.Empty;
private LRMDirectConnectModule _directConnectModule; private FishBaitDirectConnectModule _directConnectModule;
public FishBaitRegions region = FishBaitRegions.NorthAmerica; public FishBaitRegions region = FishBaitRegions.NorthAmerica;
private byte[] _clientSendBuffer; private byte[] _clientSendBuffer;

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

View file

@ -0,0 +1,134 @@
fileFormatVersion: 2
guid: 7ea33150c4705e343b2f3b84c78511c2
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,57 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using FishBait;
using FishNet.Transporting;
using FishNet.Managing;
public class FishBaitFunctionTest : MonoBehaviour
{
public Text functionDisplay;
private NetworkManager _NetworkManager;
private FishBaitTransport _FishBait;
private bool _serverListUpdated = false;
void Start()
{
_NetworkManager = FindObjectOfType<NetworkManager>();
_FishBait = (FishBaitTransport)_NetworkManager.TransportManager.Transport;
_FishBait.serverListUpdated.AddListener(ServerListUpdated);
StartCoroutine(TestFishBait());
}
void ServerListUpdated() => _serverListUpdated = true;
IEnumerator TestFishBait()
{
DisplayText("Waiting for FishBait to authenticate...");
yield return new WaitUntil(() => _FishBait.IsAuthenticated());
DisplayText("<color=lime>Authenticated!</color>");
DisplayText("Attempting hosting a room...");
_FishBait.serverName = "Default Server Name";
_FishBait.extraServerData = "Default Server Data";
_FishBait.maxServerPlayers = 5;
_FishBait.isPublicServer = true;
//_FishBait.StartConnection(true);
//_FishBait.StartConnection(false);
yield return new WaitUntil(() => _FishBait.serverId.Length > 4);
DisplayText($"<color=lime>Room created! ID: {_FishBait.serverId}</color>");
DisplayText("Requesting Server Data Change...");
_FishBait.UpdateRoomName("Updated Server Name");
_FishBait.UpdateRoomData("Updated Server Data");
_FishBait.UpdateRoomPlayerCount(10);
yield return new WaitForSeconds(1); // Give FishBait time to process
DisplayText("Requesting Server List...");
_FishBait.RequestServerList();
yield return new WaitUntil(() => _serverListUpdated);
foreach (var server in _FishBait.relayServerList)
DisplayText($"Got Server: {server.serverName}, {server.serverData}, {server.maxPlayers}");
}
void DisplayText(string msg)
{
functionDisplay.text += $"\n{msg}";
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d4a0423ee42dbe243bcf6dc7920c0c20
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b003de61e8843214dbabb568f06a57ed
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -520,7 +520,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!114 &1013063539 --- !u!114 &1013063539
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -607,57 +607,6 @@ Transform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 2 m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1094339529
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1094339531}
- component: {fileID: 1094339530}
m_Layer: 0
m_Name: FishBait - Connector
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1094339530
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1094339529}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6f48f002b825cbd45a19bd96d90f9edb, type: 3}
m_Name:
m_EditorClassIdentifier:
_unreliableMTU: 1023
_ipv4BindAddress:
_ipv6BindAddress:
_port: 7770
_maximumClients: 4095
_clientAddress: localhost
_timeout: 15
--- !u!4 &1094339531
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1094339529}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1516572637330113619}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1172724428 --- !u!1 &1172724428
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -850,757 +799,3 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
functionDisplay: {fileID: 278665276} functionDisplay: {fileID: 278665276}
--- !u!1 &1287384425
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1287384427}
- component: {fileID: 1287384426}
m_Layer: 0
m_Name: FishBait - Direct Connect
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1287384426
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1287384425}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6f48f002b825cbd45a19bd96d90f9edb, type: 3}
m_Name:
m_EditorClassIdentifier:
_unreliableMTU: 1023
_ipv4BindAddress:
_ipv6BindAddress:
_port: 7770
_maximumClients: 4095
_clientAddress: localhost
_timeout: 15
--- !u!4 &1287384427
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1287384425}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1516572637330113619}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!224 &905488192866952489
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5776995517907044923}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -1}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5670112770959365451}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1516572637330113616
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d2c95dfde7d73b54dbbdc23155d35d36, type: 3}
m_Name:
m_EditorClassIdentifier:
_refreshDefaultPrefabs: 0
_runInBackground: 1
_dontDestroyOnLoad: 1
_persistence: 0
_logging: {fileID: 0}
_spawnablePrefabs: {fileID: 11400000, guid: ec64eb18c93ab344892891f33edbf82a, type: 2}
--- !u!1 &1516572637330113617
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1516572637330113619}
- component: {fileID: 1516572637330113616}
- component: {fileID: 8234759579310384502}
- component: {fileID: 1516572637330113630}
- component: {fileID: 8234759579310384505}
- component: {fileID: 8234759579310384507}
- component: {fileID: 8234759579310384506}
m_Layer: 0
m_Name: FishNetworkManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1516572637330113619
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 5670112771492132974}
- {fileID: 1287384427}
- {fileID: 1094339531}
m_Father: {fileID: 0}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1516572637330113630
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 211a9f6ec51ddc14f908f5acc0cd0423, type: 3}
m_Name:
m_EditorClassIdentifier:
_playerPrefab: {fileID: 0}
_addToDefaultScene: 1
Spawns: []
--- !u!224 &1595977265591389899
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3529504718462195493}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -1}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5670112771043582155}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3447973838823685665
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5776995517907044923}
m_CullTransparentMesh: 0
--- !u!1 &3529504718462195493
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1595977265591389899}
- component: {fileID: 3788041517377950370}
- component: {fileID: 4993975790925741784}
m_Layer: 5
m_Name: Indicator
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!222 &3788041517377950370
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3529504718462195493}
m_CullTransparentMesh: 0
--- !u!114 &4993975790925741784
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3529504718462195493}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.25490198, g: 0.25490198, b: 0.25490198, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 2b3dca501a9d8c8479dc71dd068aa8b8, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &5670112770959365444
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112770959365448}
m_CullTransparentMesh: 0
--- !u!114 &5670112770959365445
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112770959365448}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 2d50394614f8feb4eb0567fb7618d84d, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &5670112770959365448
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5670112770959365451}
- component: {fileID: 5670112770959365444}
- component: {fileID: 5670112770959365445}
- component: {fileID: 5670112770959365450}
m_Layer: 5
m_Name: Client
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &5670112770959365450
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112770959365448}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 5670112770959365445}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5670112771492132978}
m_TargetAssemblyTypeName:
m_MethodName: OnClick_Client
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!224 &5670112770959365451
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112770959365448}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 905488192866952489}
m_Father: {fileID: 5670112771492132974}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 16, y: -96}
m_SizeDelta: {x: 256, y: 64}
m_Pivot: {x: 0, y: 1}
--- !u!222 &5670112771043582148
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771043582152}
m_CullTransparentMesh: 0
--- !u!114 &5670112771043582149
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771043582152}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 1b187e63031bf7849b249c8212440c3b, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &5670112771043582152
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5670112771043582155}
- component: {fileID: 5670112771043582148}
- component: {fileID: 5670112771043582149}
- component: {fileID: 5670112771043582154}
m_Layer: 5
m_Name: Server
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &5670112771043582154
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771043582152}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 5670112771043582149}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5670112771492132978}
m_TargetAssemblyTypeName:
m_MethodName: OnClick_Server
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!224 &5670112771043582155
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771043582152}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1595977265591389899}
m_Father: {fileID: 5670112771492132974}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 16, y: -16}
m_SizeDelta: {x: 256, y: 64}
m_Pivot: {x: 0, y: 1}
--- !u!114 &5670112771492132972
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771492132979}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 1920, y: 1080}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0.5
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!114 &5670112771492132973
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771492132979}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!224 &5670112771492132974
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771492132979}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 5670112771043582155}
- {fileID: 5670112770959365451}
m_Father: {fileID: 1516572637330113619}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!223 &5670112771492132975
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771492132979}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!114 &5670112771492132978
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5670112771492132979}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6d3606bfdac5a4743890fc1a5ecd8f24, type: 3}
m_Name:
m_EditorClassIdentifier:
_autoStartType: 0
_stoppedColor: {r: 0.25490198, g: 0.25490198, b: 0.25490198, a: 1}
_changingColor: {r: 0.78431374, g: 0.6862745, b: 0, a: 1}
_startedColor: {r: 0, g: 0.5882353, b: 0.64705884, a: 1}
_serverIndicator: {fileID: 4993975790925741784}
_clientIndicator: {fileID: 7026884142372709074}
--- !u!1 &5670112771492132979
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5670112771492132974}
- component: {fileID: 5670112771492132978}
- component: {fileID: 5670112771492132975}
- component: {fileID: 5670112771492132972}
- component: {fileID: 5670112771492132973}
m_Layer: 5
m_Name: NetworkHudCanvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &5776995517907044923
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 905488192866952489}
- component: {fileID: 3447973838823685665}
- component: {fileID: 7026884142372709074}
m_Layer: 5
m_Name: Indicator
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &7026884142372709074
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5776995517907044923}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.25490198, g: 0.25490198, b: 0.25490198, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 2b3dca501a9d8c8479dc71dd068aa8b8, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &8234759579310384502
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7d331f979d46e8e4a9fc90070c596d44, type: 3}
m_Name:
m_EditorClassIdentifier:
_updateHostVisibility: 1
_defaultConditions:
- {fileID: 11400000, guid: 2033f54fd2794464bae08fa5a55c8996, type: 2}
--- !u!114 &8234759579310384505
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 34e4a322dca349547989b14021da4e23, type: 3}
m_Name:
m_EditorClassIdentifier:
Transport: {fileID: 8234759579310384507}
_latencySimulator:
_enabled: 0
_simulateHost: 1
_latency: 0
_outOfOrder: 0
_packetLoss: 0
--- !u!114 &8234759579310384506
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 21eba6e2b0a7e964eb29db14a4eae4d6, type: 3}
m_Name:
m_EditorClassIdentifier:
directConnectTransport: {fileID: 1287384426}
showDebugLogs: 0
--- !u!114 &8234759579310384507
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1516572637330113617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 37bf248b7e575fe4592c1ec247b10573, type: 3}
m_Name:
m_EditorClassIdentifier:
transport: {fileID: 1094339530}
transportHolder: {fileID: 0}
serverIP: 172.105.109.117
serverPort: 7777
endpointServerPort: 8080
heartBeatInterval: 3
connectOnAwake: 1
authenticationKey: Secret Auth Key
disconnectedFromRelay:
m_PersistentCalls:
m_Calls: []
connectedToRelay:
m_PersistentCalls:
m_Calls: []
useNATPunch: 1
NATPunchtroughPort: 1
useLoadBalancer: 0
loadBalancerPort: 7070
loadBalancerAddress: 127.0.0.1
serverName: My awesome server!
extraServerData: Map 1
maxServerPlayers: 10
isPublicServer: 1
serverListUpdated:
m_PersistentCalls:
m_Calls: []
serverStatus: Not Started.
serverId:
region: 1

View file

@ -0,0 +1,154 @@
using FishNet.Transporting;
using FishNet.Managing;
using FishNet.Managing.Logging;
using FishNet.Serializing;
using FishNet.Utility.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEngine;
public class Test : Transport
{
public Transport transport;
private int fishBaitId;
private int transportId;
public override event Action<ClientConnectionStateArgs> OnClientConnectionState;
public override event Action<ServerConnectionStateArgs> OnServerConnectionState;
public override event Action<RemoteConnectionStateArgs> OnRemoteConnectionState;
public override event Action<ClientReceivedDataArgs> OnClientReceivedData;
public override event Action<ServerReceivedDataArgs> OnServerReceivedData;
public override string GetConnectionAddress(int connectionId)
{
return transport.GetConnectionAddress(connectionId);
}
public override LocalConnectionState GetConnectionState(bool server)
{
return GetConnectionState(server);
}
public override RemoteConnectionState GetConnectionState(int connectionId)
{
return transport.GetConnectionState(connectionId);
}
public override int GetMTU(byte channel)
{
return transport.GetMTU(channel);
}
public override void HandleClientConnectionState(ClientConnectionStateArgs connectionStateArgs)
{
transport.HandleClientConnectionState(connectionStateArgs);
}
public override void HandleClientReceivedDataArgs(ClientReceivedDataArgs receivedDataArgs)
{
transport.HandleClientReceivedDataArgs(receivedDataArgs);
}
public override void HandleRemoteConnectionState(RemoteConnectionStateArgs connectionStateArgs)
{
transport.HandleRemoteConnectionState(connectionStateArgs);
}
public override void HandleServerConnectionState(ServerConnectionStateArgs connectionStateArgs)
{
transport.HandleServerConnectionState(connectionStateArgs);
}
public override void HandleServerReceivedDataArgs(ServerReceivedDataArgs receivedDataArgs)
{
transport.HandleServerReceivedDataArgs(receivedDataArgs);
}
public override void IterateIncoming(bool server)
{
transport.IterateIncoming(server);
}
public override void IterateOutgoing(bool server)
{
transport.IterateOutgoing(server);
}
public override void SendToClient(byte channelId, ArraySegment<byte> segment, int connectionId)
{
transport.SendToClient(channelId, segment, connectionId);
}
public override void SendToServer(byte channelId, ArraySegment<byte> segment)
{
transport.SendToServer(channelId, segment);
}
public override void Shutdown()
{
transport.Shutdown();
}
public override bool StartConnection(bool server)
{
return transport.StartConnection(server);
}
public override bool StopConnection(bool server)
{
return transport.StopConnection(server);
}
public override bool StopConnection(int connectionId, bool immediately)
{
return transport.StopConnection(connectionId, immediately);
}
public override void Initialize(NetworkManager networkManager, int transportIndex)
{
base.Initialize(networkManager, transportIndex);
if (transport == null)
{
if (base.NetworkManager.CanLog(LoggingType.Error))
Debug.LogError($"No transport was set for use with FishBait");
}
transport.Initialize(networkManager, 0);
transport.OnClientConnectionState += FishBait_OnClientConnectionState;
}
public void FishBait_OnClientConnectionState(ClientConnectionStateArgs args)
{
OnClientConnectionState?.Invoke(args);
}
public void FishBait_OnServerConnectionState(ServerConnectionStateArgs args)
{
OnServerConnectionState?.Invoke(args);
}
public void FishBait_OnRemoteConnectionState(RemoteConnectionStateArgs args)
{
OnRemoteConnectionState?.Invoke(args);
}
public void FishBait_OnClientReceivedData(ClientReceivedDataArgs args)
{
OnClientReceivedData?.Invoke(args);
}
public void FishBait_OnServerReceivedData(ServerReceivedDataArgs args)
{
OnServerReceivedData?.Invoke(args);
}
private void OnDestroy()
{
transport.Shutdown();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f150eb68d7ee9dc419246c43f862ec4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: