Add connecting, spawning, networking, etc. beginning stuff

This commit is contained in:
Sofia 2020-08-07 04:46:09 +03:00
parent 267cbf6fd9
commit 9daa855f81
23 changed files with 436 additions and 182 deletions

View File

@ -12,7 +12,7 @@ GameObject:
- component: {fileID: 8631085319058959107} - component: {fileID: 8631085319058959107}
m_Layer: 0 m_Layer: 0
m_Name: NetChaperone m_Name: NetChaperone
m_TagString: Untagged m_TagString: Net
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
@ -43,3 +43,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 74110215548fa9145b867baf649d14b0, type: 3} m_Script: {fileID: 11500000, guid: 74110215548fa9145b867baf649d14b0, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
SpawnedRemotePlayer: {fileID: 6246660765983498204, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}

View File

@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1 m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0} m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0} m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.17393494, g: 0.2174847, b: 0.299652, a: 1} m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0 m_UseRadianceAmbientProbe: 0
--- !u!157 &3 --- !u!157 &3
LightmapSettings: LightmapSettings:
@ -1499,7 +1499,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142122 m_Name: pb_Mesh165724
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -3217,24 +3217,13 @@ Transform:
m_Father: {fileID: 524351210} m_Father: {fileID: 524351210}
m_RootOrder: 7 m_RootOrder: 7
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
--- !u!114 &100871694 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 2280554230953742630, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
m_PrefabInstance: {fileID: 733776679}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f10708676bd58ed419f4c9ab7caeec69, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!43 &123497149 --- !u!43 &123497149
Mesh: Mesh:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142062 m_Name: pb_Mesh165602
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -3934,7 +3923,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142202 m_Name: pb_Mesh165832
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -4603,7 +4592,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh141906 m_Name: pb_Mesh165378
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -5988,7 +5977,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142172 m_Name: pb_Mesh165802
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -7770,63 +7759,6 @@ Transform:
m_Father: {fileID: 524351210} m_Father: {fileID: 524351210}
m_RootOrder: 3 m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &733776679
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalPosition.x
value: -2.525249
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalPosition.z
value: 2.4943764
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_RootOrder
value: 9
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498179, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6246660765983498204, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
propertyPath: m_Name
value: RemotePlayer
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 0fd59d93bc0809e4c8bca733a842cb6f, type: 3}
--- !u!1 &797735189 --- !u!1 &797735189
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -7989,7 +7921,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142268 m_Name: pb_Mesh165944
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -8179,6 +8111,17 @@ Transform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &876278657 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 8526795833546299750, guid: e3d975a8d1b28eb4b9f646262c56653d, type: 3}
m_PrefabInstance: {fileID: 962083752}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f6e08271c272323469510daa22c35599, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &913024989 --- !u!1 &913024989
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -8701,7 +8644,7 @@ PrefabInstance:
- target: {fileID: 8526795833546299750, guid: e3d975a8d1b28eb4b9f646262c56653d, type: 3} - target: {fileID: 8526795833546299750, guid: e3d975a8d1b28eb4b9f646262c56653d, type: 3}
propertyPath: TestingPlayer propertyPath: TestingPlayer
value: value:
objectReference: {fileID: 100871694} objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: e3d975a8d1b28eb4b9f646262c56653d, type: 3} m_SourcePrefab: {fileID: 100100000, guid: e3d975a8d1b28eb4b9f646262c56653d, type: 3}
--- !u!1 &972260615 --- !u!1 &972260615
@ -11436,7 +11379,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh141866 m_Name: pb_Mesh165308
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -12942,7 +12885,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142104 m_Name: pb_Mesh165704
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -16706,7 +16649,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh141892 m_Name: pb_Mesh165354
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -17160,7 +17103,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142150 m_Name: pb_Mesh165762
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -17628,7 +17571,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142226 m_Name: pb_Mesh165874
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -17884,7 +17827,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142238 m_Name: pb_Mesh165886
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -18222,7 +18165,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh141846 m_Name: pb_Mesh165282
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -18386,7 +18329,7 @@ Mesh:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: pb_Mesh142012 m_Name: pb_Mesh165542
serializedVersion: 10 serializedVersion: 10
m_SubMeshes: m_SubMeshes:
- serializedVersion: 2 - serializedVersion: 2
@ -18754,7 +18697,7 @@ PrefabInstance:
- target: {fileID: 2654296452177192280, guid: 68b0b7d9f7cd54f4a9f3382b9452d809, type: 3} - target: {fileID: 2654296452177192280, guid: 68b0b7d9f7cd54f4a9f3382b9452d809, type: 3}
propertyPath: Player propertyPath: Player
value: value:
objectReference: {fileID: 0} objectReference: {fileID: 876278657}
- target: {fileID: 5023538681700148317, guid: 68b0b7d9f7cd54f4a9f3382b9452d809, type: 3} - target: {fileID: 5023538681700148317, guid: 68b0b7d9f7cd54f4a9f3382b9452d809, type: 3}
propertyPath: m_AnchorMax.x propertyPath: m_AnchorMax.x
value: 0 value: 0

View File

@ -31,15 +31,15 @@ namespace NeonTea.Quakeball.Net {
Net.Singleton.StartClient(addr, Int32.Parse(port), this); Net.Singleton.StartClient(addr, Int32.Parse(port), this);
}); });
Stop.onClick.AddListener(() => { Stop.onClick.AddListener(() => {
Net.Singleton.Stop(); Net.Quit();
}); });
Send.onClick.AddListener(() => { Send.onClick.AddListener(() => {
if (Net.Singleton.Peer != null) { if (Net.Singleton.Instance.Peer != null) {
foreach (ulong uid in Net.Singleton.Connections) { foreach (ulong uid in Net.Singleton.Instance.Connections) {
HelloPckt pckt = new HelloPckt(); HelloPckt pckt = new HelloPckt();
pckt.Text = MessageField.text; pckt.Text = MessageField.text;
Net.Singleton.Peer.SendReliableLater(uid, pckt); Net.Singleton.Instance.Peer.SendReliableLater(uid, pckt);
Net.Singleton.Peer.SendReliable(uid, pckt); Net.Singleton.Instance.Peer.SendReliable(uid, pckt);
} }
} }
}); });

View File

@ -0,0 +1,41 @@
using System.Collections.Generic;
using System;
using UnityEngine;
using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.TeaNet.Packets;
using NeonTea.Quakeball.Net.Packets;
using NeonTea.Quakeball.Net.Instances;
namespace NeonTea.Quakeball.Net {
public class GameProtocol : Protocol {
public override byte Identifier => 0x7A;
public override string Version => "0.0.1";
private NetInstance Instance;
public GameProtocol(NetInstance instance) {
Instance = instance;
RegisterPacket(typeof(HelloPckt));
RegisterPacket(typeof(SpawnPckt));
RegisterPacket(typeof(SelfIdentPckt));
}
public override void ConnectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus, Connection conn) {
if (conn.IsReady() && !Instance.Connections.Contains(conn.uid)) {
Instance.Connected(conn);
} else if (conn.IsDisconnected()) {
Instance.Disconnected(conn);
}
}
public override void Receive(Connection conn, Packet packet) {
Instance.Handle(conn, packet);
}
public override void Timeout(Connection conn) {
Instance.Disconnected(conn);
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b7082cebeb9d3441babb6ce8d99628c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NeonTea.Quakeball.Net.Packets;
using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Instances {
public class Client : NetInstance {
private NetChaperone Net;
private Connection Server;
private Dictionary<ulong, NetPlayer> Players = new Dictionary<ulong, NetPlayer>();
private NetPlayer LocalPlayer;
public override void Start(string address, int port, PeerMessageListener listener) {
if (Peer != null) {
return;
}
Peer = new Peer(Fingerprint);
Peer.MessageListener = listener;
Peer.Start(0);
byte ident = Peer.RegisterProtocol(new GameProtocol(this));
Peer.Connect(address, port, ident);
Net = GameObject.FindGameObjectWithTag("Net").GetComponent<NetChaperone>();
LocalPlayer = new NetPlayer(ulong.MaxValue - 1);
LocalPlayer.Controlled = GameObject.FindGameObjectWithTag("Player");
}
public override void Connected(Connection conn) {
if (Server == null) {
Server = conn;
} else {
Peer.Disconnect(conn.uid);
}
}
public override void Disconnected(Connection conn) {
if (Server == conn) {
Server = null;
}
}
public override void Handle(Connection conn, Packet packet) {
if (packet is SelfIdentPckt) {
SelfIdentPckt ident = (SelfIdentPckt)packet;
LocalPlayer.Id = ident.PlayerId;
Players.Add(LocalPlayer.Id, LocalPlayer);
SpawnPckt spawn = new SpawnPckt();
spawn.Location = LocalPlayer.Controlled.transform.position;
Peer.SendReliable(Server.uid, spawn);
} else if (packet is SpawnPckt) {
SpawnPckt spawn = (SpawnPckt)packet;
if (spawn.PlayerId == LocalPlayer.Id) {
return; // Ignore, it's their own.
}
Net.SpawnPlayer(spawn.PlayerId, spawn.Location);
}
}
public override void PlayerSpawned(ulong uid, GameObject obj) {
NetPlayer player = new NetPlayer(uid);
player.Controlled = obj;
}
}
}

View File

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

View File

@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Instances {
public abstract class NetInstance {
protected static byte[] Fingerprint = new byte[] { 0xFF, 0xF7 };
public Peer Peer;
public List<ulong> Connections = new List<ulong>();
public abstract void Start(string address, int port, PeerMessageListener listener);
public abstract void Connected(Connection conn);
public abstract void Disconnected(Connection conn);
public abstract void Handle(Connection conn, Packet packet);
public abstract void PlayerSpawned(ulong uid, GameObject obj);
public void Stop() {
if (Peer != null) {
Peer.Stop();
Peer.MessageListener.Message("Stopping");
Peer = null;
}
}
}
}

View File

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

View File

@ -0,0 +1,79 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NeonTea.Quakeball.Net.Packets;
using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Instances {
public class Server : NetInstance {
private NetChaperone Net;
private Dictionary<ulong, NetPlayer> Players = new Dictionary<ulong, NetPlayer>();
private ulong PlayerIdCounter;
private NetPlayer LocalPlayer = new NetPlayer(ulong.MaxValue);
public override void Start(string address, int port, PeerMessageListener listener) {
if (Peer != null) {
return;
}
Peer = new Peer(Fingerprint);
Peer.MessageListener = listener;
Peer.Start(port);
Peer.RegisterProtocol(new GameProtocol(this));
Peer.StartListen(address, port);
Net = GameObject.FindGameObjectWithTag("Net").GetComponent<NetChaperone>();
GameObject obj = GameObject.FindGameObjectWithTag("Player");
LocalPlayer.Controlled = obj;
Players.Add(LocalPlayer.Id, LocalPlayer);
}
public override void Connected(Connection conn) {
foreach (NetPlayer p in Players.Values) {
if (p.Controlled == null) { // Not yet initialized, sending later.
continue;
}
SpawnPckt spawn = new SpawnPckt();
spawn.PlayerId = p.Id;
spawn.Location = p.Controlled.transform.position;
Peer.SendReliable(conn.uid, spawn);
}
NetPlayer RemotePlayer = new NetPlayer(PlayerIdCounter++);
Players.Add(RemotePlayer.Id, RemotePlayer);
SelfIdentPckt ident = new SelfIdentPckt();
ident.PlayerId = RemotePlayer.Id;
Peer.SendReliable(conn.uid, ident);
}
public override void Disconnected(Connection conn) {
}
public override void Handle(Connection conn, Packet packet) {
if (packet is SpawnPckt) {
SpawnPckt spawn = (SpawnPckt)packet;
if (Players[conn.uid].Controlled == null) {
Net.SpawnPlayer(conn.uid, spawn.Location);
}
}
}
public void SendReliableToAll(Packet packet) {
foreach (NetPlayer p in Players.Values) {
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);
}
}
}

View File

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

View File

@ -1,4 +1,5 @@
using UnityEngine; using UnityEngine;
using NeonTea.Quakeball.Net.Instances;
using NeonTea.Quakeball.TeaNet.Peers; using NeonTea.Quakeball.TeaNet.Peers;
using System.Collections.Generic; using System.Collections.Generic;
@ -6,48 +7,21 @@ namespace NeonTea.Quakeball.Net {
public class Net { public class Net {
public static Net Singleton = new Net(); public static Net Singleton = new Net();
private static byte[] FP = new byte[] { 0xFF, 0xF7 };
public Peer Peer; public NetInstance Instance;
public List<ulong> Connections = new List<ulong>();
public bool IsServer = false;
public void StartClient(string address, int port, PeerMessageListener listener) { public void StartClient(string address, int port, PeerMessageListener listener) {
if (Peer != null) { Instance = new Client();
Debug.Log("Can not start multiple endpoints at once! Use Server if multiple connections are required."); Instance.Start(address, port, listener);
return;
}
Peer = new Peer(FP);
Peer.MessageListener = listener;
Peer.Start(0);
byte ident = Peer.RegisterProtocol(new TestProtocol());
Peer.Connect(address, port, ident);
} }
public void StartServer(string address, int port, PeerMessageListener listener) { public void StartServer(string address, int port, PeerMessageListener listener) {
if (Peer != null) { Instance = new Server();
Debug.Log("Can not start multiple endpoints at once! Use Server if multiple connections are required."); Instance.Start(address, port, listener);
return;
}
IsServer = true;
Peer = new Peer(FP);
Peer.MessageListener = listener;
Peer.Start(port);
Peer.RegisterProtocol(new TestProtocol());
Peer.StartListen(address, port);
} }
public void Stop() { public static void Quit() {
if (Peer != null) { Singleton.Instance.Stop();
Peer.Stop();
Peer.MessageListener.Message("Stopping");
Peer = null;
}
}
static void Quit() {
Singleton.Stop();
} }
[RuntimeInitializeOnLoadMethod] [RuntimeInitializeOnLoadMethod]

View File

@ -7,10 +7,26 @@ using NeonTea.Quakeball.TeaNet.Peers;
namespace NeonTea.Quakeball.Net { namespace NeonTea.Quakeball.Net {
public class NetChaperone : MonoBehaviour, PeerMessageListener { public class NetChaperone : MonoBehaviour, PeerMessageListener {
public GameObject SpawnedRemotePlayer;
private Terminal Terminal; private Terminal Terminal;
private Queue<string> MessageQueue = new Queue<string>(); private Queue<string> MessageQueue = new Queue<string>();
private Queue<SpawnInfo> SpawnQueue = new Queue<SpawnInfo>();
class SpawnInfo {
public ulong id;
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() {
if (Terminal.Singleton != null) { if (Terminal.Singleton != null) {
Terminal = Terminal.Singleton; Terminal = Terminal.Singleton;
@ -24,6 +40,12 @@ namespace NeonTea.Quakeball.Net {
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);
}
} }
} }

View File

@ -0,0 +1,13 @@
using UnityEngine;
namespace NeonTea.Quakeball.Net {
public class NetPlayer {
public ulong Id;
public GameObject Controlled;
public NetPlayer(ulong id, GameObject obj = null) {
Id = id;
Controlled = obj;
}
}
}

View File

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

View File

@ -0,0 +1,39 @@
using UnityEngine;
using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Packets {
public class SpawnPckt : Packet {
public ulong PlayerId;
public Vector3 Location;
public override void Read(ByteBuffer buffer) {
float x = buffer.ReadFloat();
float y = buffer.ReadFloat();
float z = buffer.ReadFloat();
Location = new Vector3(x, y, z);
PlayerId = buffer.ReadULong();
}
public override void Write(ByteBuffer buffer) {
buffer.Write(Location.x);
buffer.Write(Location.y);
buffer.Write(Location.z);
buffer.Write(PlayerId);
}
}
public class SelfIdentPckt : Packet {
public ulong PlayerId;
public override void Read(ByteBuffer buffer) {
PlayerId = buffer.ReadULong();
}
public override void Write(ByteBuffer buffer) {
buffer.Write(PlayerId);
}
}
}

View File

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

View File

@ -1,42 +0,0 @@
using System.Collections.Generic;
using System;
using UnityEngine;
using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.TeaNet.Packets;
using NeonTea.Quakeball.Net.Packets;
namespace NeonTea.Quakeball.Net {
public class TestProtocol : Protocol {
public override byte Identifier => 0x7A;
public override string Version => "0.0.1";
public TestProtocol() {
RegisterPacket(typeof(HelloPckt));
}
public override void ConnectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus, Connection conn) {
Peer.MessageListener.Message($"Connection Status Changed into {newStatus.ToString()} for {conn.Endpoint}");
if (conn.IsReady() && !Net.Singleton.Connections.Contains(conn.uid)) {
Net.Singleton.Connections.Add(conn.uid);
} else if (newStatus == ConnectionStatus.Closed) {
Net.Singleton.Peer.MessageListener.Message($"Conncection closed: {conn.ClosingReason}");
}
if (conn.IsDisconnected()) {
Net.Singleton.Connections.Remove(conn.uid);
}
}
public override void Receive(Connection conn, Packet packet) {
if (packet is HelloPckt) {
HelloPckt Hello = (HelloPckt)packet;
Peer.MessageListener.Message($"Received HelloPckt: {Hello.Text}");
}
}
public override void Timeout(Connection conn) {
Peer.MessageListener.Message($"Closed {conn.Endpoint} for Timeout");
}
}
}

View File

@ -2,9 +2,9 @@ namespace NeonTea.Quakeball.TeaNet.Packets {
/// <summary>A packet for sending stuff over to connections.</summary> /// <summary>A packet for sending stuff over to connections.</summary>
public abstract class Packet { public abstract class Packet {
/// <summary>Packet meta-information: Is this packet reliable. Set just before sending.</summary> /// <summary>Packet meta-information: Is this packet reliable. Set just before sending.</summary>
public bool Reliable = true; public bool PacketIsReliable = true;
/// <summary>Packet meta-information: Id of this packet. Set just before sending.</summary> /// <summary>Packet meta-information: Id of this packet. Set just before sending.</summary>
public int Id; public int PacketId;
/// <summary>Write any relevant information about this packet into the buffer.</summary> /// <summary>Write any relevant information about this packet into the buffer.</summary>
public abstract void Write(ByteBuffer buffer); public abstract void Write(ByteBuffer buffer);
@ -13,14 +13,14 @@ namespace NeonTea.Quakeball.TeaNet.Packets {
/// <summary>Reads packet meta-information from the buffer.</summary> /// <summary>Reads packet meta-information from the buffer.</summary>
public void ReadMeta(ByteBuffer buffer) { public void ReadMeta(ByteBuffer buffer) {
Id = buffer.ReadInt(); PacketId = buffer.ReadInt();
Reliable = buffer.ReadBool(); PacketIsReliable = buffer.ReadBool();
} }
/// <summary>Writes packet meta-information to the buffer.</summary> /// <summary>Writes packet meta-information to the buffer.</summary>
public void WriteMeta(ByteBuffer buffer) { public void WriteMeta(ByteBuffer buffer) {
buffer.Write(Id); buffer.Write(PacketId);
buffer.Write(Reliable); buffer.Write(PacketIsReliable);
} }
/// <summary>Make a shallow copy for this packet, copying any primitives but retaining any references to instances.</summary> /// <summary>Make a shallow copy for this packet, copying any primitives but retaining any references to instances.</summary>
@ -45,6 +45,8 @@ namespace NeonTea.Quakeball.TeaNet.Packets {
public enum ClosingReason { public enum ClosingReason {
Unknown = 0, Unknown = 0,
IncorrectVersion = 1, IncorrectVersion = 1,
Timeout = 2,
Manual = 3,
} }
} }

View File

@ -57,13 +57,21 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
return conn; return conn;
} }
/// <summary>Soft-closes the connection with the given uid, meaning it will wait for them to acknowledge the closing</summary>
public void CloseConnection(ulong uid, ClosingReason reason) {
if (Connections.ContainsKey(uid)) {
Connections[uid].ClosingReason = reason;
Connections[uid].Status = ConnectionStatus.Rejected;
}
}
/// <summary>Add a reliable packet to the packet queue, to be sent on the next update, or when SendPacketQueue is called.</summary> /// <summary>Add a reliable packet to the packet queue, to be sent on the next update, or when SendPacketQueue is called.</summary>
public void AddPacketToQueue(ulong uid, Packet p) { public void AddPacketToQueue(ulong uid, Packet p) {
if (!Connections.ContainsKey(uid)) { if (!Connections.ContainsKey(uid)) {
return; return;
} }
p = p.ShallowCopy(); p = p.ShallowCopy();
p.Id = Connections[uid].Internal.ReliablePacketIDCounter++; p.PacketId = Connections[uid].Internal.ReliablePacketIDCounter++;
PacketQueue[uid].Add(p); PacketQueue[uid].Add(p);
} }
@ -92,8 +100,8 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
} }
Connection conn = Connections[uid]; Connection conn = Connections[uid];
p = p.ShallowCopy(); p = p.ShallowCopy();
p.Id = conn.Internal.UnreliablePacketIDCounter++; p.PacketId = conn.Internal.UnreliablePacketIDCounter++;
p.Reliable = false; p.PacketIsReliable = false;
Protocol protocol = Peer.GetProtocol(conn.Internal.AssignedProtocol); Protocol protocol = Peer.GetProtocol(conn.Internal.AssignedProtocol);
if (protocol != null && conn.IsReady()) { if (protocol != null && conn.IsReady()) {
ByteBuffer buffer = protocol.BuildMessage(conn); ByteBuffer buffer = protocol.BuildMessage(conn);
@ -179,23 +187,25 @@ 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); protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
} else {
break; // They're cheating! No cheating!
} }
conn.Internal.LatestOutwardReliable = buffer.ReadInt(); conn.Internal.LatestOutwardReliable = buffer.ReadInt();
List<Packet> list = PacketQueue[conn.uid]; List<Packet> list = PacketQueue[conn.uid];
list.RemoveAll(p => p.Id <= conn.Internal.LatestOutwardReliable); list.RemoveAll(p => p.PacketId <= conn.Internal.LatestOutwardReliable);
PacketQueue[conn.uid] = list; PacketQueue[conn.uid] = list;
int PacketAmount = buffer.ReadInt(); int PacketAmount = buffer.ReadInt();
for (int i = 0; i < PacketAmount; i++) { for (int i = 0; i < PacketAmount; i++) {
Packet p = buffer.ReadPacket(protocol); Packet p = buffer.ReadPacket(protocol);
if (p.Reliable) { if (p.PacketIsReliable) {
if (p.Id > conn.Internal.LatestInwardReliable) { if (p.PacketId > conn.Internal.LatestInwardReliable) {
conn.Internal.LatestInwardReliable = p.Id; conn.Internal.LatestInwardReliable = p.PacketId;
protocol.Receive(conn, p); protocol.Receive(conn, p);
} }
} else if (p.Id > conn.Internal.LatestInwardUnreliable) { } else if (p.PacketId > conn.Internal.LatestInwardUnreliable) {
conn.Internal.LatestInwardUnreliable = p.Id; conn.Internal.LatestInwardUnreliable = p.PacketId;
protocol.Receive(conn, p); protocol.Receive(conn, p);
} }
} }
@ -230,6 +240,7 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
|| conn.Status == ConnectionStatus.Lost) { || conn.Status == ConnectionStatus.Lost) {
Protocol protocol = Peer.GetProtocol(conn.Internal.AssignedProtocol); Protocol protocol = Peer.GetProtocol(conn.Internal.AssignedProtocol);
if (protocol != null) { if (protocol != null) {
conn.ClosingReason = ClosingReason.Timeout;
protocol.Timeout(conn); protocol.Timeout(conn);
} }
} }

View File

@ -88,6 +88,11 @@ namespace NeonTea.Quakeball.TeaNet.Peers {
MessageListener.Message($"Connecting to {endpoint}"); MessageListener.Message($"Connecting to {endpoint}");
} }
/// <summary>Soft-disconnects the connection with the given uid, meaning it will wait until they acknowledge, before timing out.abstract</summary>
public void Disconnect(ulong uid) {
ConnectionManager.CloseConnection(uid, ClosingReason.Manual);
}
/// <summary>Send a reliable packet, meaning it will reliably be delivered.</summary> /// <summary>Send a reliable packet, meaning it will reliably be delivered.</summary>
public void SendReliable(ulong uid, Packet packet) { public void SendReliable(ulong uid, Packet packet) {
ConnectionManager.AddPacketToQueue(uid, packet); ConnectionManager.AddPacketToQueue(uid, packet);

View File

@ -6,6 +6,7 @@ TagManager:
tags: tags:
- Terminal - Terminal
- RemotePlayer - RemotePlayer
- Net
layers: layers:
- Default - Default
- TransparentFX - TransparentFX