Tons of new stuff.

This commit is contained in:
MrOkiDoki 2023-08-17 18:39:20 +03:00
parent 164cf6b349
commit 4a87c1e13a
13 changed files with 688 additions and 317 deletions

View File

@ -1,5 +1,4 @@
using System.Numerics;
using CommunityServerAPI.BattleBitAPI.Server;
namespace BattleBitAPI.Common
{

View File

@ -28,6 +28,8 @@
public const int MinServerNameLength = 5;
public const int MaxServerNameLength = 400;
public const int MaxTokenSize = 512;
public const int MinGamemodeNameLength = 2;
public const int MaxGamemodeNameLength = 12;

View File

@ -282,7 +282,7 @@
case AttachmentType.Barrel:
return this.Barrel == attachment;
case AttachmentType.UnderRail:
return this.Barrel == attachment;
return this.UnderRail == attachment;
case AttachmentType.SideRail:
return this.SideRail == attachment;
case AttachmentType.Bolt:
@ -307,7 +307,7 @@
this.Barrel = attachment;
break;
case AttachmentType.UnderRail:
this.Barrel = attachment;
this.UnderRail = attachment;
break;
case AttachmentType.SideRail:
this.SideRail = attachment;

View File

@ -15,6 +15,7 @@
SetNewRoundState = 15,
SetPlayerWeapon = 16,
SetPlayerGadget = 17,
SetPlayerModifications = 18,
PlayerConnected = 50,
PlayerDisconnected = 51,

View File

@ -101,6 +101,35 @@ namespace BattleBitAPI.Server
}
}
//Gather all changes.
this.mInternal.mChangedModifications.Clear();
lock (this.mInternal.Players)
{
foreach (var steamid in this.mInternal.Players.Keys)
{
var @internal = this.mInternal.mGetInternals(steamid);
if (@internal._Modifications.IsDirtyFlag)
this.mInternal.mChangedModifications.Enqueue((steamid, @internal._Modifications));
}
}
//Send all changes.
while (this.mInternal.mChangedModifications.Count > 0)
{
(ulong steamID, PlayerModifications<TPlayer>.mPlayerModifications modifications) item = this.mInternal.mChangedModifications.Dequeue();
item.modifications.IsDirtyFlag = false;
//Send new settings
using (var pck = Common.Serialization.Stream.Get())
{
pck.Write((byte)NetworkCommuncation.SetPlayerModifications);
pck.Write(item.steamID);
item.modifications.Write(pck);
WriteToSocket(pck);
}
}
try
{
//Are we still connected on socket level?
@ -315,7 +344,7 @@ namespace BattleBitAPI.Server
{
}
public virtual async Task OnAPlayerRevivedAnotherPlayer(TPlayer from,TPlayer to)
public virtual async Task OnAPlayerRevivedAnotherPlayer(TPlayer from, TPlayer to)
{
}
@ -555,46 +584,6 @@ namespace BattleBitAPI.Server
{
Heal(player.SteamID, heal);
}
public void SetRunningSpeedMultiplier(ulong steamID, float value)
{
ExecuteCommand("setrunningspeed " + steamID + " " + value);
}
public void SetRunningSpeedMultiplier(Player<TPlayer> player, float value)
{
SetRunningSpeedMultiplier(player.SteamID, value);
}
public void SetReceiveDamageMultiplier(ulong steamID, float value)
{
ExecuteCommand("setreceivedamagemultiplier " + steamID + " " + value);
}
public void SetReceiveDamageMultiplier(Player<TPlayer> player, float value)
{
SetReceiveDamageMultiplier(player.SteamID, value);
}
public void SetGiveDamageMultiplier(ulong steamID, float value)
{
ExecuteCommand("setgivedamagemultiplier " + steamID + " " + value);
}
public void SetGiveDamageMultiplier(Player<TPlayer> player, float value)
{
SetGiveDamageMultiplier(player.SteamID, value);
}
public void SetJumpMultiplier(ulong steamID, float value)
{
ExecuteCommand("setjumpmultiplier " + steamID + " " + value);
}
public void SetJumpMultiplier(Player<TPlayer> player, float value)
{
SetJumpMultiplier(player.SteamID, value);
}
public void SetFallDamageMultiplier(ulong steamID, float value)
{
ExecuteCommand("setfalldamagemultiplier " + steamID + " " + value);
}
public void SetFallDamageMultiplier(Player<TPlayer> player, float value)
{
SetFallDamageMultiplier(player.SteamID, value);
}
public void SetPrimaryWeapon(ulong steamID, WeaponItem item, int extraMagazines, bool clear = false)
{
@ -759,6 +748,7 @@ namespace BattleBitAPI.Server
public int GamePort;
public TcpClient Socket;
public Func<GameServer<TPlayer>, Internal, Common.Serialization.Stream, Task> mExecutionFunc;
public Func<ulong, Player<TPlayer>.Internal> mGetInternals;
public bool IsPasswordProtected;
public string ServerName;
public string Gamemode;
@ -786,6 +776,7 @@ namespace BattleBitAPI.Server
public long mLastPackageSent;
public bool mWantsToCloseConnection;
public StringBuilder mBuilder;
public Queue<(ulong steamID, PlayerModifications<TPlayer>.mPlayerModifications)> mChangedModifications;
public Internal()
{
@ -816,17 +807,18 @@ namespace BattleBitAPI.Server
this.MapRotation = new MapRotation<TPlayer>(this);
this.GamemodeRotation = new GamemodeRotation<TPlayer>(this);
this.RoundSettings = new RoundSettings<TPlayer>(this);
this.mChangedModifications = new Queue<(ulong steamID, PlayerModifications<TPlayer>.mPlayerModifications)>(254);
}
// ---- Players In Room ----
public Dictionary<ulong, Player<TPlayer>> Players = new Dictionary<ulong, Player<TPlayer>>(254);
// ---- Room Settings ----
public mRoomSettings _RoomSettings = new mRoomSettings();
public ServerSettings<TPlayer>.mRoomSettings _RoomSettings = new ServerSettings<TPlayer>.mRoomSettings();
public bool IsDirtyRoomSettings;
// ---- Round Settings ----
public mRoundSettings _RoundSettings = new mRoundSettings();
public RoundSettings<TPlayer>.mRoundSettings _RoundSettings = new RoundSettings<TPlayer>.mRoundSettings();
public bool IsDirtyRoundSettings;
// ---- Map Rotation ----
@ -838,7 +830,24 @@ namespace BattleBitAPI.Server
public bool IsDirtyGamemodeRotation = false;
// ---- Public Functions ----
public void Set(Func<GameServer<TPlayer>, Internal, Common.Serialization.Stream, Task> func, TcpClient socket, IPAddress iP, int port, bool isPasswordProtected, string serverName, string gamemode, string map, MapSize mapSize, MapDayNight dayNight, int currentPlayers, int inQueuePlayers, int maxPlayers, string loadingScreenText, string serverRulesText)
public void Set(
Func<GameServer<TPlayer>, Internal, Common.Serialization.Stream, Task> func,
Func<ulong, Player<TPlayer>.Internal> internalGetFunc,
TcpClient socket,
IPAddress iP,
int port,
bool isPasswordProtected,
string serverName,
string gamemode,
string map,
MapSize mapSize,
MapDayNight dayNight,
int currentPlayers,
int inQueuePlayers,
int maxPlayers,
string loadingScreenText,
string serverRulesText
)
{
this.ServerHash = ((ulong)port << 32) | (ulong)iP.ToUInt();
this.IsConnected = true;
@ -846,6 +855,7 @@ namespace BattleBitAPI.Server
this.GamePort = port;
this.Socket = socket;
this.mExecutionFunc = func;
this.mGetInternals = internalGetFunc;
this.IsPasswordProtected = isPasswordProtected;
this.ServerName = serverName;
this.Gamemode = gamemode;
@ -884,6 +894,7 @@ namespace BattleBitAPI.Server
this.mLastPackageSent = Extentions.TickCount;
this.mWantsToCloseConnection = false;
this.mBuilder.Clear();
this.mChangedModifications.Clear();
}
public void AddPlayer(Player<TPlayer> player)
{
@ -904,117 +915,5 @@ namespace BattleBitAPI.Server
return Players.TryGetValue(steamID, out result);
}
}
public class mRoomSettings
{
public float DamageMultiplier = 1.0f;
public bool BleedingEnabled = true;
public bool StaminaEnabled = false;
public bool FriendlyFireEnabled = false;
public bool HideMapVotes = true;
public bool OnlyWinnerTeamCanVote = false;
public bool HitMarkersEnabled = true;
public bool PointLogEnabled = true;
public bool SpectatorEnabled = true;
public float CaptureFlagSpeedMultiplier = 1f;
public byte MedicLimitPerSquad = 8;
public byte EngineerLimitPerSquad = 8;
public byte SupportLimitPerSquad = 8;
public byte ReconLimitPerSquad = 8;
public void Write(Common.Serialization.Stream ser)
{
ser.Write(this.DamageMultiplier);
ser.Write(this.BleedingEnabled);
ser.Write(this.StaminaEnabled);
ser.Write(this.FriendlyFireEnabled);
ser.Write(this.HideMapVotes);
ser.Write(this.OnlyWinnerTeamCanVote);
ser.Write(this.HitMarkersEnabled);
ser.Write(this.PointLogEnabled);
ser.Write(this.SpectatorEnabled);
ser.Write(this.CaptureFlagSpeedMultiplier);
ser.Write(this.MedicLimitPerSquad);
ser.Write(this.EngineerLimitPerSquad);
ser.Write(this.SupportLimitPerSquad);
ser.Write(this.ReconLimitPerSquad);
}
public void Read(Common.Serialization.Stream ser)
{
this.DamageMultiplier = ser.ReadFloat();
this.BleedingEnabled = ser.ReadBool();
this.StaminaEnabled = ser.ReadBool();
this.FriendlyFireEnabled = ser.ReadBool();
this.HideMapVotes = ser.ReadBool();
this.OnlyWinnerTeamCanVote = ser.ReadBool();
this.HitMarkersEnabled = ser.ReadBool();
this.PointLogEnabled = ser.ReadBool();
this.SpectatorEnabled = ser.ReadBool();
this.CaptureFlagSpeedMultiplier = ser.ReadFloat();
this.MedicLimitPerSquad = ser.ReadInt8();
this.EngineerLimitPerSquad = ser.ReadInt8();
this.SupportLimitPerSquad = ser.ReadInt8();
this.ReconLimitPerSquad = ser.ReadInt8();
}
public void Reset()
{
this.DamageMultiplier = 1.0f;
this.BleedingEnabled = true;
this.StaminaEnabled = false;
this.FriendlyFireEnabled = false;
this.HideMapVotes = true;
this.OnlyWinnerTeamCanVote = false;
this.HitMarkersEnabled = true;
this.PointLogEnabled = true;
this.SpectatorEnabled = true;
this.MedicLimitPerSquad = 8;
this.EngineerLimitPerSquad = 8;
this.SupportLimitPerSquad = 8;
this.ReconLimitPerSquad = 8;
}
}
public class mRoundSettings
{
public const int Size = 1 + 8 + 8 + 8 + 4 + 4;
public GameState State = GameState.WaitingForPlayers;
public double TeamATickets = 0;
public double TeamBTickets = 0;
public double MaxTickets = 1;
public int PlayersToStart = 16;
public int SecondsLeft = 60;
public void Write(Common.Serialization.Stream ser)
{
ser.Write((byte)this.State);
ser.Write(this.TeamATickets);
ser.Write(this.TeamBTickets);
ser.Write(this.MaxTickets);
ser.Write(this.PlayersToStart);
ser.Write(this.SecondsLeft);
}
public void Read(Common.Serialization.Stream ser)
{
this.State = (GameState)ser.ReadInt8();
this.TeamATickets = ser.ReadDouble();
this.TeamBTickets = ser.ReadDouble();
this.MaxTickets = ser.ReadDouble();
this.PlayersToStart = ser.ReadInt32();
this.SecondsLeft = ser.ReadInt32();
}
public void Reset()
{
this.State = GameState.WaitingForPlayers;
this.TeamATickets = 0;
this.TeamBTickets = 0;
this.MaxTickets = 1;
this.PlayersToStart = 16;
this.SecondsLeft = 60;
}
}
}
}

View File

@ -1,5 +1,4 @@
using BattleBitAPI.Common;
using CommunityServerAPI.BattleBitAPI.Server;
namespace BattleBitAPI.Server
{

View File

@ -1,5 +1,4 @@
using CommunityServerAPI.BattleBitAPI.Server;

namespace BattleBitAPI.Server
{
public class MapRotation<TPlayer> where TPlayer : Player<TPlayer>

View File

@ -2,27 +2,410 @@
{
public class PlayerModifications<TPlayer> where TPlayer : Player<TPlayer>
{
// ---- Construction ----
private Player<TPlayer>.Internal @internal;
public PlayerModifications(Player<TPlayer>.Internal @internal)
{
this.@internal = @internal;
}
public float RunningSpeedMultiplier { get; set; }
public float ReceiveDamageMultiplier { get; set; }
public float GiveDamageMultiplier { get; set; }
public float JumpHeightMultiplier { get; set; }
public float FallDamageMultiplier { get; set; }
public float ReloadSpeedMultiplier { get; set; }
public bool CanUseNightVision { get; set; }
public bool HasCollision { get; set; }
public float DownTimeGiveUpTime { get; set; }
public bool AirStrafe { get; set; }
public bool CanSpawn { get; set; }
public bool CanSpectate { get; set; }
public bool IsTextChatMuted { get; set; }
public bool IsVoiceChatMuted { get; set; }
public float RespawnTime { get; set; }
public bool CanRespawn { get; set; }
// ---- Variables ----
public float RunningSpeedMultiplier
{
get => @internal._Modifications.RunningSpeedMultiplier;
set
{
if (@internal._Modifications.RunningSpeedMultiplier == value)
return;
@internal._Modifications.RunningSpeedMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float ReceiveDamageMultiplier
{
get => @internal._Modifications.ReceiveDamageMultiplier;
set
{
if (@internal._Modifications.ReceiveDamageMultiplier == value)
return;
@internal._Modifications.ReceiveDamageMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float GiveDamageMultiplier
{
get => @internal._Modifications.GiveDamageMultiplier;
set
{
if (@internal._Modifications.GiveDamageMultiplier == value)
return;
@internal._Modifications.GiveDamageMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float JumpHeightMultiplier
{
get => @internal._Modifications.JumpHeightMultiplier;
set
{
if (@internal._Modifications.JumpHeightMultiplier == value)
return;
@internal._Modifications.JumpHeightMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float FallDamageMultiplier
{
get => @internal._Modifications.FallDamageMultiplier;
set
{
if (@internal._Modifications.FallDamageMultiplier == value)
return;
@internal._Modifications.FallDamageMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float ReloadSpeedMultiplier
{
get => @internal._Modifications.ReloadSpeedMultiplier;
set
{
if (@internal._Modifications.ReloadSpeedMultiplier == value)
return;
@internal._Modifications.ReloadSpeedMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool CanUseNightVision
{
get => @internal._Modifications.CanUseNightVision;
set
{
if (@internal._Modifications.CanUseNightVision == value)
return;
@internal._Modifications.CanUseNightVision = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float DownTimeGiveUpTime
{
get => @internal._Modifications.DownTimeGiveUpTime;
set
{
if (@internal._Modifications.DownTimeGiveUpTime == value)
return;
@internal._Modifications.DownTimeGiveUpTime = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool AirStrafe
{
get => @internal._Modifications.AirStrafe;
set
{
if (@internal._Modifications.AirStrafe == value)
return;
@internal._Modifications.AirStrafe = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool CanDeploy
{
get => @internal._Modifications.CanDeploy;
set
{
if (@internal._Modifications.CanDeploy == value)
return;
@internal._Modifications.CanDeploy = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool CanSpectate
{
get => @internal._Modifications.CanSpectate;
set
{
if (@internal._Modifications.CanSpectate == value)
return;
@internal._Modifications.CanSpectate = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool IsTextChatMuted
{
get => @internal._Modifications.IsTextChatMuted;
set
{
if (@internal._Modifications.IsTextChatMuted == value)
return;
@internal._Modifications.IsTextChatMuted = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool IsVoiceChatMuted
{
get => @internal._Modifications.IsVoiceChatMuted;
set
{
if (@internal._Modifications.IsVoiceChatMuted == value)
return;
@internal._Modifications.IsVoiceChatMuted = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float RespawnTime
{
get => @internal._Modifications.RespawnTime;
set
{
if (@internal._Modifications.RespawnTime == value)
return;
@internal._Modifications.RespawnTime = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool CanSuicide
{
get => @internal._Modifications.CanSuicide;
set
{
if (@internal._Modifications.CanSuicide == value)
return;
@internal._Modifications.CanSuicide = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float MinimumDamageToStartBleeding
{
get => @internal._Modifications.MinDamageToStartBleeding;
set
{
if (@internal._Modifications.MinDamageToStartBleeding == value)
return;
@internal._Modifications.MinDamageToStartBleeding = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float MinimumHpToStartBleeding
{
get => @internal._Modifications.MinHpToStartBleeding;
set
{
if (@internal._Modifications.MinHpToStartBleeding == value)
return;
@internal._Modifications.MinHpToStartBleeding = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float HpPerBandage
{
get => @internal._Modifications.HPperBandage;
set
{
if (value >= 100f)
value = 100f;
else if (value < 0)
value = 0f;
if (@internal._Modifications.HPperBandage == value)
return;
@internal._Modifications.HPperBandage = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool StaminaEnabled
{
get => @internal._Modifications.StaminaEnabled;
set
{
if (@internal._Modifications.StaminaEnabled == value)
return;
@internal._Modifications.StaminaEnabled = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool HitMarkersEnabled
{
get => @internal._Modifications.HitMarkersEnabled;
set
{
if (@internal._Modifications.HitMarkersEnabled == value)
return;
@internal._Modifications.HitMarkersEnabled = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool FriendlyHUDEnabled
{
get => @internal._Modifications.FriendlyHUDEnabled;
set
{
if (@internal._Modifications.FriendlyHUDEnabled == value)
return;
@internal._Modifications.FriendlyHUDEnabled = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public float CaptureFlagSpeedMultiplier
{
get => @internal._Modifications.CaptureFlagSpeedMultiplier;
set
{
if (@internal._Modifications.CaptureFlagSpeedMultiplier == value)
return;
@internal._Modifications.CaptureFlagSpeedMultiplier = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool PointLogHudEnabled
{
get => @internal._Modifications.PointLogHudEnabled;
set
{
if (@internal._Modifications.PointLogHudEnabled == value)
return;
@internal._Modifications.PointLogHudEnabled = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public bool KillFeed
{
get => @internal._Modifications.KillFeed;
set
{
if (@internal._Modifications.KillFeed == value)
return;
@internal._Modifications.KillFeed = value;
@internal._Modifications.IsDirtyFlag = true;
}
}
public void DisableBleeding()
{
this.MinimumDamageToStartBleeding = 100f;
this.MinimumHpToStartBleeding = 0f;
}
public void EnableBleeding(float minimumHP = 40f, float minimumDamage = 10f)
{
this.MinimumDamageToStartBleeding = minimumDamage;
this.MinimumHpToStartBleeding = minimumHP;
}
// ---- Classes ----
public class mPlayerModifications
{
public float RunningSpeedMultiplier = 1f;
public float ReceiveDamageMultiplier = 1f;
public float GiveDamageMultiplier = 1f;
public float JumpHeightMultiplier = 1f;
public float FallDamageMultiplier = 1f;
public float ReloadSpeedMultiplier = 1f;
public bool CanUseNightVision = true;
public float DownTimeGiveUpTime = 60f;
public bool AirStrafe = true;
public bool CanDeploy = true;
public bool CanSpectate = true;
public bool IsTextChatMuted = false;
public bool IsVoiceChatMuted = false;
public float RespawnTime = 10f;
public bool CanSuicide = true;
public float MinDamageToStartBleeding = 10f;
public float MinHpToStartBleeding = 40f;
public float HPperBandage = 40f;
public bool StaminaEnabled = false;
public bool HitMarkersEnabled = true;
public bool FriendlyHUDEnabled = true;
public float CaptureFlagSpeedMultiplier = 1f;
public bool PointLogHudEnabled = true;
public bool KillFeed = false;
public bool IsDirtyFlag = false;
public void Write(BattleBitAPI.Common.Serialization.Stream ser)
{
ser.Write(this.RunningSpeedMultiplier);
ser.Write(this.ReceiveDamageMultiplier);
ser.Write(this.GiveDamageMultiplier);
ser.Write(this.JumpHeightMultiplier);
ser.Write(this.FallDamageMultiplier);
ser.Write(this.ReloadSpeedMultiplier);
ser.Write(this.CanUseNightVision);
ser.Write(this.DownTimeGiveUpTime);
ser.Write(this.AirStrafe);
ser.Write(this.CanDeploy);
ser.Write(this.CanSpectate);
ser.Write(this.IsTextChatMuted);
ser.Write(this.IsVoiceChatMuted);
ser.Write(this.RespawnTime);
ser.Write(this.CanSuicide);
ser.Write(this.MinDamageToStartBleeding);
ser.Write(this.MinHpToStartBleeding);
ser.Write(this.HPperBandage);
ser.Write(this.StaminaEnabled);
ser.Write(this.HitMarkersEnabled);
ser.Write(this.FriendlyHUDEnabled);
ser.Write(this.CaptureFlagSpeedMultiplier);
ser.Write(this.PointLogHudEnabled);
ser.Write(this.KillFeed);
}
public void Read(BattleBitAPI.Common.Serialization.Stream ser)
{
this.RunningSpeedMultiplier = ser.ReadFloat();
if (this.RunningSpeedMultiplier <= 0f)
this.RunningSpeedMultiplier = 0.01f;
this.ReceiveDamageMultiplier = ser.ReadFloat();
this.GiveDamageMultiplier = ser.ReadFloat();
this.JumpHeightMultiplier = ser.ReadFloat();
this.FallDamageMultiplier = ser.ReadFloat();
this.ReloadSpeedMultiplier = ser.ReadFloat();
this.CanUseNightVision = ser.ReadBool();
this.DownTimeGiveUpTime = ser.ReadFloat();
this.AirStrafe = ser.ReadBool();
this.CanDeploy = ser.ReadBool();
this.CanSpectate = ser.ReadBool();
this.IsTextChatMuted = ser.ReadBool();
this.IsVoiceChatMuted = ser.ReadBool();
this.RespawnTime = ser.ReadFloat();
this.CanSuicide = ser.ReadBool();
this.MinDamageToStartBleeding = ser.ReadFloat();
this.MinHpToStartBleeding = ser.ReadFloat();
this.HPperBandage = ser.ReadFloat();
this.StaminaEnabled = ser.ReadBool();
this.HitMarkersEnabled = ser.ReadBool();
this.FriendlyHUDEnabled = ser.ReadBool();
this.CaptureFlagSpeedMultiplier = ser.ReadFloat();
this.PointLogHudEnabled = ser.ReadBool();
this.KillFeed = ser.ReadBool();
}
public void Reset()
{
this.RunningSpeedMultiplier = 1f;
this.ReceiveDamageMultiplier = 1f;
this.GiveDamageMultiplier = 1f;
this.JumpHeightMultiplier = 1f;
this.FallDamageMultiplier = 1f;
this.ReloadSpeedMultiplier = 1f;
this.CanUseNightVision = true;
this.DownTimeGiveUpTime = 60f;
this.AirStrafe = true;
this.CanDeploy = true;
this.CanSpectate = true;
this.IsTextChatMuted = false;
this.IsVoiceChatMuted = false;
this.RespawnTime = 10f;
this.CanSuicide = true;
this.MinDamageToStartBleeding = 10f;
this.MinHpToStartBleeding = 40f;
this.HPperBandage = 40f;
this.StaminaEnabled = false;
this.HitMarkersEnabled = true;
this.FriendlyHUDEnabled = true;
this.CaptureFlagSpeedMultiplier = 1f;
this.PointLogHudEnabled = true;
this.KillFeed = false;
}
}
}
}

View File

@ -1,16 +1,17 @@
using BattleBitAPI.Common;
using CommunityServerAPI.BattleBitAPI.Server;
namespace BattleBitAPI.Server
{
public class RoundSettings<TPlayer> where TPlayer : Player<TPlayer>
{
// ---- Construction ----
private GameServer<TPlayer>.Internal mResources;
public RoundSettings(GameServer<TPlayer>.Internal resources)
{
mResources = resources;
}
// ---- Variables ----
public GameState State
{
get => this.mResources._RoundSettings.State;
@ -61,9 +62,52 @@ namespace BattleBitAPI.Server
}
}
// ---- Reset ----
public void Reset()
{
}
// ---- Classes ----
public class mRoundSettings
{
public const int Size = 1 + 8 + 8 + 8 + 4 + 4;
public GameState State = GameState.WaitingForPlayers;
public double TeamATickets = 0;
public double TeamBTickets = 0;
public double MaxTickets = 1;
public int PlayersToStart = 16;
public int SecondsLeft = 60;
public void Write(Common.Serialization.Stream ser)
{
ser.Write((byte)this.State);
ser.Write(this.TeamATickets);
ser.Write(this.TeamBTickets);
ser.Write(this.MaxTickets);
ser.Write(this.PlayersToStart);
ser.Write(this.SecondsLeft);
}
public void Read(Common.Serialization.Stream ser)
{
this.State = (GameState)ser.ReadInt8();
this.TeamATickets = ser.ReadDouble();
this.TeamBTickets = ser.ReadDouble();
this.MaxTickets = ser.ReadDouble();
this.PlayersToStart = ser.ReadInt32();
this.SecondsLeft = ser.ReadInt32();
}
public void Reset()
{
this.State = GameState.WaitingForPlayers;
this.TeamATickets = 0;
this.TeamBTickets = 0;
this.MaxTickets = 1;
this.PlayersToStart = 16;
this.SecondsLeft = 60;
}
}
}
}

View File

@ -1,47 +1,33 @@
using CommunityServerAPI.BattleBitAPI.Server;
namespace BattleBitAPI.Server
namespace BattleBitAPI.Server
{
public class ServerSettings<TPlayer> where TPlayer : Player<TPlayer>
{
// ---- Construction ----
private GameServer<TPlayer>.Internal mResources;
public ServerSettings(GameServer<TPlayer>.Internal resources)
{
mResources = resources;
}
// ---- Variables ----
public float DamageMultiplier
{
get => mResources._RoomSettings.DamageMultiplier;
set
{
if (mResources._RoomSettings.DamageMultiplier == value)
return;
mResources._RoomSettings.DamageMultiplier = value;
mResources.IsDirtyRoomSettings = true;
}
}
public bool BleedingEnabled
{
get => mResources._RoomSettings.BleedingEnabled;
set
{
mResources._RoomSettings.BleedingEnabled = value;
mResources.IsDirtyRoomSettings = true;
}
}
public bool StamineEnabled
{
get => mResources._RoomSettings.StaminaEnabled;
set
{
mResources._RoomSettings.StaminaEnabled = value;
mResources.IsDirtyRoomSettings = true;
}
}
public bool FriendlyFireEnabled
{
get => mResources._RoomSettings.FriendlyFireEnabled;
set
{
if (mResources._RoomSettings.FriendlyFireEnabled == value)
return;
mResources._RoomSettings.FriendlyFireEnabled = value;
mResources.IsDirtyRoomSettings = true;
}
@ -51,41 +37,82 @@ namespace BattleBitAPI.Server
get => mResources._RoomSettings.OnlyWinnerTeamCanVote;
set
{
if (mResources._RoomSettings.OnlyWinnerTeamCanVote == value)
return;
mResources._RoomSettings.OnlyWinnerTeamCanVote = value;
mResources.IsDirtyRoomSettings = true;
}
}
public bool HitMarkersEnabled
public bool PlayerCollision
{
get => mResources._RoomSettings.HitMarkersEnabled;
get => mResources._RoomSettings.PlayerCollision;
set
{
mResources._RoomSettings.HitMarkersEnabled = value;
mResources.IsDirtyRoomSettings = true;
}
}
public bool PointLogEnabled
{
get => mResources._RoomSettings.PointLogEnabled;
set
{
mResources._RoomSettings.PointLogEnabled = value;
mResources.IsDirtyRoomSettings = true;
}
}
public bool SpectatorEnabled
{
get => mResources._RoomSettings.SpectatorEnabled;
set
{
mResources._RoomSettings.SpectatorEnabled = value;
if (mResources._RoomSettings.PlayerCollision == value)
return;
mResources._RoomSettings.PlayerCollision = value;
mResources.IsDirtyRoomSettings = true;
}
}
// ---- Reset ----
public void Reset()
{
}
// ---- Classes ----
public class mRoomSettings
{
public float DamageMultiplier = 1.0f;
public bool FriendlyFireEnabled = false;
public bool HideMapVotes = true;
public bool OnlyWinnerTeamCanVote = false;
public bool PlayerCollision = false;
public byte MedicLimitPerSquad = 8;
public byte EngineerLimitPerSquad = 8;
public byte SupportLimitPerSquad = 8;
public byte ReconLimitPerSquad = 8;
public void Write(Common.Serialization.Stream ser)
{
ser.Write(this.DamageMultiplier);
ser.Write(this.FriendlyFireEnabled);
ser.Write(this.HideMapVotes);
ser.Write(this.OnlyWinnerTeamCanVote);
ser.Write(this.PlayerCollision);
ser.Write(this.MedicLimitPerSquad);
ser.Write(this.EngineerLimitPerSquad);
ser.Write(this.SupportLimitPerSquad);
ser.Write(this.ReconLimitPerSquad);
}
public void Read(Common.Serialization.Stream ser)
{
this.DamageMultiplier = ser.ReadFloat();
this.FriendlyFireEnabled = ser.ReadBool();
this.HideMapVotes = ser.ReadBool();
this.OnlyWinnerTeamCanVote = ser.ReadBool();
this.PlayerCollision=ser.ReadBool();
this.MedicLimitPerSquad = ser.ReadInt8();
this.EngineerLimitPerSquad = ser.ReadInt8();
this.SupportLimitPerSquad = ser.ReadInt8();
this.ReconLimitPerSquad = ser.ReadInt8();
}
public void Reset()
{
this.DamageMultiplier = 1.0f;
this.FriendlyFireEnabled = false;
this.HideMapVotes = true;
this.OnlyWinnerTeamCanVote = false;
this.PlayerCollision = false;
this.MedicLimitPerSquad = 8;
this.EngineerLimitPerSquad = 8;
this.SupportLimitPerSquad = 8;
this.ReconLimitPerSquad = 8;
}
}
}
}

View File

@ -49,7 +49,23 @@ namespace BattleBitAPI
public bool InSquad => mInternal.Squad != Squads.NoSquad;
public int PingMs => mInternal.PingMs;
public float HP => mInternal.HP;
public float HP
{
get => mInternal.HP;
set
{
if (mInternal.HP > 0)
{
float v = value;
if (v <= 0)
v = 0.1f;
else if (v > 100f)
v = 100f;
SetHP(v);
}
}
}
public bool IsAlive => mInternal.HP >= 0f;
public bool IsUp => mInternal.HP > 0f;
public bool IsDown => mInternal.HP == 0f;
@ -193,26 +209,6 @@ namespace BattleBitAPI
{
GameServer.Heal(this, hp);
}
public void SetRunningSpeedMultiplier(float value)
{
GameServer.SetRunningSpeedMultiplier(this, value);
}
public void SetReceiveDamageMultiplier(float value)
{
GameServer.SetReceiveDamageMultiplier(this, value);
}
public void SetGiveDamageMultiplier(float value)
{
GameServer.SetGiveDamageMultiplier(this, value);
}
public void SetJumpMultiplier(float value)
{
GameServer.SetJumpMultiplier(this, value);
}
public void SetFallDamageMultiplier(float value)
{
GameServer.SetFallDamageMultiplier(this, value);
}
public void SetPrimaryWeapon(WeaponItem item, int extraMagazines, bool clear = false)
{
GameServer.SetPrimaryWeapon(this, item, extraMagazines, clear);
@ -275,13 +271,13 @@ namespace BattleBitAPI
public PlayerLoadout CurrentLoadout;
public PlayerWearings CurrentWearings;
public mPlayerModifications _Modifications;
public PlayerModifications<TPlayer>.mPlayerModifications _Modifications;
public PlayerModifications<TPlayer> Modifications;
public Internal()
{
this._Modifications = new PlayerModifications<TPlayer>.mPlayerModifications();
this.Modifications = new PlayerModifications<TPlayer>(this);
this._Modifications = new mPlayerModifications();
}
public void OnDie()
@ -298,67 +294,5 @@ namespace BattleBitAPI
CurrentWearings = new PlayerWearings();
}
}
public class mPlayerModifications
{
public float RunningSpeedMultiplier = 1f;
public float ReceiveDamageMultiplier = 1f;
public float GiveDamageMultiplier = 1f;
public float JumpHeightMultiplier = 1f;
public float FallDamageMultiplier = 1f;
public float ReloadSpeedMultiplier = 1f;
public bool CanUseNightVision = true;
public bool HasCollision = false;
public float DownTimeGiveUpTime = 60f;
public bool AirStrafe = true;
public bool CanSpawn = true;
public bool CanSpectate = true;
public bool IsTextChatMuted = false;
public bool IsVoiceChatMuted = false;
public float RespawnTime = 10f;
public bool CanRespawn = true;
public bool IsDirtyFlag = false;
public void Write(BattleBitAPI.Common.Serialization.Stream ser)
{
ser.Write(this.RunningSpeedMultiplier);
ser.Write(this.ReceiveDamageMultiplier);
ser.Write(this.GiveDamageMultiplier);
ser.Write(this.JumpHeightMultiplier);
ser.Write(this.FallDamageMultiplier);
ser.Write(this.ReloadSpeedMultiplier);
ser.Write(this.CanUseNightVision);
ser.Write(this.HasCollision);
ser.Write(this.DownTimeGiveUpTime);
ser.Write(this.AirStrafe);
ser.Write(this.CanSpawn);
ser.Write(this.CanSpectate);
ser.Write(this.IsTextChatMuted);
ser.Write(this.IsVoiceChatMuted);
ser.Write(this.RespawnTime);
ser.Write(this.CanRespawn);
}
public void Read(BattleBitAPI.Common.Serialization.Stream ser)
{
this.RunningSpeedMultiplier = ser.ReadFloat();
if (this.RunningSpeedMultiplier <= 0f)
this.RunningSpeedMultiplier = 0.01f;
this.ReceiveDamageMultiplier = ser.ReadFloat();
this.GiveDamageMultiplier = ser.ReadFloat();
this.JumpHeightMultiplier = ser.ReadFloat();
this.FallDamageMultiplier = ser.ReadFloat();
this.ReloadSpeedMultiplier = ser.ReadFloat();
this.CanUseNightVision = ser.ReadBool();
this.HasCollision = ser.ReadBool();
this.DownTimeGiveUpTime = ser.ReadFloat();
this.AirStrafe = ser.ReadBool();
this.CanSpawn = ser.ReadBool();
this.CanSpectate = ser.ReadBool();
this.IsTextChatMuted = ser.ReadBool();
this.IsVoiceChatMuted = ser.ReadBool();
this.RespawnTime = ser.ReadFloat();
this.CanRespawn = ser.ReadBool();
}
}
}
}

View File

@ -1,15 +1,10 @@
using System.Diagnostics;
using System.Net;
using System.Net.Security;
using System.Net;
using System.Net.Sockets;
using System.Numerics;
using System.Xml;
using BattleBitAPI.Common;
using BattleBitAPI.Common.Extentions;
using BattleBitAPI.Common.Serialization;
using BattleBitAPI.Networking;
using CommunityServerAPI.BattleBitAPI;
using CommunityServerAPI.BattleBitAPI.Server;
namespace BattleBitAPI.Server
{
@ -35,6 +30,22 @@ namespace BattleBitAPI.Server
/// </value>
public Func<IPAddress, Task<bool>> OnGameServerConnecting { get; set; }
/// <summary>
/// Fired when server needs to validate token from incoming connection.<br/>
/// Default, any connection attempt will be accepted
/// </summary>
///
/// <remarks>
/// IPAddress: IP of incoming connection <br/>
/// ushort: Game Port of the connection <br/>
/// string: Token of connection<br/>
/// </remarks>
///
/// <value>
/// Returns: true if allow connection, false if deny the connection.
/// </value>
public Func<IPAddress, ushort, string, Task<bool>> OnValidateGameServerToken { get; set; }
/// <summary>
/// Fired when a game server connects.
/// </summary>
@ -178,6 +189,24 @@ namespace BattleBitAPI.Server
throw new Exception("Incoming package wasn't hail.");
}
//Read the server name
string token;
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 2, source.Token))
throw new Exception("Unable to read the Token Size");
int stringSize = readStream.ReadUInt16();
if (stringSize > Const.MaxTokenSize)
throw new Exception("Invalid token size");
readStream.Reset();
if (!await networkStream.TryRead(readStream, stringSize, source.Token))
throw new Exception("Unable to read the token");
token = readStream.ReadString(stringSize);
}
//Read port
int gamePort;
{
@ -187,6 +216,12 @@ namespace BattleBitAPI.Server
gamePort = readStream.ReadUInt16();
}
if (OnValidateGameServerToken != null)
allow = await OnValidateGameServerToken(ip, (ushort)gamePort, token);
if (!allow)
throw new Exception("Token was not valid!");
//Read is server protected
bool isPasswordProtected;
{
@ -349,6 +384,7 @@ namespace BattleBitAPI.Server
server = this.mInstanceDatabase.GetServerInstance(hash, out bool isNew, out resources);
resources.Set(
this.mExecutePackage,
this.mGetPlayerInternals,
client,
ip,
gamePort,
@ -409,7 +445,7 @@ namespace BattleBitAPI.Server
//Round Settings
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, GameServer<TPlayer>.mRoundSettings.Size, source.Token))
if (!await networkStream.TryRead(readStream, RoundSettings<TPlayer>.mRoundSettings.Size, source.Token))
throw new Exception("Unable to read the round settings");
resources._RoundSettings.Read(readStream);
}
@ -531,13 +567,26 @@ namespace BattleBitAPI.Server
playerInternal.CurrentLoadout = loadout;
playerInternal.CurrentWearings = wearings;
//Modifications
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 4, source.Token))
throw new Exception("Unable to read the Modifications Size");
int modificationSize = (int)readStream.ReadUInt32();
readStream.Reset();
if (!await networkStream.TryRead(readStream, modificationSize, source.Token))
throw new Exception("Unable to read the Modifications");
playerInternal._Modifications.Read(readStream);
}
//Call new instance callback if needed.
if (isNewClient)
{
if (this.OnCreatingPlayerInstance != null)
this.OnCreatingPlayerInstance(player);
}
resources.AddPlayer(player);
}
@ -677,6 +726,9 @@ namespace BattleBitAPI.Server
playerInternal.Squad = squad;
playerInternal.Role = role;
//Start from default.
playerInternal._Modifications.Reset();
if (isNewClient)
{
if (this.OnCreatingPlayerInstance != null)
@ -1066,7 +1118,7 @@ namespace BattleBitAPI.Server
}
case NetworkCommuncation.NotifyNewRoundState:
{
if (stream.CanRead(GameServer<TPlayer>.mRoundSettings.Size))
if (stream.CanRead(RoundSettings<TPlayer>.mRoundSettings.Size))
{
var oldState = resources._RoundSettings.State;
resources._RoundSettings.Read(stream);
@ -1187,6 +1239,12 @@ namespace BattleBitAPI.Server
}
}
// --- Private ---
private Player<TPlayer>.Internal mGetPlayerInternals(ulong steamID)
{
return mInstanceDatabase.GetPlayerInternals(steamID);
}
// --- Public ---
public IEnumerable<TGameServer> ConnectedGameServers
{

View File

@ -1,6 +1,8 @@
using BattleBitAPI;
using BattleBitAPI.Common;
using BattleBitAPI.Server;
using System.Net;
using System.Numerics;
using System.Threading.Channels;
using System.Xml;
@ -9,16 +11,29 @@ class Program
static void Main(string[] args)
{
var listener = new ServerListener<MyPlayer, MyGameServer>();
listener.OnGameServerConnecting += OnGameServerConnecting;
listener.OnValidateGameServerToken += OnValidateGameServerToken;
listener.Start(29294);
Thread.Sleep(-1);
}
private static async Task<bool> OnValidateGameServerToken(IPAddress ip, ushort gameport, string sentToken)
{
await Console.Out.WriteLineAsync(ip + ":" + gameport + " sent " + sentToken);
return true;
}
private static async Task<bool> OnGameServerConnecting(IPAddress arg)
{
await Console.Out.WriteLineAsync(arg.ToString() + " connecting");
return true;
}
}
class MyPlayer : Player<MyPlayer>
{
public override async Task OnConnected()
public override async Task OnSpawned()
{
}
}
@ -27,14 +42,25 @@ class MyGameServer : GameServer<MyPlayer>
public override async Task OnConnected()
{
ForceStartGame();
ServerSettings.PlayerCollision = true;
}
public override async Task OnDisconnected()
{
await Console.Out.WriteLineAsync("Disconnected: "+ this.TerminationReason);
}
ServerSettings.PointLogEnabled = false;
public override async Task OnTick()
{
base.ServerSettings.PlayerCollision = true;
foreach (var item in AllPlayers)
item.Modifications.CanSuicide = true;
}
public override async Task OnPlayerConnected(MyPlayer player)
{
await Console.Out.WriteLineAsync("Connected: " + player);
}
public override async Task OnPlayerSpawned(MyPlayer player)
{