Make Protocol only be called on mainthread
This commit is contained in:
parent
9daa855f81
commit
1d8e027558
@ -60,13 +60,9 @@ namespace NeonTea.Quakeball.Net.Instances {
|
|||||||
if (spawn.PlayerId == LocalPlayer.Id) {
|
if (spawn.PlayerId == LocalPlayer.Id) {
|
||||||
return; // Ignore, it's their own.
|
return; // Ignore, it's their own.
|
||||||
}
|
}
|
||||||
Net.SpawnPlayer(spawn.PlayerId, spawn.Location);
|
GameObject obj = Net.SpawnPlayer(spawn.Location);
|
||||||
}
|
NetPlayer player = new NetPlayer(spawn.PlayerId, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PlayerSpawned(ulong uid, GameObject obj) {
|
|
||||||
NetPlayer player = new NetPlayer(uid);
|
|
||||||
player.Controlled = obj;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,6 @@ namespace NeonTea.Quakeball.Net.Instances {
|
|||||||
public abstract void Connected(Connection conn);
|
public abstract void Connected(Connection conn);
|
||||||
public abstract void Disconnected(Connection conn);
|
public abstract void Disconnected(Connection conn);
|
||||||
public abstract void Handle(Connection conn, Packet packet);
|
public abstract void Handle(Connection conn, Packet packet);
|
||||||
public abstract void PlayerSpawned(ulong uid, GameObject obj);
|
|
||||||
|
|
||||||
public void Stop() {
|
public void Stop() {
|
||||||
if (Peer != null) {
|
if (Peer != null) {
|
||||||
|
@ -56,7 +56,13 @@ namespace NeonTea.Quakeball.Net.Instances {
|
|||||||
if (packet is SpawnPckt) {
|
if (packet is SpawnPckt) {
|
||||||
SpawnPckt spawn = (SpawnPckt)packet;
|
SpawnPckt spawn = (SpawnPckt)packet;
|
||||||
if (Players[conn.uid].Controlled == null) {
|
if (Players[conn.uid].Controlled == null) {
|
||||||
Net.SpawnPlayer(conn.uid, spawn.Location);
|
GameObject obj = Net.SpawnPlayer(spawn.Location);
|
||||||
|
Players[conn.uid].Controlled = obj;
|
||||||
|
|
||||||
|
spawn = new SpawnPckt();
|
||||||
|
spawn.PlayerId = conn.uid;
|
||||||
|
spawn.Location = obj.transform.position;
|
||||||
|
SendReliableToAll(spawn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,14 +72,5 @@ namespace NeonTea.Quakeball.Net.Instances {
|
|||||||
Peer.SendReliable(p.Id, packet);
|
Peer.SendReliable(p.Id, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PlayerSpawned(ulong uid, GameObject obj) {
|
|
||||||
Players[uid].Controlled = obj;
|
|
||||||
|
|
||||||
SpawnPckt spawn = new SpawnPckt();
|
|
||||||
spawn.PlayerId = uid;
|
|
||||||
spawn.Location = obj.transform.position;
|
|
||||||
SendReliableToAll(spawn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using NeonTea.Quakeball.Interface;
|
using NeonTea.Quakeball.Interface;
|
||||||
|
using NeonTea.Quakeball.Net;
|
||||||
using NeonTea.Quakeball.TeaNet.Peers;
|
using NeonTea.Quakeball.TeaNet.Peers;
|
||||||
|
|
||||||
namespace NeonTea.Quakeball.Net {
|
namespace NeonTea.Quakeball.Net {
|
||||||
@ -13,18 +14,10 @@ namespace NeonTea.Quakeball.Net {
|
|||||||
|
|
||||||
private Queue<string> MessageQueue = new Queue<string>();
|
private Queue<string> MessageQueue = new Queue<string>();
|
||||||
|
|
||||||
private Queue<SpawnInfo> SpawnQueue = new Queue<SpawnInfo>();
|
public GameObject SpawnPlayer(Vector3 location) {
|
||||||
|
GameObject obj = GameObject.Instantiate(SpawnedRemotePlayer);
|
||||||
class SpawnInfo {
|
obj.transform.position = location;
|
||||||
public ulong id;
|
return obj;
|
||||||
public Vector3 location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SpawnPlayer(ulong uid, Vector3 location) {
|
|
||||||
SpawnInfo info = new SpawnInfo();
|
|
||||||
info.id = uid;
|
|
||||||
info.location = location;
|
|
||||||
SpawnQueue.Enqueue(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start() {
|
private void Start() {
|
||||||
@ -36,16 +29,11 @@ namespace NeonTea.Quakeball.Net {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Update() {
|
private void Update() {
|
||||||
|
Net.Singleton.Instance.Peer.Update();
|
||||||
if (Terminal != null && Terminal.isActiveAndEnabled) {
|
if (Terminal != null && Terminal.isActiveAndEnabled) {
|
||||||
while (MessageQueue.Count > 0) {
|
while (MessageQueue.Count > 0) {
|
||||||
Terminal.Println(MessageQueue.Dequeue());
|
Terminal.Println(MessageQueue.Dequeue());
|
||||||
}
|
}
|
||||||
while (SpawnQueue.Count > 0) {
|
|
||||||
SpawnInfo info = SpawnQueue.Dequeue();
|
|
||||||
GameObject obj = GameObject.Instantiate(SpawnedRemotePlayer);
|
|
||||||
obj.transform.position = info.location;
|
|
||||||
Net.Singleton.Instance.PlayerSpawned(info.id, obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
private Dictionary<ulong, List<Packet>> PacketQueue = new Dictionary<ulong, List<Packet>>();
|
private Dictionary<ulong, List<Packet>> PacketQueue = new Dictionary<ulong, List<Packet>>();
|
||||||
private Peer Peer;
|
private Peer Peer;
|
||||||
|
|
||||||
|
public Dictionary<ulong, Queue<ProtocolAction>> ProtocolActionQueues = new Dictionary<ulong, Queue<ProtocolAction>>();
|
||||||
|
|
||||||
private Thread UpdateThread;
|
private Thread UpdateThread;
|
||||||
|
|
||||||
public long Timeout = 8000;
|
public long Timeout = 8000;
|
||||||
@ -111,6 +113,26 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Go through queue of networking actions that have happened since last update.</summary>
|
||||||
|
public void Update() {
|
||||||
|
foreach (byte id in ProtocolActionQueues.Keys) {
|
||||||
|
Protocol protocol = Peer.GetProtocol(id);
|
||||||
|
while (ProtocolActionQueues[id].Count > 0) {
|
||||||
|
ProtocolAction action = ProtocolActionQueues[id].Dequeue();
|
||||||
|
if (action is ReceiveAction) {
|
||||||
|
ReceiveAction receive = (ReceiveAction)action;
|
||||||
|
protocol.Receive(receive.Connection, receive.Packet);
|
||||||
|
} else if (action is ConnectionChangedAction) {
|
||||||
|
ConnectionChangedAction changed = (ConnectionChangedAction)action;
|
||||||
|
protocol.ConnectionStatusChanged(changed.OldStatus, changed.NewStatus, changed.Connection);
|
||||||
|
} else if (action is TimeoutAction) {
|
||||||
|
TimeoutAction changed = (TimeoutAction)action;
|
||||||
|
protocol.Timeout(changed.Connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void AddConnection(Connection conn) {
|
private void AddConnection(Connection conn) {
|
||||||
conn.uid = ConnectionCounter++;
|
conn.uid = ConnectionCounter++;
|
||||||
Connections.Add(conn.uid, conn);
|
Connections.Add(conn.uid, conn);
|
||||||
@ -160,7 +182,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
conn.Status = ConnectionStatus.Ready;
|
conn.Status = ConnectionStatus.Ready;
|
||||||
}
|
}
|
||||||
if (protocol != null) {
|
if (protocol != null) {
|
||||||
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
|
ProtocolActionQueues[protocol.Identifier].Enqueue(new ConnectionChangedAction(oldStatus, conn.Status, conn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -168,7 +190,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
conn.Status = ConnectionStatus.Closed;
|
conn.Status = ConnectionStatus.Closed;
|
||||||
conn.ClosingReason = buffer.ReadClosingReason();
|
conn.ClosingReason = buffer.ReadClosingReason();
|
||||||
if (protocol != null) {
|
if (protocol != null) {
|
||||||
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
|
ProtocolActionQueues[protocol.Identifier].Enqueue(new ConnectionChangedAction(oldStatus, conn.Status, conn));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketStage.Closed:
|
case PacketStage.Closed:
|
||||||
@ -177,7 +199,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
}
|
}
|
||||||
conn.Status = ConnectionStatus.Stopped;
|
conn.Status = ConnectionStatus.Stopped;
|
||||||
if (protocol != null) {
|
if (protocol != null) {
|
||||||
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
|
ProtocolActionQueues[protocol.Identifier].Enqueue(new ConnectionChangedAction(oldStatus, conn.Status, conn));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketStage.Ready:
|
case PacketStage.Ready:
|
||||||
@ -186,7 +208,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
}
|
}
|
||||||
if (oldStatus == ConnectionStatus.Establishing) { // Update connection status
|
if (oldStatus == ConnectionStatus.Establishing) { // Update connection status
|
||||||
conn.Status = ConnectionStatus.Ready;
|
conn.Status = ConnectionStatus.Ready;
|
||||||
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
|
ProtocolActionQueues[protocol.Identifier].Enqueue(new ConnectionChangedAction(oldStatus, conn.Status, conn));
|
||||||
} else {
|
} else {
|
||||||
break; // They're cheating! No cheating!
|
break; // They're cheating! No cheating!
|
||||||
}
|
}
|
||||||
@ -202,11 +224,11 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
if (p.PacketIsReliable) {
|
if (p.PacketIsReliable) {
|
||||||
if (p.PacketId > conn.Internal.LatestInwardReliable) {
|
if (p.PacketId > conn.Internal.LatestInwardReliable) {
|
||||||
conn.Internal.LatestInwardReliable = p.PacketId;
|
conn.Internal.LatestInwardReliable = p.PacketId;
|
||||||
protocol.Receive(conn, p);
|
ProtocolActionQueues[protocol.Identifier].Enqueue(new ReceiveAction(conn, p));
|
||||||
}
|
}
|
||||||
} else if (p.PacketId > conn.Internal.LatestInwardUnreliable) {
|
} else if (p.PacketId > conn.Internal.LatestInwardUnreliable) {
|
||||||
conn.Internal.LatestInwardUnreliable = p.PacketId;
|
conn.Internal.LatestInwardUnreliable = p.PacketId;
|
||||||
protocol.Receive(conn, p);
|
ProtocolActionQueues[protocol.Identifier].Enqueue(new ReceiveAction(conn, p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -241,7 +263,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
Protocol protocol = Peer.GetProtocol(conn.Internal.AssignedProtocol);
|
Protocol protocol = Peer.GetProtocol(conn.Internal.AssignedProtocol);
|
||||||
if (protocol != null) {
|
if (protocol != null) {
|
||||||
conn.ClosingReason = ClosingReason.Timeout;
|
conn.ClosingReason = ClosingReason.Timeout;
|
||||||
protocol.Timeout(conn);
|
ProtocolActionQueues[conn.Internal.AssignedProtocol].Enqueue(new TimeoutAction(conn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,4 +274,36 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class ProtocolAction { };
|
||||||
|
|
||||||
|
class ReceiveAction : ProtocolAction {
|
||||||
|
public Connection Connection;
|
||||||
|
public Packet Packet;
|
||||||
|
|
||||||
|
public ReceiveAction(Connection connection, Packet packet) {
|
||||||
|
Connection = connection;
|
||||||
|
Packet = packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConnectionChangedAction : ProtocolAction {
|
||||||
|
public ConnectionStatus OldStatus;
|
||||||
|
public ConnectionStatus NewStatus;
|
||||||
|
public Connection Connection;
|
||||||
|
|
||||||
|
public ConnectionChangedAction(ConnectionStatus old, ConnectionStatus newstatus, Connection connection) {
|
||||||
|
Connection = connection;
|
||||||
|
OldStatus = old;
|
||||||
|
NewStatus = newstatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeoutAction : ProtocolAction {
|
||||||
|
public Connection Connection;
|
||||||
|
|
||||||
|
public TimeoutAction(Connection connection) {
|
||||||
|
Connection = connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ using System.Net.Sockets;
|
|||||||
using NeonTea.Quakeball.TeaNet.Packets;
|
using NeonTea.Quakeball.TeaNet.Packets;
|
||||||
|
|
||||||
namespace NeonTea.Quakeball.TeaNet.Peers {
|
namespace NeonTea.Quakeball.TeaNet.Peers {
|
||||||
/// <summary>Main class for networking. Remember to register a protocol before using.</summary>
|
/// <summary>Main class for networking. Remember to register a protocol before using. Remember to call Update from a gameobject!</summary>
|
||||||
public class Peer : PeerMessageListener {
|
public class Peer : PeerMessageListener {
|
||||||
/// <summary>Underlying UdpClient. Do not touch unless you know what you are doing.</summary>
|
/// <summary>Underlying UdpClient. Do not touch unless you know what you are doing.</summary>
|
||||||
public UdpClient UdpClient { get; private set; }
|
public UdpClient UdpClient { get; private set; }
|
||||||
@ -121,6 +121,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
RegisteredProtocols.Add(ident, protocol);
|
RegisteredProtocols.Add(ident, protocol);
|
||||||
|
ConnectionManager.ProtocolActionQueues.Add(ident, new Queue<ProtocolAction>());
|
||||||
protocol.Peer = this;
|
protocol.Peer = this;
|
||||||
return ident;
|
return ident;
|
||||||
}
|
}
|
||||||
@ -133,6 +134,11 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Shorthand for Peer.ConnectionManager.Update(): Handles network stuff that was received since last update.</summary>
|
||||||
|
public void Update() {
|
||||||
|
ConnectionManager.Update();
|
||||||
|
}
|
||||||
|
|
||||||
public void Message(string msg) { }
|
public void Message(string msg) { }
|
||||||
public void Err(string msg) { }
|
public void Err(string msg) { }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user