diff --git a/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs b/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs index a0e0e2c..ca8389a 100644 --- a/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs +++ b/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs @@ -1,5 +1,4 @@ using System.Numerics; -using CommunityServerAPI.BattleBitAPI.Server; namespace BattleBitAPI.Common { diff --git a/BattleBitAPI/Common/Conts.cs b/BattleBitAPI/Common/Conts.cs index d7577ea..4abba28 100644 --- a/BattleBitAPI/Common/Conts.cs +++ b/BattleBitAPI/Common/Conts.cs @@ -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; diff --git a/BattleBitAPI/Common/Data/PlayerLoadout.cs b/BattleBitAPI/Common/Data/PlayerLoadout.cs index c6f8a0e..abd14f9 100644 --- a/BattleBitAPI/Common/Data/PlayerLoadout.cs +++ b/BattleBitAPI/Common/Data/PlayerLoadout.cs @@ -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; diff --git a/BattleBitAPI/Networking/NetworkCommuncation.cs b/BattleBitAPI/Networking/NetworkCommuncation.cs index 428f1a9..1199b5a 100644 --- a/BattleBitAPI/Networking/NetworkCommuncation.cs +++ b/BattleBitAPI/Networking/NetworkCommuncation.cs @@ -15,6 +15,7 @@ SetNewRoundState = 15, SetPlayerWeapon = 16, SetPlayerGadget = 17, + SetPlayerModifications = 18, PlayerConnected = 50, PlayerDisconnected = 51, diff --git a/BattleBitAPI/Server/GameServer.cs b/BattleBitAPI/Server/GameServer.cs index c3c0169..6b92ed7 100644 --- a/BattleBitAPI/Server/GameServer.cs +++ b/BattleBitAPI/Server/GameServer.cs @@ -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.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 player, float value) - { - SetRunningSpeedMultiplier(player.SteamID, value); - } - public void SetReceiveDamageMultiplier(ulong steamID, float value) - { - ExecuteCommand("setreceivedamagemultiplier " + steamID + " " + value); - } - public void SetReceiveDamageMultiplier(Player player, float value) - { - SetReceiveDamageMultiplier(player.SteamID, value); - } - public void SetGiveDamageMultiplier(ulong steamID, float value) - { - ExecuteCommand("setgivedamagemultiplier " + steamID + " " + value); - } - public void SetGiveDamageMultiplier(Player player, float value) - { - SetGiveDamageMultiplier(player.SteamID, value); - } - public void SetJumpMultiplier(ulong steamID, float value) - { - ExecuteCommand("setjumpmultiplier " + steamID + " " + value); - } - public void SetJumpMultiplier(Player player, float value) - { - SetJumpMultiplier(player.SteamID, value); - } - public void SetFallDamageMultiplier(ulong steamID, float value) - { - ExecuteCommand("setfalldamagemultiplier " + steamID + " " + value); - } - public void SetFallDamageMultiplier(Player 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, Internal, Common.Serialization.Stream, Task> mExecutionFunc; + public Func.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.mPlayerModifications)> mChangedModifications; public Internal() { @@ -816,17 +807,18 @@ namespace BattleBitAPI.Server this.MapRotation = new MapRotation(this); this.GamemodeRotation = new GamemodeRotation(this); this.RoundSettings = new RoundSettings(this); + this.mChangedModifications = new Queue<(ulong steamID, PlayerModifications.mPlayerModifications)>(254); } // ---- Players In Room ---- public Dictionary> Players = new Dictionary>(254); // ---- Room Settings ---- - public mRoomSettings _RoomSettings = new mRoomSettings(); + public ServerSettings.mRoomSettings _RoomSettings = new ServerSettings.mRoomSettings(); public bool IsDirtyRoomSettings; // ---- Round Settings ---- - public mRoundSettings _RoundSettings = new mRoundSettings(); + public RoundSettings.mRoundSettings _RoundSettings = new RoundSettings.mRoundSettings(); public bool IsDirtyRoundSettings; // ---- Map Rotation ---- @@ -838,7 +830,24 @@ namespace BattleBitAPI.Server public bool IsDirtyGamemodeRotation = false; // ---- Public Functions ---- - public void Set(Func, 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, Internal, Common.Serialization.Stream, Task> func, + Func.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 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; - } - } } } diff --git a/BattleBitAPI/Server/Internal/GamemodeRotation.cs b/BattleBitAPI/Server/Internal/GamemodeRotation.cs index 7c5ee4d..999b11b 100644 --- a/BattleBitAPI/Server/Internal/GamemodeRotation.cs +++ b/BattleBitAPI/Server/Internal/GamemodeRotation.cs @@ -1,5 +1,4 @@ using BattleBitAPI.Common; -using CommunityServerAPI.BattleBitAPI.Server; namespace BattleBitAPI.Server { diff --git a/BattleBitAPI/Server/Internal/MapRotation.cs b/BattleBitAPI/Server/Internal/MapRotation.cs index c718005..3361e56 100644 --- a/BattleBitAPI/Server/Internal/MapRotation.cs +++ b/BattleBitAPI/Server/Internal/MapRotation.cs @@ -1,5 +1,4 @@ -using CommunityServerAPI.BattleBitAPI.Server; - + namespace BattleBitAPI.Server { public class MapRotation where TPlayer : Player diff --git a/BattleBitAPI/Server/Internal/PlayerModifications.cs b/BattleBitAPI/Server/Internal/PlayerModifications.cs index 4f9c77e..ff48e86 100644 --- a/BattleBitAPI/Server/Internal/PlayerModifications.cs +++ b/BattleBitAPI/Server/Internal/PlayerModifications.cs @@ -2,27 +2,410 @@ { public class PlayerModifications where TPlayer : Player { + // ---- Construction ---- private Player.Internal @internal; public PlayerModifications(Player.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; + } + } } } diff --git a/BattleBitAPI/Server/Internal/RoundSettings.cs b/BattleBitAPI/Server/Internal/RoundSettings.cs index a25a203..4653da8 100644 --- a/BattleBitAPI/Server/Internal/RoundSettings.cs +++ b/BattleBitAPI/Server/Internal/RoundSettings.cs @@ -1,16 +1,17 @@ using BattleBitAPI.Common; -using CommunityServerAPI.BattleBitAPI.Server; namespace BattleBitAPI.Server { public class RoundSettings where TPlayer : Player { + // ---- Construction ---- private GameServer.Internal mResources; public RoundSettings(GameServer.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; + } + } } } diff --git a/BattleBitAPI/Server/Internal/ServerSettings.cs b/BattleBitAPI/Server/Internal/ServerSettings.cs index b84bdf8..64eee73 100644 --- a/BattleBitAPI/Server/Internal/ServerSettings.cs +++ b/BattleBitAPI/Server/Internal/ServerSettings.cs @@ -1,47 +1,33 @@ -using CommunityServerAPI.BattleBitAPI.Server; - -namespace BattleBitAPI.Server +namespace BattleBitAPI.Server { public class ServerSettings where TPlayer : Player { + // ---- Construction ---- private GameServer.Internal mResources; public ServerSettings(GameServer.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; + } + } } } diff --git a/BattleBitAPI/Server/Player.cs b/BattleBitAPI/Server/Player.cs index c05f783..d16c0b7 100644 --- a/BattleBitAPI/Server/Player.cs +++ b/BattleBitAPI/Server/Player.cs @@ -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.mPlayerModifications _Modifications; public PlayerModifications Modifications; public Internal() { + this._Modifications = new PlayerModifications.mPlayerModifications(); this.Modifications = new PlayerModifications(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(); - } - } } } diff --git a/BattleBitAPI/Server/ServerListener.cs b/BattleBitAPI/Server/ServerListener.cs index 5a4d261..4177d6c 100644 --- a/BattleBitAPI/Server/ServerListener.cs +++ b/BattleBitAPI/Server/ServerListener.cs @@ -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 /// public Func> OnGameServerConnecting { get; set; } + /// + /// Fired when server needs to validate token from incoming connection.
+ /// Default, any connection attempt will be accepted + ///
+ /// + /// + /// IPAddress: IP of incoming connection
+ /// ushort: Game Port of the connection
+ /// string: Token of connection
+ ///
+ /// + /// + /// Returns: true if allow connection, false if deny the connection. + /// + public Func> OnValidateGameServerToken { get; set; } + /// /// Fired when a game server connects. /// @@ -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.mRoundSettings.Size, source.Token)) + if (!await networkStream.TryRead(readStream, RoundSettings.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.mRoundSettings.Size)) + if (stream.CanRead(RoundSettings.mRoundSettings.Size)) { var oldState = resources._RoundSettings.State; resources._RoundSettings.Read(stream); @@ -1187,6 +1239,12 @@ namespace BattleBitAPI.Server } } + // --- Private --- + private Player.Internal mGetPlayerInternals(ulong steamID) + { + return mInstanceDatabase.GetPlayerInternals(steamID); + } + // --- Public --- public IEnumerable ConnectedGameServers { diff --git a/Program.cs b/Program.cs index 022a2b9..9c041c0 100644 --- a/Program.cs +++ b/Program.cs @@ -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(); + listener.OnGameServerConnecting += OnGameServerConnecting; + listener.OnValidateGameServerToken += OnValidateGameServerToken; listener.Start(29294); Thread.Sleep(-1); } + private static async Task OnValidateGameServerToken(IPAddress ip, ushort gameport, string sentToken) + { + await Console.Out.WriteLineAsync(ip + ":" + gameport + " sent " + sentToken); + return true; + } + + private static async Task OnGameServerConnecting(IPAddress arg) + { + await Console.Out.WriteLineAsync(arg.ToString() + " connecting"); + return true; + } } class MyPlayer : Player { - public override async Task OnConnected() + public override async Task OnSpawned() { } } @@ -27,14 +42,25 @@ class MyGameServer : GameServer 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) {