mirror of
https://github.com/MrOkiDoki/BattleBit-Community-Server-API.git
synced 2025-01-09 11:17:30 -03:00
commit
d1854786a1
9 changed files with 526 additions and 158 deletions
|
@ -1,4 +1,4 @@
|
|||
namespace CommunityServerAPI.BattleBitAPI
|
||||
namespace BattleBitAPI
|
||||
{
|
||||
public static class Const
|
||||
{
|
||||
|
|
53
BattleBitAPI/Common/Enums/LogLevel.cs
Normal file
53
BattleBitAPI/Common/Enums/LogLevel.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
namespace BattleBitAPI.Common
|
||||
{
|
||||
[System.Flags]
|
||||
public enum LogLevel : ulong
|
||||
{
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs from low level sockets.
|
||||
/// </summary>
|
||||
Sockets = 1 << 0,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs from remote game server (Highly recommended)
|
||||
/// </summary>
|
||||
GameServerErrors = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs of game server connects, reconnects.
|
||||
/// </summary>
|
||||
GameServers = 1 << 2,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs of player connects, disconnects
|
||||
/// </summary>
|
||||
Players = 1 << 3,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs of squad changes (someone joining, leaving etc)
|
||||
/// </summary>
|
||||
Squads = 1 << 4,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs of kills/giveups/revives.
|
||||
/// </summary>
|
||||
KillsAndSpawns = 1 << 5,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs of role changes (player changing role to medic, support etc).
|
||||
/// </summary>
|
||||
Roles = 1 << 6,
|
||||
|
||||
/// <summary>
|
||||
/// Output logs player's healt changes. (When received damage or healed)
|
||||
/// </summary>
|
||||
HealtChanges = 1 << 7,
|
||||
|
||||
/// <summary>
|
||||
/// Output everything.
|
||||
/// </summary>
|
||||
All = ulong.MaxValue,
|
||||
}
|
||||
}
|
|
@ -25,6 +25,12 @@ namespace BattleBitAPI.Common.Extentions
|
|||
#endif
|
||||
}
|
||||
|
||||
public static void Replace<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value)
|
||||
{
|
||||
dic.Remove(key);
|
||||
dic.Add(key, value);
|
||||
}
|
||||
|
||||
public static void SafeClose(this TcpClient client)
|
||||
{
|
||||
try { client.Close(); } catch { }
|
||||
|
|
|
@ -40,5 +40,7 @@
|
|||
OnPlayerGivenUp = 70,
|
||||
OnPlayerRevivedAnother = 71,
|
||||
OnSquadPointsChanged = 72,
|
||||
NotifyNewRoundID = 73,
|
||||
Log = 74,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
@ -9,7 +6,6 @@ using BattleBitAPI.Common;
|
|||
using BattleBitAPI.Common.Extentions;
|
||||
using BattleBitAPI.Networking;
|
||||
using BattleBitAPI.Pooling;
|
||||
using CommunityServerAPI.BattleBitAPI;
|
||||
|
||||
namespace BattleBitAPI.Server
|
||||
{
|
||||
|
@ -21,7 +17,6 @@ namespace BattleBitAPI.Server
|
|||
public IPAddress GameIP => mInternal.GameIP;
|
||||
public int GamePort => mInternal.GamePort;
|
||||
|
||||
public TcpClient Socket => mInternal.Socket;
|
||||
public bool IsPasswordProtected => mInternal.IsPasswordProtected;
|
||||
public string ServerName => mInternal.ServerName;
|
||||
public string Gamemode => mInternal.Gamemode;
|
||||
|
@ -33,6 +28,8 @@ namespace BattleBitAPI.Server
|
|||
public int MaxPlayerCount => mInternal.MaxPlayerCount;
|
||||
public string LoadingScreenText => mInternal.LoadingScreenText;
|
||||
public string ServerRulesText => mInternal.ServerRulesText;
|
||||
public uint RoundIndex => mInternal.RoundIndex;
|
||||
public long SessionID => mInternal.SessionID;
|
||||
public ServerSettings<TPlayer> ServerSettings => mInternal.ServerSettings;
|
||||
public MapRotation<TPlayer> MapRotation => mInternal.MapRotation;
|
||||
public GamemodeRotation<TPlayer> GamemodeRotation => mInternal.GamemodeRotation;
|
||||
|
@ -162,7 +159,7 @@ namespace BattleBitAPI.Server
|
|||
try
|
||||
{
|
||||
//Are we still connected on socket level?
|
||||
if (!Socket.Connected)
|
||||
if (mInternal.Socket == null || !mInternal.Socket.Connected)
|
||||
{
|
||||
mClose("Connection was terminated.");
|
||||
return;
|
||||
|
@ -175,10 +172,10 @@ namespace BattleBitAPI.Server
|
|||
return;
|
||||
}
|
||||
|
||||
var networkStream = Socket.GetStream();
|
||||
var networkStream = mInternal.Socket.GetStream();
|
||||
|
||||
//Read network packages.
|
||||
while (Socket.Available > 0)
|
||||
while (mInternal.Socket.Available > 0)
|
||||
{
|
||||
this.mInternal.mLastPackageReceived = Extentions.TickCount;
|
||||
|
||||
|
@ -409,10 +406,6 @@ namespace BattleBitAPI.Server
|
|||
public virtual async Task OnTick()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual async Task OnReconnected()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual async Task OnDisconnected()
|
||||
{
|
||||
|
@ -504,6 +497,10 @@ namespace BattleBitAPI.Server
|
|||
public virtual async Task OnRoundEnded()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual async Task OnSessionChanged(long oldSessionID, long newSessionID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ---- Functions ----
|
||||
|
@ -557,10 +554,18 @@ namespace BattleBitAPI.Server
|
|||
{
|
||||
ExecuteCommand("endgame");
|
||||
}
|
||||
public void SayToChat(string msg)
|
||||
public void SayToAllChat(string msg)
|
||||
{
|
||||
ExecuteCommand("say " + msg);
|
||||
}
|
||||
public void SayToChat(string msg, ulong steamID)
|
||||
{
|
||||
ExecuteCommand("sayto " + steamID + " " + msg);
|
||||
}
|
||||
public void SayToChat(string msg, Player<TPlayer> player)
|
||||
{
|
||||
SayToChat(msg, player.SteamID);
|
||||
}
|
||||
|
||||
public void StopServer()
|
||||
{
|
||||
|
@ -901,7 +906,7 @@ namespace BattleBitAPI.Server
|
|||
}
|
||||
|
||||
// ---- Static ----
|
||||
public static void SetInstance(GameServer<TPlayer> server, Internal @internal)
|
||||
internal static void SetInstance(GameServer<TPlayer> server, Internal @internal)
|
||||
{
|
||||
server.mInternal = @internal;
|
||||
}
|
||||
|
@ -912,6 +917,7 @@ namespace BattleBitAPI.Server
|
|||
// ---- Variables ----
|
||||
public ulong ServerHash;
|
||||
public bool IsConnected;
|
||||
public bool HasActiveConnectionSession;
|
||||
public IPAddress GameIP;
|
||||
public int GamePort;
|
||||
public TcpClient Socket;
|
||||
|
@ -928,6 +934,8 @@ namespace BattleBitAPI.Server
|
|||
public int MaxPlayerCount;
|
||||
public string LoadingScreenText;
|
||||
public string ServerRulesText;
|
||||
public uint RoundIndex;
|
||||
public long SessionID;
|
||||
public ServerSettings<TPlayer> ServerSettings;
|
||||
public MapRotation<TPlayer> MapRotation;
|
||||
public GamemodeRotation<TPlayer> GamemodeRotation;
|
||||
|
@ -948,6 +956,7 @@ namespace BattleBitAPI.Server
|
|||
public long mLastPackageReceived;
|
||||
public long mLastPackageSent;
|
||||
public bool mWantsToCloseConnection;
|
||||
public long mPreviousSessionID;
|
||||
public StringBuilder mBuilder;
|
||||
public Queue<(ulong steamID, PlayerModifications<TPlayer>.mPlayerModifications)> mChangedModifications;
|
||||
|
||||
|
@ -1294,7 +1303,9 @@ namespace BattleBitAPI.Server
|
|||
int inQueuePlayers,
|
||||
int maxPlayers,
|
||||
string loadingScreenText,
|
||||
string serverRulesText
|
||||
string serverRulesText,
|
||||
uint roundIndex,
|
||||
long sessionID
|
||||
)
|
||||
{
|
||||
this.ServerHash = ((ulong)port << 32) | (ulong)iP.ToUInt();
|
||||
|
@ -1315,6 +1326,8 @@ namespace BattleBitAPI.Server
|
|||
this.MaxPlayerCount = maxPlayers;
|
||||
this.LoadingScreenText = loadingScreenText;
|
||||
this.ServerRulesText = serverRulesText;
|
||||
this.RoundIndex = roundIndex;
|
||||
this.SessionID = sessionID;
|
||||
|
||||
this.ServerSettings.Reset();
|
||||
this._RoomSettings.Reset();
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace BattleBitAPI.Server
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return Team + " : " + Name;
|
||||
return "Squad " + Name;
|
||||
}
|
||||
|
||||
// ---- Internal ----
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace BattleBitAPI
|
|||
KickFromSquad();
|
||||
else
|
||||
{
|
||||
if(value.Team != this.Team)
|
||||
if (value.Team != this.Team)
|
||||
ChangeTeam(value.Team);
|
||||
JoinSquad(value.Name);
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ namespace BattleBitAPI
|
|||
}
|
||||
public bool InSquad => mInternal.SquadName != Squads.NoSquad;
|
||||
public int PingMs => mInternal.PingMs;
|
||||
public long CurrentSessionID => mInternal.SessionID;
|
||||
public bool IsConnected => mInternal.SessionID != 0;
|
||||
|
||||
public float HP
|
||||
{
|
||||
|
@ -156,56 +158,78 @@ namespace BattleBitAPI
|
|||
public virtual async Task OnDisconnected()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual async Task OnSessionChanged(long oldSessionID, long newSessionID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ---- Functions ----
|
||||
public void Kick(string reason = "")
|
||||
{
|
||||
GameServer.Kick(this, reason);
|
||||
if (IsConnected)
|
||||
GameServer.Kick(this, reason);
|
||||
}
|
||||
public void Kill()
|
||||
{
|
||||
GameServer.Kill(this);
|
||||
if (IsConnected)
|
||||
GameServer.Kill(this);
|
||||
}
|
||||
public void ChangeTeam()
|
||||
{
|
||||
GameServer.ChangeTeam(this);
|
||||
if (IsConnected)
|
||||
GameServer.ChangeTeam(this);
|
||||
}
|
||||
public void ChangeTeam(Team team)
|
||||
{
|
||||
GameServer.ChangeTeam(this, team);
|
||||
if (IsConnected)
|
||||
GameServer.ChangeTeam(this, team);
|
||||
}
|
||||
public void KickFromSquad()
|
||||
{
|
||||
GameServer.KickFromSquad(this);
|
||||
if (IsConnected)
|
||||
GameServer.KickFromSquad(this);
|
||||
}
|
||||
public void JoinSquad(Squads targetSquad)
|
||||
{
|
||||
GameServer.JoinSquad(this, targetSquad);
|
||||
if (IsConnected)
|
||||
GameServer.JoinSquad(this, targetSquad);
|
||||
}
|
||||
public void DisbandTheSquad()
|
||||
{
|
||||
GameServer.DisbandPlayerCurrentSquad(this);
|
||||
if (IsConnected)
|
||||
GameServer.DisbandPlayerCurrentSquad(this);
|
||||
}
|
||||
public void PromoteToSquadLeader()
|
||||
{
|
||||
GameServer.PromoteSquadLeader(this);
|
||||
if (IsConnected)
|
||||
GameServer.PromoteSquadLeader(this);
|
||||
}
|
||||
public void WarnPlayer(string msg)
|
||||
{
|
||||
GameServer.WarnPlayer(this, msg);
|
||||
if (IsConnected)
|
||||
GameServer.WarnPlayer(this, msg);
|
||||
}
|
||||
public void Message(string msg)
|
||||
{
|
||||
GameServer.MessageToPlayer(this, msg);
|
||||
if (IsConnected)
|
||||
GameServer.MessageToPlayer(this, msg);
|
||||
}
|
||||
public void SayToChat(string msg)
|
||||
{
|
||||
if (IsConnected)
|
||||
GameServer.SayToChat(msg, this);
|
||||
}
|
||||
|
||||
public void Message(string msg, float fadeoutTime)
|
||||
{
|
||||
GameServer.MessageToPlayer(this, msg, fadeoutTime);
|
||||
if (IsConnected)
|
||||
GameServer.MessageToPlayer(this, msg, fadeoutTime);
|
||||
}
|
||||
public void SetNewRole(GameRole role)
|
||||
{
|
||||
GameServer.SetRoleTo(this, role);
|
||||
if (IsConnected)
|
||||
GameServer.SetRoleTo(this, role);
|
||||
}
|
||||
public void Teleport(Vector3 target)
|
||||
{
|
||||
|
@ -213,47 +237,57 @@ namespace BattleBitAPI
|
|||
}
|
||||
public void SpawnPlayer(PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection)
|
||||
{
|
||||
GameServer.SpawnPlayer(this, loadout, wearings, position, lookDirection, stand, spawnProtection);
|
||||
if (IsConnected)
|
||||
GameServer.SpawnPlayer(this, loadout, wearings, position, lookDirection, stand, spawnProtection);
|
||||
}
|
||||
public void SetHP(float newHP)
|
||||
{
|
||||
GameServer.SetHP(this, newHP);
|
||||
if (IsConnected)
|
||||
GameServer.SetHP(this, newHP);
|
||||
}
|
||||
public void GiveDamage(float damage)
|
||||
{
|
||||
GameServer.GiveDamage(this, damage);
|
||||
if (IsConnected)
|
||||
GameServer.GiveDamage(this, damage);
|
||||
}
|
||||
public void Heal(float hp)
|
||||
{
|
||||
GameServer.Heal(this, hp);
|
||||
if (IsConnected)
|
||||
GameServer.Heal(this, hp);
|
||||
}
|
||||
public void SetPrimaryWeapon(WeaponItem item, int extraMagazines, bool clear = false)
|
||||
{
|
||||
GameServer.SetPrimaryWeapon(this, item, extraMagazines, clear);
|
||||
if (IsConnected)
|
||||
GameServer.SetPrimaryWeapon(this, item, extraMagazines, clear);
|
||||
}
|
||||
public void SetSecondaryWeapon(WeaponItem item, int extraMagazines, bool clear = false)
|
||||
{
|
||||
GameServer.SetSecondaryWeapon(this, item, extraMagazines, clear);
|
||||
if (IsConnected)
|
||||
GameServer.SetSecondaryWeapon(this, item, extraMagazines, clear);
|
||||
}
|
||||
public void SetFirstAidGadget(string item, int extra, bool clear = false)
|
||||
{
|
||||
GameServer.SetFirstAid(this, item, extra, clear);
|
||||
if (IsConnected)
|
||||
GameServer.SetFirstAid(this, item, extra, clear);
|
||||
}
|
||||
public void SetLightGadget(string item, int extra, bool clear = false)
|
||||
{
|
||||
GameServer.SetLightGadget(this, item, extra, clear);
|
||||
if (IsConnected)
|
||||
GameServer.SetLightGadget(this, item, extra, clear);
|
||||
}
|
||||
public void SetHeavyGadget(string item, int extra, bool clear = false)
|
||||
{
|
||||
GameServer.SetHeavyGadget(this, item, extra, clear);
|
||||
if (IsConnected)
|
||||
GameServer.SetHeavyGadget(this, item, extra, clear);
|
||||
}
|
||||
public void SetThrowable(string item, int extra, bool clear = false)
|
||||
{
|
||||
GameServer.SetThrowable(this, item, extra, clear);
|
||||
if (IsConnected)
|
||||
GameServer.SetThrowable(this, item, extra, clear);
|
||||
}
|
||||
|
||||
// ---- Static ----
|
||||
public static void SetInstance(TPlayer player, Player<TPlayer>.Internal @internal)
|
||||
internal static void SetInstance(TPlayer player, Player<TPlayer>.Internal @internal)
|
||||
{
|
||||
player.mInternal = @internal;
|
||||
}
|
||||
|
@ -275,6 +309,8 @@ namespace BattleBitAPI
|
|||
public Team Team;
|
||||
public Squads SquadName;
|
||||
public int PingMs = 999;
|
||||
public long PreviousSessionID = 0;
|
||||
public long SessionID = 0;
|
||||
|
||||
public bool IsAlive;
|
||||
public float HP;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System.Net;
|
||||
using System.Data;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Resources;
|
||||
using BattleBitAPI.Common;
|
||||
using BattleBitAPI.Common.Extentions;
|
||||
using BattleBitAPI.Networking;
|
||||
using CommunityServerAPI.BattleBitAPI;
|
||||
using BattleBitAPI.Pooling;
|
||||
|
||||
namespace BattleBitAPI.Server
|
||||
{
|
||||
|
@ -15,6 +16,7 @@ namespace BattleBitAPI.Server
|
|||
public bool IsListening { get; private set; }
|
||||
public bool IsDisposed { get; private set; }
|
||||
public int ListeningPort { get; private set; }
|
||||
public LogLevel LogLevel { get; set; } = LogLevel.None;
|
||||
|
||||
// --- Events ---
|
||||
/// <summary>
|
||||
|
@ -56,15 +58,6 @@ namespace BattleBitAPI.Server
|
|||
/// </remarks>
|
||||
public Func<GameServer<TPlayer>, Task> OnGameServerConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fired when a game server reconnects. (When game server connects while a socket is already open)
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// GameServer: Game server that is reconnecting.<br/>
|
||||
/// </remarks>
|
||||
public Func<GameServer<TPlayer>, Task> OnGameServerReconnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fired when a game server disconnects. Check (GameServer.TerminationReason) to see the reason.
|
||||
/// </summary>
|
||||
|
@ -94,16 +87,29 @@ namespace BattleBitAPI.Server
|
|||
/// </remarks>
|
||||
public Func<ulong, TPlayer> OnCreatingPlayerInstance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fired on log
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// LogLevel: The level of log<br/>
|
||||
/// string: The message<br/>
|
||||
/// object: The object that will be carried on log<br/>
|
||||
/// </remarks>
|
||||
public Action<LogLevel, string, object?> OnLog { get; set; }
|
||||
|
||||
// --- Private ---
|
||||
private TcpListener mSocket;
|
||||
private Dictionary<ulong, (TGameServer server, GameServer<TPlayer>.Internal resources)> mActiveConnections;
|
||||
private mInstances<TPlayer, TGameServer> mInstanceDatabase;
|
||||
private ItemPooling<GameServer<TPlayer>> mGameServerPool;
|
||||
|
||||
// --- Construction ---
|
||||
public ServerListener()
|
||||
{
|
||||
this.mActiveConnections = new Dictionary<ulong, (TGameServer, GameServer<TPlayer>.Internal)>(16);
|
||||
this.mInstanceDatabase = new mInstances<TPlayer, TGameServer>();
|
||||
this.mGameServerPool = new ItemPooling<GameServer<TPlayer>>(64);
|
||||
}
|
||||
|
||||
// --- Starting ---
|
||||
|
@ -122,6 +128,9 @@ namespace BattleBitAPI.Server
|
|||
this.ListeningPort = port;
|
||||
this.IsListening = true;
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"Listening TCP connections on port " + port, null);
|
||||
|
||||
mMainLoop();
|
||||
}
|
||||
public void Start(int port)
|
||||
|
@ -143,6 +152,9 @@ namespace BattleBitAPI.Server
|
|||
}
|
||||
catch { }
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"Stopped listening TCP connection.", null);
|
||||
|
||||
this.mSocket = null;
|
||||
this.ListeningPort = 0;
|
||||
this.IsListening = true;
|
||||
|
@ -161,22 +173,32 @@ namespace BattleBitAPI.Server
|
|||
{
|
||||
var ip = (client.Client.RemoteEndPoint as IPEndPoint).Address;
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"Incoming TCP connection from {ip}", client);
|
||||
|
||||
//Is this IP allowed?
|
||||
bool allow = true;
|
||||
if (OnGameServerConnecting != null)
|
||||
allow = await OnGameServerConnecting(ip);
|
||||
|
||||
//Close connection if it was not allowed.
|
||||
if (!allow)
|
||||
{
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"Incoming connection from {ip} was denied", client);
|
||||
|
||||
//Connection is not allowed from this IP.
|
||||
client.SafeClose();
|
||||
return;
|
||||
}
|
||||
|
||||
TGameServer server = null;
|
||||
GameServer<TPlayer>.Internal resources;
|
||||
//Read port,token,version
|
||||
string token;
|
||||
string version;
|
||||
int gamePort;
|
||||
try
|
||||
{
|
||||
using (CancellationTokenSource source = new CancellationTokenSource(Const.HailConnectTimeout))
|
||||
using (var source = new CancellationTokenSource(2000))
|
||||
{
|
||||
using (var readStream = Common.Serialization.Stream.Get())
|
||||
{
|
||||
|
@ -187,13 +209,13 @@ namespace BattleBitAPI.Server
|
|||
readStream.Reset();
|
||||
if (!await networkStream.TryRead(readStream, 1, source.Token))
|
||||
throw new Exception("Unable to read the package type");
|
||||
|
||||
NetworkCommuncation type = (NetworkCommuncation)readStream.ReadInt8();
|
||||
if (type != NetworkCommuncation.Hail)
|
||||
throw new Exception("Incoming package wasn't hail.");
|
||||
}
|
||||
|
||||
//Read the server token
|
||||
string token;
|
||||
{
|
||||
readStream.Reset();
|
||||
if (!await networkStream.TryRead(readStream, 2, source.Token))
|
||||
|
@ -211,7 +233,6 @@ namespace BattleBitAPI.Server
|
|||
}
|
||||
|
||||
//Read the server version
|
||||
string version;
|
||||
{
|
||||
readStream.Reset();
|
||||
if (!await networkStream.TryRead(readStream, 2, source.Token))
|
||||
|
@ -228,23 +249,66 @@ namespace BattleBitAPI.Server
|
|||
version = readStream.ReadString(stringSize);
|
||||
}
|
||||
|
||||
if (version != Const.Version)
|
||||
throw new Exception("Incoming server's version `" + version + "` does not match with current API version `" + Const.Version + "`");
|
||||
|
||||
//Read port
|
||||
int gamePort;
|
||||
{
|
||||
readStream.Reset();
|
||||
if (!await networkStream.TryRead(readStream, 2, source.Token))
|
||||
throw new Exception("Unable to read the Port");
|
||||
gamePort = readStream.ReadUInt16();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"{ip} failed to connected because " + e.Message, client);
|
||||
|
||||
if (OnValidateGameServerToken != null)
|
||||
allow = await OnValidateGameServerToken(ip, (ushort)gamePort, token);
|
||||
client.SafeClose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!allow)
|
||||
throw new Exception("Token was not valid!");
|
||||
var hash = ((ulong)gamePort << 32) | (ulong)ip.ToUInt();
|
||||
TGameServer server = null;
|
||||
GameServer<TPlayer>.Internal resources = null;
|
||||
try
|
||||
{
|
||||
//Does versions match?
|
||||
if (version != Const.Version)
|
||||
throw new Exception("Incoming server's version `" + version + "` does not match with current API version `" + Const.Version + "`");
|
||||
|
||||
//Is valid token?
|
||||
if (OnValidateGameServerToken != null)
|
||||
{
|
||||
if (!await OnValidateGameServerToken(ip, (ushort)gamePort, token))
|
||||
throw new Exception("Token was not valid!");
|
||||
}
|
||||
|
||||
//Are there any connections with same IP and port?
|
||||
{
|
||||
bool sessionExist = false;
|
||||
(TGameServer server, GameServer<TPlayer>.Internal resources) oldSession;
|
||||
|
||||
//Any sessions with this IP:Port?
|
||||
lock (this.mActiveConnections)
|
||||
sessionExist = this.mActiveConnections.TryGetValue(hash, out oldSession);
|
||||
|
||||
if (sessionExist)
|
||||
{
|
||||
//Close old session.
|
||||
oldSession.server.CloseConnection("Reconnecting.");
|
||||
|
||||
//Wait until session is fully closed.
|
||||
while (oldSession.resources.HasActiveConnectionSession)
|
||||
await Task.Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
using (var source = new CancellationTokenSource(Const.HailConnectTimeout))
|
||||
{
|
||||
using (var readStream = Common.Serialization.Stream.Get())
|
||||
{
|
||||
var networkStream = client.GetStream();
|
||||
|
||||
//Read is server protected
|
||||
bool isPasswordProtected;
|
||||
|
@ -404,7 +468,28 @@ namespace BattleBitAPI.Server
|
|||
}
|
||||
}
|
||||
|
||||
var hash = ((ulong)gamePort << 32) | (ulong)ip.ToUInt();
|
||||
//Round index
|
||||
uint roundIndex;
|
||||
{
|
||||
readStream.Reset();
|
||||
if (!await networkStream.TryRead(readStream, 4, source.Token))
|
||||
throw new Exception("Unable to read the Server Round Index");
|
||||
roundIndex = readStream.ReadUInt32();
|
||||
}
|
||||
|
||||
//Round index
|
||||
long sessionID;
|
||||
{
|
||||
readStream.Reset();
|
||||
if (!await networkStream.TryRead(readStream, 8, source.Token))
|
||||
throw new Exception("Unable to read the Server Round ID");
|
||||
sessionID = readStream.ReadInt64();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
server = this.mInstanceDatabase.GetServerInstance(hash, out resources, this.OnCreatingGameServerInstance, ip, (ushort)gamePort);
|
||||
resources.Set(
|
||||
this.mExecutePackage,
|
||||
|
@ -422,7 +507,9 @@ namespace BattleBitAPI.Server
|
|||
queuePlayers,
|
||||
maxPlayers,
|
||||
loadingScreenText,
|
||||
serverRulesText
|
||||
serverRulesText,
|
||||
roundIndex,
|
||||
sessionID
|
||||
);
|
||||
|
||||
//Room settings
|
||||
|
@ -584,7 +671,6 @@ namespace BattleBitAPI.Server
|
|||
playerInternal.SteamID = steamid;
|
||||
playerInternal.Name = username;
|
||||
playerInternal.IP = new IPAddress(ipHash);
|
||||
playerInternal.GameServer = (GameServer<TPlayer>)server;
|
||||
playerInternal.Team = team;
|
||||
playerInternal.SquadName = squad;
|
||||
playerInternal.Role = role;
|
||||
|
@ -605,6 +691,9 @@ namespace BattleBitAPI.Server
|
|||
playerInternal._Modifications.Read(readStream);
|
||||
}
|
||||
|
||||
playerInternal.GameServer = (GameServer<TPlayer>)server;
|
||||
playerInternal.SessionID = server.SessionID;
|
||||
|
||||
resources.AddPlayer(player);
|
||||
}
|
||||
|
||||
|
@ -666,83 +755,102 @@ namespace BattleBitAPI.Server
|
|||
}
|
||||
catch { }
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"{ip} failed to connected because " + e.Message, client);
|
||||
|
||||
client.SafeClose();
|
||||
return;
|
||||
}
|
||||
|
||||
bool connectionExist = false;
|
||||
|
||||
//Track the connection
|
||||
lock (this.mActiveConnections)
|
||||
{
|
||||
//An old connection exist with same IP + Port?
|
||||
if (connectionExist = this.mActiveConnections.TryGetValue(server.ServerHash, out var oldServer))
|
||||
{
|
||||
oldServer.resources.ReconnectFlag = true;
|
||||
this.mActiveConnections.Remove(server.ServerHash);
|
||||
}
|
||||
|
||||
this.mActiveConnections.Add(server.ServerHash, (server, resources));
|
||||
}
|
||||
|
||||
//Call the callback.
|
||||
if (!connectionExist)
|
||||
{
|
||||
//New connection!
|
||||
server.OnConnected();
|
||||
if (this.OnGameServerConnected != null)
|
||||
this.OnGameServerConnected(server);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reconnection
|
||||
server.OnReconnected();
|
||||
if (this.OnGameServerReconnected != null)
|
||||
this.OnGameServerReconnected(server);
|
||||
}
|
||||
|
||||
//Set the buffer sizes.
|
||||
client.ReceiveBufferSize = Const.MaxNetworkPackageSize;
|
||||
client.SendBufferSize = Const.MaxNetworkPackageSize;
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Sockets))
|
||||
OnLog(LogLevel.Sockets, $"Incoming game server from {ip}:{gamePort} accepted.", client);
|
||||
|
||||
//Join to main server loop.
|
||||
await mHandleGameServer(server, resources);
|
||||
}
|
||||
private async Task mHandleGameServer(TGameServer server, GameServer<TPlayer>.Internal @internal)
|
||||
{
|
||||
bool isTicking = false;
|
||||
|
||||
using (server)
|
||||
@internal.HasActiveConnectionSession = true;
|
||||
{
|
||||
async Task mTickAsync()
|
||||
// ---- Connected ----
|
||||
{
|
||||
isTicking = true;
|
||||
await server.OnTick();
|
||||
isTicking = false;
|
||||
lock (this.mActiveConnections)
|
||||
this.mActiveConnections.Replace(server.ServerHash, (server, @internal));
|
||||
|
||||
server.OnConnected();
|
||||
if (this.OnGameServerConnected != null)
|
||||
this.OnGameServerConnected(server);
|
||||
}
|
||||
|
||||
while (server.IsConnected)
|
||||
//Update sessions
|
||||
{
|
||||
if (!isTicking)
|
||||
mTickAsync();
|
||||
if (@internal.mPreviousSessionID != @internal.SessionID)
|
||||
{
|
||||
var oldSession = @internal.mPreviousSessionID;
|
||||
@internal.mPreviousSessionID = @internal.SessionID;
|
||||
|
||||
await server.Tick();
|
||||
await Task.Delay(10);
|
||||
if (oldSession != 0)
|
||||
server.OnSessionChanged(oldSession, @internal.SessionID);
|
||||
}
|
||||
|
||||
foreach (var item in @internal.Players)
|
||||
{
|
||||
var @player_internal = mInstanceDatabase.GetPlayerInternals(item.Key);
|
||||
if (@player_internal.PreviousSessionID != @player_internal.SessionID)
|
||||
{
|
||||
var previousID = @player_internal.PreviousSessionID;
|
||||
@player_internal.PreviousSessionID = @player_internal.SessionID;
|
||||
|
||||
if (previousID != 0)
|
||||
item.Value.OnSessionChanged(previousID, @player_internal.SessionID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!server.ReconnectFlag)
|
||||
if (this.LogLevel.HasFlag(LogLevel.GameServers))
|
||||
OnLog(LogLevel.GameServers, $"{server} has connected", server);
|
||||
|
||||
// ---- Ticking ----
|
||||
using (server)
|
||||
{
|
||||
var isTicking = false;
|
||||
async Task mTickAsync()
|
||||
{
|
||||
isTicking = true;
|
||||
await server.OnTick();
|
||||
isTicking = false;
|
||||
}
|
||||
|
||||
while (server.IsConnected)
|
||||
{
|
||||
if (!isTicking)
|
||||
mTickAsync();
|
||||
|
||||
await server.Tick();
|
||||
await Task.Delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Disconnected ----
|
||||
{
|
||||
mCleanup(server, @internal);
|
||||
|
||||
lock (this.mActiveConnections)
|
||||
this.mActiveConnections.Remove(server.ServerHash);
|
||||
|
||||
server.OnDisconnected();
|
||||
|
||||
if (this.OnGameServerDisconnected != null)
|
||||
this.OnGameServerDisconnected(server);
|
||||
}
|
||||
}
|
||||
|
||||
//Remove from list.
|
||||
if (!server.ReconnectFlag)
|
||||
lock (this.mActiveConnections)
|
||||
this.mActiveConnections.Remove(server.ServerHash);
|
||||
if (this.LogLevel.HasFlag(LogLevel.GameServers))
|
||||
OnLog(LogLevel.GameServers, $"{server} has disconnected", server);
|
||||
}
|
||||
@internal.HasActiveConnectionSession = false;
|
||||
}
|
||||
|
||||
// --- Logic Executing ---
|
||||
|
@ -767,8 +875,6 @@ namespace BattleBitAPI.Server
|
|||
playerInternal.SteamID = steamID;
|
||||
playerInternal.Name = username;
|
||||
playerInternal.IP = new IPAddress(ip);
|
||||
playerInternal.GameServer = (GameServer<TPlayer>)server;
|
||||
|
||||
playerInternal.Team = team;
|
||||
playerInternal.SquadName = squad;
|
||||
playerInternal.Role = role;
|
||||
|
@ -776,9 +882,24 @@ namespace BattleBitAPI.Server
|
|||
//Start from default.
|
||||
playerInternal._Modifications.Reset();
|
||||
|
||||
playerInternal.GameServer = (GameServer<TPlayer>)server;
|
||||
playerInternal.SessionID = server.SessionID;
|
||||
|
||||
resources.AddPlayer(player);
|
||||
player.OnConnected();
|
||||
server.OnPlayerConnected(player);
|
||||
|
||||
if (playerInternal.PreviousSessionID != playerInternal.SessionID)
|
||||
{
|
||||
var previousID = playerInternal.PreviousSessionID;
|
||||
playerInternal.PreviousSessionID = playerInternal.SessionID;
|
||||
|
||||
if (previousID != 0)
|
||||
player.OnSessionChanged(previousID, playerInternal.SessionID);
|
||||
}
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Players))
|
||||
OnLog(LogLevel.Players, $"{player} has connected", player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -817,8 +938,14 @@ namespace BattleBitAPI.Server
|
|||
server.OnPlayerLeftSquad((TPlayer)player, msquad);
|
||||
}
|
||||
|
||||
@internal.SessionID = 0;
|
||||
@internal.GameServer = null;
|
||||
|
||||
player.OnDisconnected();
|
||||
server.OnPlayerDisconnected((TPlayer)player);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Players))
|
||||
OnLog(LogLevel.Players, $"{player} has disconnected", player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -888,6 +1015,9 @@ namespace BattleBitAPI.Server
|
|||
|
||||
victimClient.OnDowned();
|
||||
server.OnAPlayerDownedAnotherPlayer(args);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{killer} downed {victim} in {(Vector3.Distance(killerPos, victimPos))} meters", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -946,13 +1076,19 @@ namespace BattleBitAPI.Server
|
|||
ulong steamID = stream.ReadUInt64();
|
||||
GameRole role = (GameRole)stream.ReadInt8();
|
||||
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
async Task mHandle()
|
||||
{
|
||||
bool accepted = await server.OnPlayerRequestingToChangeRole((TPlayer)client, role);
|
||||
if (this.LogLevel.HasFlag(LogLevel.Roles))
|
||||
OnLog(LogLevel.Roles, $"{player} asking to change role to {role}", player);
|
||||
|
||||
bool accepted = await server.OnPlayerRequestingToChangeRole((TPlayer)player, role);
|
||||
if (accepted)
|
||||
server.SetRoleTo(steamID, role);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Roles))
|
||||
OnLog(LogLevel.Roles, $"{player}'s request to change role to {role} was {(accepted ? "accepted" : "denied")}", player);
|
||||
}
|
||||
|
||||
mHandle();
|
||||
|
@ -967,13 +1103,16 @@ namespace BattleBitAPI.Server
|
|||
ulong steamID = stream.ReadUInt64();
|
||||
GameRole role = (GameRole)stream.ReadInt8();
|
||||
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
|
||||
@internal.Role = role;
|
||||
|
||||
client.OnChangedRole(role);
|
||||
server.OnPlayerChangedRole((TPlayer)client, role);
|
||||
player.OnChangedRole(role);
|
||||
server.OnPlayerChangedRole((TPlayer)player, role);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Roles))
|
||||
OnLog(LogLevel.Roles, $"{player} changed role to {role}", player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -985,18 +1124,21 @@ namespace BattleBitAPI.Server
|
|||
ulong steamID = stream.ReadUInt64();
|
||||
Squads squad = (Squads)stream.ReadInt8();
|
||||
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
|
||||
@internal.SquadName = squad;
|
||||
|
||||
var msquad = server.GetSquad(client.Team, squad);
|
||||
var msquad = server.GetSquad(player.Team, squad);
|
||||
var rsquad = resources.GetSquadInternal(msquad);
|
||||
lock (rsquad.Members)
|
||||
rsquad.Members.Add((TPlayer)client);
|
||||
rsquad.Members.Add((TPlayer)player);
|
||||
|
||||
client.OnJoinedSquad(msquad);
|
||||
server.OnPlayerJoinedSquad((TPlayer)client, msquad);
|
||||
player.OnJoinedSquad(msquad);
|
||||
server.OnPlayerJoinedSquad((TPlayer)player, msquad);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Squads))
|
||||
OnLog(LogLevel.Squads, $"{player} has joined to {msquad}", msquad);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1007,30 +1149,33 @@ namespace BattleBitAPI.Server
|
|||
{
|
||||
ulong steamID = stream.ReadUInt64();
|
||||
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
|
||||
|
||||
var oldSquad = client.SquadName;
|
||||
var oldRole = client.Role;
|
||||
var oldSquad = player.SquadName;
|
||||
var oldRole = player.Role;
|
||||
@internal.SquadName = Squads.NoSquad;
|
||||
@internal.Role = GameRole.Assault;
|
||||
|
||||
var msquad = server.GetSquad(client.Team, oldSquad);
|
||||
var msquad = server.GetSquad(player.Team, oldSquad);
|
||||
var rsquad = resources.GetSquadInternal(msquad);
|
||||
|
||||
@internal.SquadName = Squads.NoSquad;
|
||||
lock (rsquad.Members)
|
||||
rsquad.Members.Remove((TPlayer)client);
|
||||
rsquad.Members.Remove((TPlayer)player);
|
||||
|
||||
client.OnLeftSquad(msquad);
|
||||
server.OnPlayerLeftSquad((TPlayer)client, msquad);
|
||||
player.OnLeftSquad(msquad);
|
||||
server.OnPlayerLeftSquad((TPlayer)player, msquad);
|
||||
|
||||
if (oldRole != GameRole.Assault)
|
||||
{
|
||||
client.OnChangedRole(GameRole.Assault);
|
||||
server.OnPlayerChangedRole((TPlayer)client, GameRole.Assault);
|
||||
player.OnChangedRole(GameRole.Assault);
|
||||
server.OnPlayerChangedRole((TPlayer)player, GameRole.Assault);
|
||||
}
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Squads))
|
||||
OnLog(LogLevel.Squads, $"{player} has left the {msquad}", msquad);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1064,11 +1209,14 @@ namespace BattleBitAPI.Server
|
|||
request.Read(stream);
|
||||
ushort vehicleID = stream.ReadUInt16();
|
||||
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
async Task mHandle()
|
||||
{
|
||||
var responseSpawn = await server.OnPlayerSpawning((TPlayer)client, request);
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{player} asking to spawn at {request.SpawnPosition} ({request.RequestedPoint})", player);
|
||||
|
||||
var responseSpawn = await server.OnPlayerSpawning((TPlayer)player, request);
|
||||
|
||||
//Respond back.
|
||||
using (var response = Common.Serialization.Stream.Get())
|
||||
|
@ -1089,6 +1237,15 @@ namespace BattleBitAPI.Server
|
|||
|
||||
server.WriteToSocket(response);
|
||||
}
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
{
|
||||
if (responseSpawn == null)
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{player}'s spawn request was denied", player);
|
||||
else
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{player}'s spawn request was accepted at {responseSpawn.Value.SpawnPosition}", player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mHandle();
|
||||
|
@ -1120,7 +1277,7 @@ namespace BattleBitAPI.Server
|
|||
if (stream.CanRead(8 + 2))
|
||||
{
|
||||
ulong steamID = stream.ReadUInt64();
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
|
||||
|
||||
|
@ -1132,10 +1289,21 @@ namespace BattleBitAPI.Server
|
|||
wearings.Read(stream);
|
||||
@internal.CurrentWearings = wearings;
|
||||
|
||||
Vector3 position = new Vector3()
|
||||
{
|
||||
X = stream.ReadFloat(),
|
||||
Y = stream.ReadFloat(),
|
||||
Z = stream.ReadFloat(),
|
||||
};
|
||||
|
||||
@internal.Position = position;
|
||||
@internal.IsAlive = true;
|
||||
|
||||
client.OnSpawned();
|
||||
server.OnPlayerSpawned((TPlayer)client);
|
||||
player.OnSpawned();
|
||||
server.OnPlayerSpawned((TPlayer)player);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{player} has spawned at {player.Position}", player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1145,13 +1313,16 @@ namespace BattleBitAPI.Server
|
|||
if (stream.CanRead(8))
|
||||
{
|
||||
ulong steamid = stream.ReadUInt64();
|
||||
if (resources.TryGetPlayer(steamid, out var client))
|
||||
if (resources.TryGetPlayer(steamid, out var player))
|
||||
{
|
||||
var @internal = mInstanceDatabase.GetPlayerInternals(steamid);
|
||||
@internal.OnDie();
|
||||
|
||||
client.OnDied();
|
||||
server.OnPlayerDied((TPlayer)client);
|
||||
player.OnDied();
|
||||
server.OnPlayerDied((TPlayer)player);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{player} has died", player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1262,19 +1433,38 @@ namespace BattleBitAPI.Server
|
|||
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
|
||||
if (@internal.IsAlive)
|
||||
{
|
||||
float newHP = (com_healt * 0.5f) - 1f;
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.HealtChanges))
|
||||
{
|
||||
var player = resources.Players[steamID];
|
||||
float dtHP = newHP - @internal.HP;
|
||||
if (dtHP > 0)
|
||||
{
|
||||
//Heal
|
||||
OnLog(LogLevel.HealtChanges, $"{player} was healed by {dtHP} HP (new HP is {newHP} HP)", player);
|
||||
}
|
||||
else if(dtHP < 0)
|
||||
{
|
||||
//Damage
|
||||
OnLog(LogLevel.HealtChanges, $"{player} was damaged by {(-dtHP)} HP (new HP is {newHP} HP)", player);
|
||||
}
|
||||
}
|
||||
|
||||
@internal.Position = new Vector3()
|
||||
{
|
||||
X = com_posX * decompressX,
|
||||
Y = com_posY * decompressY,
|
||||
Z = com_posZ * decompressZ,
|
||||
};
|
||||
@internal.HP = (com_healt * 0.5f) - 1f;
|
||||
@internal.HP = newHP;
|
||||
@internal.Standing = standing;
|
||||
@internal.Leaning = side;
|
||||
@internal.CurrentLoadoutIndex = loadoutIndex;
|
||||
@internal.InVehicle = inSeat;
|
||||
@internal.IsBleeding = isBleeding;
|
||||
@internal.PingMs = ping;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1285,10 +1475,13 @@ namespace BattleBitAPI.Server
|
|||
if (stream.CanRead(8))
|
||||
{
|
||||
ulong steamID = stream.ReadUInt64();
|
||||
if (resources.TryGetPlayer(steamID, out var client))
|
||||
if (resources.TryGetPlayer(steamID, out var player))
|
||||
{
|
||||
client.OnGivenUp();
|
||||
server.OnPlayerGivenUp((TPlayer)client);
|
||||
player.OnGivenUp();
|
||||
server.OnPlayerGivenUp((TPlayer)player);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{player} has givenup", player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1307,6 +1500,9 @@ namespace BattleBitAPI.Server
|
|||
{
|
||||
fromClient.OnRevivedAnotherPlayer();
|
||||
server.OnAPlayerRevivedAnotherPlayer((TPlayer)fromClient, (TPlayer)toClient);
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.KillsAndSpawns))
|
||||
OnLog(LogLevel.KillsAndSpawns, $"{fromClient} revived {toClient}", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1328,6 +1524,51 @@ namespace BattleBitAPI.Server
|
|||
rsquad.SquadPoints = points;
|
||||
server.OnSquadPointsChanged(msquad, points);
|
||||
}
|
||||
|
||||
if (this.LogLevel.HasFlag(LogLevel.Squads))
|
||||
OnLog(LogLevel.Squads, $"{msquad} now has {points} points", msquad);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NetworkCommuncation.NotifyNewRoundID:
|
||||
{
|
||||
if (stream.CanRead(4 + 8))
|
||||
{
|
||||
resources.RoundIndex = stream.ReadUInt32();
|
||||
resources.SessionID = stream.ReadInt64();
|
||||
|
||||
if (resources.mPreviousSessionID != resources.SessionID)
|
||||
{
|
||||
var oldSession = resources.mPreviousSessionID;
|
||||
resources.mPreviousSessionID = resources.SessionID;
|
||||
|
||||
if (oldSession != 0)
|
||||
server.OnSessionChanged(oldSession, resources.SessionID);
|
||||
}
|
||||
|
||||
foreach (var item in resources.Players)
|
||||
{
|
||||
var @player_internal = mInstanceDatabase.GetPlayerInternals(item.Key);
|
||||
@player_internal.SessionID = resources.SessionID;
|
||||
|
||||
if (@player_internal.PreviousSessionID != @player_internal.SessionID)
|
||||
{
|
||||
var previousID = @player_internal.PreviousSessionID;
|
||||
@player_internal.PreviousSessionID = @player_internal.SessionID;
|
||||
|
||||
if (previousID != 0)
|
||||
item.Value.OnSessionChanged(previousID, @player_internal.SessionID);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NetworkCommuncation.Log:
|
||||
{
|
||||
if (this.LogLevel.HasFlag(LogLevel.GameServerErrors))
|
||||
{
|
||||
if (stream.TryReadString(out var log))
|
||||
OnLog(LogLevel.GameServerErrors, log, server);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1335,6 +1576,18 @@ namespace BattleBitAPI.Server
|
|||
}
|
||||
|
||||
// --- Private ---
|
||||
private void mCleanup(GameServer<TPlayer> server, GameServer<TPlayer>.Internal @internal)
|
||||
{
|
||||
lock (@internal.Players)
|
||||
{
|
||||
foreach (var item in @internal.Players)
|
||||
{
|
||||
var @player_internal = mInstanceDatabase.GetPlayerInternals(item.Key);
|
||||
@player_internal.SessionID = 0;
|
||||
@player_internal.GameServer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
private Player<TPlayer>.Internal mGetPlayerInternals(ulong steamID)
|
||||
{
|
||||
return mInstanceDatabase.GetPlayerInternals(steamID);
|
||||
|
@ -1345,13 +1598,17 @@ namespace BattleBitAPI.Server
|
|||
{
|
||||
get
|
||||
{
|
||||
var list = new List<TGameServer>(mActiveConnections.Count);
|
||||
lock (mActiveConnections)
|
||||
using (var list = this.mGameServerPool.Get())
|
||||
{
|
||||
foreach (var item in mActiveConnections.Values)
|
||||
list.Add(item.server);
|
||||
//Get a copy
|
||||
lock (mActiveConnections)
|
||||
foreach (var item in mActiveConnections.Values)
|
||||
list.ListItems.Add(item.server);
|
||||
|
||||
//Iterate
|
||||
for (int i = 0; i < list.ListItems.Count; i++)
|
||||
yield return (TGameServer)list.ListItems[i];
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
public bool TryGetGameServer(IPAddress ip, ushort port, out TGameServer server)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<PackageProjectUrl>https://github.com/MrOkiDoki/BattleBit-Community-Server-API</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/MrOkiDoki/BattleBit-Community-Server-API</RepositoryUrl>
|
||||
<PackageTags>BattleBit</PackageTags>
|
||||
<Version>1.0.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Reference in a new issue