Created
September 6, 2023 12:42
-
-
Save RyanGarber/97248fcfe672dcaedd54c75fe4dd4696 to your computer and use it in GitHub Desktop.
Improved Photon Realtime Transport for FishNet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NetworkTransport : Transport, IOnEventCallback, IMatchmakingCallbacks, IInRoomCallbacks | |
{ | |
public LoadBalancingClient Photon = new(); | |
public override void Initialize(NetworkManager networkManager, int transportIndex) | |
{ | |
base.Initialize(networkManager, transportIndex); | |
Photon.AddCallbackTarget(this); | |
} | |
public override string GetConnectionAddress(int connectionId) => (connectionId + 1).ToString(); | |
public override LocalConnectionState GetConnectionState(bool server) => Photon.State switch | |
{ | |
ClientState.Joining => LocalConnectionState.Starting, | |
ClientState.Joined => LocalConnectionState.Started, | |
ClientState.Leaving => LocalConnectionState.Stopping, | |
_ => LocalConnectionState.Stopped | |
}; | |
public override RemoteConnectionState GetConnectionState(int connectionId) => | |
Photon.CurrentRoom.Players[connectionId].IsInactive ? RemoteConnectionState.Stopped : RemoteConnectionState.Started; | |
public override void SendToClient(byte channelId, ArraySegment<byte> segment, int connectionId) | |
{ | |
SetChannel(ref segment, out SendOptions options, channelId); | |
Photon.OpRaiseEvent((byte)EventCode.ToClient, segment, new() { TargetActors = new[] { connectionId + 1 } }, options); | |
} | |
public override void SendToServer(byte channelId, ArraySegment<byte> segment) | |
{ | |
SetChannel(ref segment, out SendOptions options, channelId); | |
Photon.OpRaiseEvent((byte)EventCode.ToServer, segment, new() { TargetActors = new[] { Photon.CurrentRoom.MasterClientId } }, options); | |
} | |
void IOnEventCallback.OnEvent(EventData photonEvent) | |
{ | |
if (photonEvent.Code >= 200) return; | |
using (ByteArraySlice slice = photonEvent.CustomData as ByteArraySlice) | |
{ | |
ArraySegment<byte> segment = new(slice.Buffer, slice.Offset, slice.Count); | |
GetChannel(ref segment, out Channel channel); | |
if (photonEvent.Code == (byte)EventCode.ToClient) HandleClientReceivedDataArgs(new(segment, channel, Index)); | |
if (photonEvent.Code == (byte)EventCode.ToServer) HandleServerReceivedDataArgs(new(segment, channel, photonEvent.Sender - 1, Index)); | |
} | |
} | |
void IMatchmakingCallbacks.OnJoinedRoom() | |
{ | |
if (Photon.LocalPlayer.IsMasterClient) | |
{ | |
HandleServerConnectionState(new(LocalConnectionState.Started, Index)); | |
HandleRemoteConnectionState(new(RemoteConnectionState.Started, 0, Index)); | |
} | |
HandleClientConnectionState(new(LocalConnectionState.Started, Index)); | |
} | |
void IMatchmakingCallbacks.OnLeftRoom() | |
{ | |
HandleClientConnectionState(new(LocalConnectionState.Stopped, Index)); | |
if (NetworkManager.IsServer) | |
{ | |
HandleRemoteConnectionState(new(RemoteConnectionState.Stopped, 0, Index)); | |
HandleServerConnectionState(new(LocalConnectionState.Stopped, Index)); | |
} | |
} | |
void IInRoomCallbacks.OnPlayerEnteredRoom(Photon.Realtime.Player newPlayer) | |
{ | |
if (NetworkManager.IsServer) | |
{ | |
HandleRemoteConnectionState(new(RemoteConnectionState.Started, newPlayer.ActorNumber - 1, Index)); | |
} | |
} | |
void IInRoomCallbacks.OnPlayerLeftRoom(Photon.Realtime.Player otherPlayer) | |
{ | |
if (NetworkManager.IsServer) | |
{ | |
HandleRemoteConnectionState(new(RemoteConnectionState.Stopped, otherPlayer.ActorNumber - 1, Index)); | |
} | |
} | |
public override void Shutdown() | |
{ | |
} | |
public override bool StartConnection(bool server) | |
{ | |
return true; | |
} | |
public override bool StopConnection(bool server) | |
{ | |
return true; | |
} | |
public override bool StopConnection(int connectionId, bool immediately) | |
{ | |
return true; | |
} | |
public void SetChannel(ref ArraySegment<byte> segment, out SendOptions options, byte channelId) | |
{ | |
byte[] array = segment.Array; | |
if (segment.Offset + segment.Count >= array.Length) | |
{ | |
Array.Resize(ref array, array.Length + 1); | |
array[^1] = channelId; | |
} | |
else | |
{ | |
array[segment.Offset + segment.Count] = channelId; | |
} | |
segment = new ArraySegment<byte>(array, segment.Offset, segment.Count + 1); | |
options = channelId == (byte)Channel.Reliable ? SendOptions.SendReliable : SendOptions.SendUnreliable; | |
} | |
public void GetChannel(ref ArraySegment<byte> segment, out Channel channel) | |
{ | |
channel = (Channel)segment[^1]; | |
segment = new(segment.Array, segment.Offset, segment.Count - 1); | |
} | |
public override int GetMTU(byte channel) => 1200; | |
public override void IterateIncoming(bool server) { } | |
public override void IterateOutgoing(bool server) { } | |
void IMatchmakingCallbacks.OnFriendListUpdate(List<FriendInfo> friendList) { } | |
void IMatchmakingCallbacks.OnCreatedRoom() { } | |
void IMatchmakingCallbacks.OnCreateRoomFailed(short returnCode, string message) { } | |
void IMatchmakingCallbacks.OnJoinRoomFailed(short returnCode, string message) { } | |
void IMatchmakingCallbacks.OnJoinRandomFailed(short returnCode, string message) { } | |
void IInRoomCallbacks.OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { } | |
void IInRoomCallbacks.OnPlayerPropertiesUpdate(Photon.Realtime.Player targetPlayer, Hashtable changedProps) { } | |
void IInRoomCallbacks.OnMasterClientSwitched(Photon.Realtime.Player newMasterClient) { } | |
public override void HandleClientConnectionState(ClientConnectionStateArgs connectionStateArgs) => OnClientConnectionState?.Invoke(connectionStateArgs); | |
public override event Action<ClientConnectionStateArgs> OnClientConnectionState; | |
public override void HandleClientReceivedDataArgs(ClientReceivedDataArgs receivedDataArgs) => OnClientReceivedData?.Invoke(receivedDataArgs); | |
public override event Action<ClientReceivedDataArgs> OnClientReceivedData; | |
public override void HandleRemoteConnectionState(RemoteConnectionStateArgs connectionStateArgs) => OnRemoteConnectionState?.Invoke(connectionStateArgs); | |
public override event Action<RemoteConnectionStateArgs> OnRemoteConnectionState; | |
public override void HandleServerConnectionState(ServerConnectionStateArgs connectionStateArgs) => OnServerConnectionState?.Invoke(connectionStateArgs); | |
public override event Action<ServerConnectionStateArgs> OnServerConnectionState; | |
public override void HandleServerReceivedDataArgs(ServerReceivedDataArgs receivedDataArgs) => OnServerReceivedData?.Invoke(receivedDataArgs); | |
public override event Action<ServerReceivedDataArgs> OnServerReceivedData; | |
} | |
public enum EventCode | |
{ | |
ToClient, | |
ToServer | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment