2020-08-07 03:46:09 +02:00
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
2020-08-07 20:20:13 +02:00
|
|
|
|
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;
|
2020-08-07 03:46:09 +02:00
|
|
|
|
using NeonTea.Quakeball.TeaNet.Peers;
|
|
|
|
|
using NeonTea.Quakeball.TeaNet.Packets;
|
|
|
|
|
|
2020-08-07 20:20:13 +02:00
|
|
|
|
namespace NeonTea.Quakeball.Networking.Instances {
|
2020-08-07 03:46:09 +02:00
|
|
|
|
public class Server : NetInstance {
|
|
|
|
|
|
|
|
|
|
private NetChaperone Net;
|
|
|
|
|
|
2020-08-08 08:09:34 +02:00
|
|
|
|
public Dictionary<ulong, NetPlayer> Players { get; private set; } = new Dictionary<ulong, NetPlayer>();
|
2020-08-08 02:35:19 +02:00
|
|
|
|
public List<NetPlayer> PlayerList { get; private set; } = new List<NetPlayer>();
|
2020-08-07 03:46:09 +02:00
|
|
|
|
private ulong PlayerIdCounter;
|
|
|
|
|
|
2020-08-08 02:35:19 +02:00
|
|
|
|
private byte LastPingIdent;
|
|
|
|
|
private float LastSentPing;
|
|
|
|
|
public static float PingInterval = 1;
|
2020-08-07 21:07:58 +02:00
|
|
|
|
|
2020-08-08 09:08:10 +02:00
|
|
|
|
public Server() {
|
|
|
|
|
LocalPlayer = new NetPlayer(ulong.MaxValue);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-08 19:14:34 +02:00
|
|
|
|
public override void Start(string address, int port, string nick, PeerMessageListener listener) {
|
2020-08-08 03:03:08 +02:00
|
|
|
|
if (Peer.Running) {
|
2020-08-07 03:46:09 +02:00
|
|
|
|
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>();
|
|
|
|
|
|
2020-08-07 21:07:58 +02:00
|
|
|
|
Player obj = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
|
2020-08-07 03:46:09 +02:00
|
|
|
|
LocalPlayer.Controlled = obj;
|
2020-08-08 19:14:34 +02:00
|
|
|
|
LocalPlayer.Nick = nick;
|
2020-08-07 21:07:58 +02:00
|
|
|
|
AddPlayer(LocalPlayer);
|
2020-08-07 03:46:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-08-08 03:03:08 +02:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 03:46:09 +02:00
|
|
|
|
public override void Connected(Connection conn) {
|
2020-08-07 05:24:46 +02:00
|
|
|
|
Terminal.Singleton.Println($"{conn.uid} Connected");
|
2020-08-07 03:46:09 +02:00
|
|
|
|
foreach (NetPlayer p in Players.Values) {
|
2020-08-07 05:24:46 +02:00
|
|
|
|
|
2020-08-07 03:46:09 +02:00
|
|
|
|
if (p.Controlled == null) { // Not yet initialized, sending later.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-08-08 19:14:34 +02:00
|
|
|
|
NicknamePckt nick = new NicknamePckt(p.Nick, p.Id);
|
|
|
|
|
Peer.SendReliableLater(conn.uid, nick);
|
|
|
|
|
|
2020-08-08 08:50:37 +02:00
|
|
|
|
SpawnPckt spawn = new SpawnPckt(p.Controlled.transform.position, p.Id);
|
2020-08-07 04:31:49 +02:00
|
|
|
|
Peer.SendReliableLater(conn.uid, spawn);
|
2020-08-07 03:46:09 +02:00
|
|
|
|
}
|
|
|
|
|
NetPlayer RemotePlayer = new NetPlayer(PlayerIdCounter++);
|
2020-08-07 21:07:58 +02:00
|
|
|
|
AddPlayer(RemotePlayer);
|
2020-08-07 03:46:09 +02:00
|
|
|
|
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}");
|
2020-08-07 21:07:58 +02:00
|
|
|
|
if (Players.ContainsKey(conn.uid)) {
|
2020-08-08 03:03:08 +02:00
|
|
|
|
GameObject.Destroy(Players[conn.uid].Controlled.gameObject);
|
2020-08-07 21:07:58 +02:00
|
|
|
|
RemovePlayer(Players[conn.uid]);
|
|
|
|
|
}
|
2020-08-07 03:46:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Handle(Connection conn, Packet packet) {
|
2020-08-08 19:14:34 +02:00
|
|
|
|
if (packet is NicknamePckt) {
|
|
|
|
|
NicknamePckt nick = (NicknamePckt)packet;
|
|
|
|
|
Players[conn.uid].Nick = nick.Nick;
|
|
|
|
|
nick.PlayerId = conn.uid;
|
|
|
|
|
SendReliableToAll(nick);
|
|
|
|
|
} else if (packet is SpawnPckt) {
|
2020-08-07 03:46:09 +02:00
|
|
|
|
SpawnPckt spawn = (SpawnPckt)packet;
|
2020-08-08 08:50:37 +02:00
|
|
|
|
if (Players[conn.uid].Controlled == null && spawn.IsInitial) {
|
2020-08-07 21:07:58 +02:00
|
|
|
|
Player obj = Net.SpawnPlayer(spawn.Location).GetComponent<Player>();
|
2020-08-07 04:11:53 +02:00
|
|
|
|
Players[conn.uid].Controlled = obj;
|
|
|
|
|
|
2020-08-08 08:50:37 +02:00
|
|
|
|
spawn = new SpawnPckt(obj.transform.position, conn.uid);
|
2020-08-07 20:12:18 +02:00
|
|
|
|
SendReliableToAll(spawn, except: spawn.PlayerId);
|
2020-08-07 03:46:09 +02:00
|
|
|
|
}
|
2020-08-07 05:24:46 +02:00
|
|
|
|
} else if (packet is PlayerUpdatePckt) {
|
|
|
|
|
PlayerUpdatePckt updatePckt = (PlayerUpdatePckt)packet;
|
2020-08-08 15:22:46 +02:00
|
|
|
|
HandleUpdatePckt(conn.uid, updatePckt);
|
2020-08-07 23:57:11 +02:00
|
|
|
|
} else if (packet is PlayerSyncPacket) {
|
2020-08-08 00:15:33 +02:00
|
|
|
|
PlayerSyncPacket syncPckt = (PlayerSyncPacket)packet;
|
2020-08-08 03:58:02 +02:00
|
|
|
|
HandleSyncPckt(conn.uid, syncPckt);
|
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-08 19:37:53 +02:00
|
|
|
|
|
|
|
|
|
PingListPckt pinglist = new PingListPckt(PlayerList);
|
|
|
|
|
SendReliableToAll(pinglist);
|
2020-08-07 03:46:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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 15:22:46 +02:00
|
|
|
|
private void HandleUpdatePckt(ulong uid, PlayerUpdatePckt pckt) {
|
|
|
|
|
if (Players[uid].Controlled != null && !Players[uid].Controlled.IsDead) {
|
|
|
|
|
pckt.PlayerId = uid;
|
|
|
|
|
Players[uid].Controlled.ProcessUpdatePacket(pckt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-08 03:58:02 +02:00
|
|
|
|
private void HandleSyncPckt(ulong uid, PlayerSyncPacket pckt) {
|
2020-08-08 15:22:46 +02:00
|
|
|
|
if (Players[uid].Controlled != null && !Players[uid].Controlled.IsDead) {
|
2020-08-08 03:58:02 +02:00
|
|
|
|
pckt.PlayerId = uid;
|
|
|
|
|
if (!Players[uid].Controlled.ProcessSyncPacket(pckt, false)) {
|
|
|
|
|
Players[uid].Unsynced = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2020-08-08 04:26:17 +02:00
|
|
|
|
case PlayerAction.Shoot:
|
|
|
|
|
ShootData shootData = (ShootData)action.Serializable;
|
|
|
|
|
HandleSyncPckt(uid, shootData.SyncPckt);
|
|
|
|
|
Players[uid].Controlled.Shoot();
|
|
|
|
|
|
|
|
|
|
action.PlayerId = uid;
|
|
|
|
|
NetPlayer Player = Players[uid];
|
|
|
|
|
shootData.SyncPckt = Player.Controlled.CreateSyncPacket(Player.Id, Player.Unsynced);
|
|
|
|
|
Player.Unsynced = false;
|
|
|
|
|
SendReliableToAll(action);
|
|
|
|
|
break;
|
2020-08-08 03:21:02 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 20:12:18 +02:00
|
|
|
|
public void SendReliableToAll(Packet packet, ulong except = ulong.MaxValue) {
|
2020-08-07 03:46:09 +02:00
|
|
|
|
foreach (NetPlayer p in Players.Values) {
|
2020-08-07 20:12:18 +02:00
|
|
|
|
if (p.Id == ulong.MaxValue || p.Id == except) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-08-07 03:46:09 +02:00
|
|
|
|
Peer.SendReliable(p.Id, packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-07 05:24:46 +02:00
|
|
|
|
|
2020-08-07 20:12:18 +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) {
|
2020-08-07 20:12:18 +02:00
|
|
|
|
if (p.Id == ulong.MaxValue || p.Id == except) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-08-07 05:24:46 +02:00
|
|
|
|
Peer.SendUnreliable(p.Id, packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 21:07:58 +02:00
|
|
|
|
public override void UpdateLocalPlayer() {
|
|
|
|
|
MultiplePlayerUpdatesPckt pckt = new MultiplePlayerUpdatesPckt(PlayerList);
|
2020-08-07 05:24:46 +02:00
|
|
|
|
SendUnreliableToAll(pckt);
|
|
|
|
|
}
|
2020-08-07 21:07:58 +02:00
|
|
|
|
|
2020-08-08 04:26:17 +02:00
|
|
|
|
public override void LocalPlayerAction(PlayerAction action, Serializable serializable = null) {
|
|
|
|
|
PlayerActionPckt actionPckt = new PlayerActionPckt(action, serializable, LocalPlayer.Id);
|
|
|
|
|
SendReliableToAll(actionPckt);
|
2020-08-07 22:09:31 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 23:57:11 +02:00
|
|
|
|
public override void SendPlayerSync() {
|
|
|
|
|
MultipleSyncsPckt pckt = new MultipleSyncsPckt(PlayerList);
|
|
|
|
|
SendUnreliableToAll(pckt);
|
2020-08-07 21:07:58 +02:00
|
|
|
|
}
|
2020-08-08 06:00:17 +02:00
|
|
|
|
|
2020-08-08 09:08:10 +02:00
|
|
|
|
public void SendHit(ulong source, ulong target) {
|
|
|
|
|
HitPckt hit = new HitPckt(source, target);
|
2020-08-08 06:00:17 +02:00
|
|
|
|
SendReliableToAll(hit);
|
|
|
|
|
}
|
2020-08-08 08:50:37 +02:00
|
|
|
|
|
2020-08-08 14:37:55 +02:00
|
|
|
|
public void HandlePlayerDeath(ulong deadid, ulong killerid) {
|
|
|
|
|
Players[deadid].Controlled.Dead(killerid);
|
|
|
|
|
DeadPckt dead = new DeadPckt(deadid, killerid);
|
|
|
|
|
SendReliableToAll(dead);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void HandlePlayerRespawn(ulong uid) {
|
2020-08-08 08:50:37 +02:00
|
|
|
|
Vector3 point = GameObject.FindGameObjectWithTag("Respawn").transform.position;
|
2020-08-08 14:37:55 +02:00
|
|
|
|
Players[uid].Controlled.Respawn(point);
|
2020-08-08 08:50:37 +02:00
|
|
|
|
SpawnPckt spawn = new SpawnPckt(point, uid, false);
|
|
|
|
|
SendReliableToAll(spawn);
|
2020-08-08 14:37:55 +02:00
|
|
|
|
|
2020-08-08 08:50:37 +02:00
|
|
|
|
}
|
2020-08-07 03:46:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|