quakeball/Assets/Scripts/Networking/Instances/Server.cs

192 lines
7.3 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NeonTea.Quakeball.Networking.Packets;
2020-08-07 20:24:43 +02:00
using NeonTea.Quakeball.Players;
2020-08-07 05:24:46 +02:00
using NeonTea.Quakeball.Interface;
using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Networking.Instances {
public class Server : NetInstance {
private NetChaperone Net;
private Dictionary<ulong, NetPlayer> Players = new Dictionary<ulong, NetPlayer>();
2020-08-08 02:35:19 +02:00
public List<NetPlayer> PlayerList { get; private set; } = new List<NetPlayer>();
private ulong PlayerIdCounter;
private NetPlayer LocalPlayer = new NetPlayer(ulong.MaxValue);
2020-08-08 02:35:19 +02:00
private byte LastPingIdent;
private float LastSentPing;
public static float PingInterval = 1;
public override void Start(string address, int port, PeerMessageListener listener) {
if (Peer.Running) {
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>();
Player obj = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
LocalPlayer.Controlled = obj;
AddPlayer(LocalPlayer);
}
public override void OnStop() {
foreach (NetPlayer p in PlayerList) {
Peer.Disconnect(p.Id);
if (p.Controlled != null && p.Id != LocalPlayer.Id) {
GameObject.Destroy(p.Controlled.gameObject);
}
}
PlayerList.Clear();
Players.Clear();
}
public override void Connected(Connection conn) {
2020-08-07 05:24:46 +02:00
Terminal.Singleton.Println($"{conn.uid} Connected");
foreach (NetPlayer p in Players.Values) {
2020-08-07 05:24:46 +02:00
if (p.Controlled == null) { // Not yet initialized, sending later.
continue;
}
SpawnPckt spawn = new SpawnPckt();
spawn.PlayerId = p.Id;
spawn.Location = p.Controlled.transform.position;
2020-08-07 04:31:49 +02:00
Peer.SendReliableLater(conn.uid, spawn);
}
NetPlayer RemotePlayer = new NetPlayer(PlayerIdCounter++);
AddPlayer(RemotePlayer);
SelfIdentPckt ident = new SelfIdentPckt();
ident.PlayerId = RemotePlayer.Id;
Peer.SendReliable(conn.uid, ident);
}
public override void Disconnected(Connection conn) {
2020-08-07 05:24:46 +02:00
Terminal.Singleton.Println($"{conn.uid} Disconnected: {conn.ClosingReason}");
if (Players.ContainsKey(conn.uid)) {
GameObject.Destroy(Players[conn.uid].Controlled.gameObject);
RemovePlayer(Players[conn.uid]);
}
}
public override void Handle(Connection conn, Packet packet) {
if (packet is SpawnPckt) {
SpawnPckt spawn = (SpawnPckt)packet;
if (Players[conn.uid].Controlled == null) {
Player obj = Net.SpawnPlayer(spawn.Location).GetComponent<Player>();
Players[conn.uid].Controlled = obj;
spawn = new SpawnPckt();
spawn.PlayerId = conn.uid;
spawn.Location = obj.transform.position;
SendReliableToAll(spawn, except: spawn.PlayerId);
}
2020-08-07 05:24:46 +02:00
} else if (packet is PlayerUpdatePckt) {
PlayerUpdatePckt updatePckt = (PlayerUpdatePckt)packet;
if (Players[conn.uid].Controlled != null) {
updatePckt.PlayerId = conn.uid;
Players[conn.uid].Controlled.ProcessUpdatePacket(updatePckt);
2020-08-07 05:24:46 +02:00
}
2020-08-07 23:57:11 +02:00
} else if (packet is PlayerSyncPacket) {
PlayerSyncPacket syncPckt = (PlayerSyncPacket)packet;
if (Players[conn.uid].Controlled != null) {
syncPckt.PlayerId = conn.uid;
if (!Players[conn.uid].Controlled.ProcessSyncPacket(syncPckt, false)) {
2020-08-08 00:21:02 +02:00
Players[conn.uid].Unsynced = true;
}
}
2020-08-08 03:21:02 +02:00
} else if (packet is PlayerActionPckt) {
PlayerActionPckt action = (PlayerActionPckt)packet;
if (Players[conn.uid].Controlled != null) {
HandleAction(conn.uid, action);
}
2020-08-08 02:35:19 +02:00
} else if (packet is PingPckt) {
PingPckt ping = (PingPckt)packet;
if (!ping.ServerReceived) {
ping.ServerReceived = true;
Peer.SendReliable(conn.uid, ping);
2020-08-08 03:44:45 +02:00
NetPlayer p = Players[conn.uid];
2020-08-08 02:35:19 +02:00
if (ping.Identifier == LastPingIdent) {
2020-08-08 03:44:45 +02:00
p.Ping = Time.time - LastSentPing;
2020-08-08 02:35:19 +02:00
} else {
2020-08-08 03:44:45 +02:00
p.Ping = PingInterval + 0.001f;
}
if (p.Controlled != null) {
p.Controlled.PingBias = p.Ping;
2020-08-08 02:35:19 +02:00
}
}
}
}
public override void Update() {
if (Time.time > LastSentPing + PingInterval) {
LastPingIdent = (byte)((LastPingIdent + 1) % 200);
PingPckt ping = new PingPckt(LastPingIdent);
SendReliableToAll(ping);
LastSentPing = Time.time;
}
}
2020-08-07 23:57:11 +02:00
private void AddPlayer(NetPlayer player) {
Players.Add(player.Id, player);
PlayerList.Add(player);
}
private void RemovePlayer(NetPlayer player) {
Players.Remove(player.Id);
PlayerList.Remove(player);
}
2020-08-08 03:21:02 +02:00
private void HandleAction(ulong uid, PlayerActionPckt action) {
switch (action.Action) {
case PlayerAction.Jump:
if (Players[uid].Controlled.Jump()) {
action.PlayerId = uid;
SendReliableToAll(action);
}
break;
}
}
public void SendReliableToAll(Packet packet, ulong except = ulong.MaxValue) {
foreach (NetPlayer p in Players.Values) {
if (p.Id == ulong.MaxValue || p.Id == except) {
continue;
}
Peer.SendReliable(p.Id, packet);
}
}
2020-08-07 05:24:46 +02:00
public void SendUnreliableToAll(Packet packet, ulong except = ulong.MaxValue) {
2020-08-07 05:24:46 +02:00
foreach (NetPlayer p in Players.Values) {
if (p.Id == ulong.MaxValue || p.Id == except) {
continue;
}
2020-08-07 05:24:46 +02:00
Peer.SendUnreliable(p.Id, packet);
}
}
public override void UpdateLocalPlayer() {
MultiplePlayerUpdatesPckt pckt = new MultiplePlayerUpdatesPckt(PlayerList);
2020-08-07 05:24:46 +02:00
SendUnreliableToAll(pckt);
}
public override void LocalPlayerAction(PlayerAction action) {
PlayerActionPckt jump = new PlayerActionPckt(action, LocalPlayer.Id);
2020-08-07 22:09:31 +02:00
SendReliableToAll(jump);
}
2020-08-07 23:57:11 +02:00
public override void SendPlayerSync() {
MultipleSyncsPckt pckt = new MultipleSyncsPckt(PlayerList);
SendUnreliableToAll(pckt);
}
}
}