From db51bbbc4ab9d6ee2916062f2801a5325a6bd5f5 Mon Sep 17 00:00:00 2001 From: Niko Storni Date: Mon, 14 Aug 2023 17:49:24 +0200 Subject: [PATCH] reformat and cleanup code --- .../Common/Arguments/OnPlayerKillArguments.cs | 24 +- .../Arguments/OnPlayerSpawnArguments.cs | 91 +- .../Common/Arguments/PlayerJoiningArgument.cs | 27 +- BattleBitAPI/Common/Conts.cs | 73 +- BattleBitAPI/Common/Data/Attachment.cs | 142 +- BattleBitAPI/Common/Data/Gadget.cs | 137 +- BattleBitAPI/Common/Data/Gadgets.cs | 131 +- BattleBitAPI/Common/Data/Map.cs | 137 +- BattleBitAPI/Common/Data/PlayerLoadout.cs | 670 ++--- BattleBitAPI/Common/Data/PlayerStats.cs | 634 ++--- BattleBitAPI/Common/Data/PlayerWearings.cs | 84 +- BattleBitAPI/Common/Data/Weapon.cs | 135 +- BattleBitAPI/Common/Datasets/Attachments.cs | 233 +- BattleBitAPI/Common/Datasets/Weapons.cs | 144 +- BattleBitAPI/Common/Enums/AttachmentType.cs | 23 +- BattleBitAPI/Common/Enums/ChatChannel.cs | 15 +- BattleBitAPI/Common/Enums/DamageReason.cs | 43 +- BattleBitAPI/Common/Enums/GameRole.cs | 16 +- BattleBitAPI/Common/Enums/GameState.cs | 17 +- BattleBitAPI/Common/Enums/LeaningSide.cs | 13 +- BattleBitAPI/Common/Enums/LoadoutIndex.cs | 21 +- BattleBitAPI/Common/Enums/MapDayNight.cs | 13 +- BattleBitAPI/Common/Enums/MapSize.cs | 21 +- BattleBitAPI/Common/Enums/PlayerBody.cs | 26 +- .../Common/Enums/PlayerSpawningPoint.cs | 15 +- BattleBitAPI/Common/Enums/PlayerStand.cs | 13 +- BattleBitAPI/Common/Enums/ReportReason.cs | 35 +- BattleBitAPI/Common/Enums/Roles.cs | 21 +- BattleBitAPI/Common/Enums/Squads.cs | 141 +- BattleBitAPI/Common/Enums/Team.cs | 15 +- BattleBitAPI/Common/Enums/WeaponType.cs | 31 +- BattleBitAPI/Common/Extentions/Extentions.cs | 108 +- .../Serialization/IStreamSerializble.cs | 13 +- BattleBitAPI/Common/Serialization/Stream.cs | 1413 +++++----- BattleBitAPI/Common/Threading/ThreadSafe.cs | 129 +- .../Networking/NetworkCommuncation.cs | 42 - .../Networking/NetworkCommunication.cs | 41 + BattleBitAPI/Server/GameServer.cs | 2053 +++++++------- .../Server/Internal/GamemodeRotation.cs | 132 +- BattleBitAPI/Server/Internal/MapRotation.cs | 143 +- .../Server/Internal/PlayerModifications.cs | 52 +- BattleBitAPI/Server/Internal/RoundSettings.cs | 120 +- .../Server/Internal/ServerSettings.cs | 172 +- BattleBitAPI/Server/Player.cs | 745 ++--- BattleBitAPI/Server/ServerListener.cs | 2422 +++++++++-------- BattleBitAPI/Storage/DiskStorage.cs | 64 +- BattleBitAPI/Storage/IPlayerStatsDatabase.cs | 13 +- Program.cs | 22 +- 48 files changed, 5572 insertions(+), 5253 deletions(-) delete mode 100644 BattleBitAPI/Networking/NetworkCommuncation.cs create mode 100644 BattleBitAPI/Networking/NetworkCommunication.cs diff --git a/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs b/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs index a0e0e2c..b635682 100644 --- a/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs +++ b/BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs @@ -1,18 +1,16 @@ using System.Numerics; -using CommunityServerAPI.BattleBitAPI.Server; -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public struct OnPlayerKillArguments where TPlayer : Player { - public struct OnPlayerKillArguments where TPlayer : Player - { - public TPlayer Killer; - public Vector3 KillerPosition; + public TPlayer Killer; + public Vector3 KillerPosition; - public TPlayer Victim; - public Vector3 VictimPosition; + public TPlayer Victim; + public Vector3 VictimPosition; - public string KillerTool; - public PlayerBody BodyPart; - public ReasonOfDamage SourceOfDamage; - } -} + public string KillerTool; + public PlayerBody BodyPart; + public ReasonOfDamage SourceOfDamage; +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Arguments/OnPlayerSpawnArguments.cs b/BattleBitAPI/Common/Arguments/OnPlayerSpawnArguments.cs index bb2f6a8..31dc8cf 100644 --- a/BattleBitAPI/Common/Arguments/OnPlayerSpawnArguments.cs +++ b/BattleBitAPI/Common/Arguments/OnPlayerSpawnArguments.cs @@ -1,50 +1,51 @@ using System.Numerics; +using Stream = BattleBitAPI.Common.Serialization.Stream; -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public struct OnPlayerSpawnArguments { - public struct OnPlayerSpawnArguments - { - public PlayerSpawningPosition RequestedPoint; - public PlayerLoadout Loadout; - public PlayerWearings Wearings; - public Vector3 SpawnPosition; - public Vector3 LookDirection; - public PlayerStand SpawnStand; - public float SpawnProtection; + public PlayerSpawningPosition RequestedPoint; + public PlayerLoadout Loadout; + public PlayerWearings Wearings; + public Vector3 SpawnPosition; + public Vector3 LookDirection; + public PlayerStand SpawnStand; + public float SpawnProtection; - public void Write(Common.Serialization.Stream ser) - { - ser.Write((byte)RequestedPoint); - Loadout.Write(ser); - Wearings.Write(ser); - ser.Write(SpawnPosition.X); - ser.Write(SpawnPosition.Y); - ser.Write(SpawnPosition.Z); - ser.Write(LookDirection.X); - ser.Write(LookDirection.Y); - ser.Write(LookDirection.Z); - ser.Write((byte)SpawnStand); - ser.Write(SpawnProtection); - } - public void Read(Common.Serialization.Stream ser) - { - RequestedPoint = (PlayerSpawningPosition)ser.ReadInt8(); - Loadout.Read(ser); - Wearings.Read(ser); - SpawnPosition = new Vector3() - { - X = ser.ReadFloat(), - Y = ser.ReadFloat(), - Z = ser.ReadFloat() - }; - LookDirection = new Vector3() - { - X = ser.ReadFloat(), - Y = ser.ReadFloat(), - Z = ser.ReadFloat() - }; - SpawnStand = (PlayerStand)ser.ReadInt8(); - SpawnProtection = ser.ReadFloat(); - } + public void Write(Stream ser) + { + ser.Write((byte)RequestedPoint); + Loadout.Write(ser); + Wearings.Write(ser); + ser.Write(SpawnPosition.X); + ser.Write(SpawnPosition.Y); + ser.Write(SpawnPosition.Z); + ser.Write(LookDirection.X); + ser.Write(LookDirection.Y); + ser.Write(LookDirection.Z); + ser.Write((byte)SpawnStand); + ser.Write(SpawnProtection); } -} + + public void Read(Stream ser) + { + RequestedPoint = (PlayerSpawningPosition)ser.ReadInt8(); + Loadout.Read(ser); + Wearings.Read(ser); + SpawnPosition = new Vector3 + { + X = ser.ReadFloat(), + Y = ser.ReadFloat(), + Z = ser.ReadFloat() + }; + LookDirection = new Vector3 + { + X = ser.ReadFloat(), + Y = ser.ReadFloat(), + Z = ser.ReadFloat() + }; + SpawnStand = (PlayerStand)ser.ReadInt8(); + SpawnProtection = ser.ReadFloat(); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs b/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs index 1cd9302..ffacf56 100644 --- a/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs +++ b/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs @@ -1,18 +1,17 @@ -using System; +using Stream = BattleBitAPI.Common.Serialization.Stream; -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public class PlayerJoiningArguments { - public class PlayerJoiningArguments - { - public PlayerStats Stats; - public Team Team; - public Squads Squad; + public Squads Squad; + public PlayerStats Stats; + public Team Team; - public void Write(BattleBitAPI.Common.Serialization.Stream ser) - { - this.Stats.Write(ser); - ser.Write((byte)this.Team); - ser.Write((byte)this.Squad); - } + public void Write(Stream ser) + { + Stats.Write(ser); + ser.Write((byte)Team); + ser.Write((byte)Squad); } -} +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Conts.cs b/BattleBitAPI/Common/Conts.cs index d7577ea..234294c 100644 --- a/BattleBitAPI/Common/Conts.cs +++ b/BattleBitAPI/Common/Conts.cs @@ -1,44 +1,47 @@ -namespace CommunityServerAPI.BattleBitAPI +namespace CommunityServerAPI.BattleBitAPI; + +public static class Const { - public static class Const - { - // ---- Networking ---- - /// - /// Maximum data size for a single package. 4MB is default. - /// - public const int MaxNetworkPackageSize = 1024 * 1024 * 4;//4mb - /// - /// How long should server/client wait until connection is determined as timed out when no packages is being sent for long time. - /// - public const int NetworkTimeout = 60 * 1000;//60 seconds - /// - /// How frequently client/server will send keep alive to each other when no message is being sent to each other for a while. - /// - public const int NetworkKeepAlive = 5 * 1000;//15 seconds - /// - /// How long server/client will wait other side to send their hail/initial package. In miliseconds. - /// + // ---- Networking ---- + /// + /// Maximum data size for a single package. 4MB is default. + /// + public const int MaxNetworkPackageSize = 1024 * 1024 * 4; //4mb + + /// + /// How long should server/client wait until connection is determined as timed out when no packages is being sent for + /// long time. + /// + public const int NetworkTimeout = 60 * 1000; //60 seconds + + /// + /// How frequently client/server will send keep alive to each other when no message is being sent to each other for a + /// while. + /// + public const int NetworkKeepAlive = 5 * 1000; //15 seconds + + /// + /// How long server/client will wait other side to send their hail/initial package. In miliseconds. + /// #if DEBUG - public const int HailConnectTimeout = 20 * 1000; + public const int HailConnectTimeout = 20 * 1000; #else - public const int HailConnectTimeout = 2 * 1000; + public const int HailConnectTimeout = 2 * 1000; #endif - // ---- Server Fields ---- - public const int MinServerNameLength = 5; - public const int MaxServerNameLength = 400; + // ---- Server Fields ---- + public const int MinServerNameLength = 5; + public const int MaxServerNameLength = 400; - public const int MinGamemodeNameLength = 2; - public const int MaxGamemodeNameLength = 12; + public const int MinGamemodeNameLength = 2; + public const int MaxGamemodeNameLength = 12; - public const int MinMapNameLength = 2; - public const int MaxMapNameLength = 36; + public const int MinMapNameLength = 2; + public const int MaxMapNameLength = 36; - public const int MinLoadingScreenTextLength = 0; - public const int MaxLoadingScreenTextLength = 1024 * 8; + public const int MinLoadingScreenTextLength = 0; + public const int MaxLoadingScreenTextLength = 1024 * 8; - public const int MinServerRulesTextLength = 0; - public const int MaxServerRulesTextLength = 1024 * 8; - - } -} + public const int MinServerRulesTextLength = 0; + public const int MaxServerRulesTextLength = 1024 * 8; +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/Attachment.cs b/BattleBitAPI/Common/Data/Attachment.cs index 2cb870f..2771ea9 100644 --- a/BattleBitAPI/Common/Data/Attachment.cs +++ b/BattleBitAPI/Common/Data/Attachment.cs @@ -1,74 +1,76 @@ -using BattleBitAPI.Common; -using System; +namespace BattleBitAPI.Common; -namespace BattleBitAPI.Common +public class Attachment : IEquatable, IEquatable { - public class Attachment : IEquatable, IEquatable + public Attachment(string name, AttachmentType attachmentType) { - public string Name { get; private set; } - public AttachmentType AttachmentType { get; private set; } - public Attachment(string name, AttachmentType attachmentType) - { - Name = name; - AttachmentType = attachmentType; - } - - public override string ToString() - { - return this.Name; - } - public bool Equals(string other) - { - if (other == null) - return false; - return this.Name.Equals(other); - } - public bool Equals(Attachment other) - { - if (other == null) - return false; - return this.Name.Equals(other.Name); - } - - public static bool operator ==(string left, Attachment right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(string left, Attachment right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator ==(Attachment right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(Attachment right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } + Name = name; + AttachmentType = attachmentType; } -} + + public string Name { get; } + public AttachmentType AttachmentType { get; private set; } + + public bool Equals(Attachment other) + { + if (other == null) + return false; + return Name.Equals(other.Name); + } + + public bool Equals(string other) + { + if (other == null) + return false; + return Name.Equals(other); + } + + public override string ToString() + { + return Name; + } + + public static bool operator ==(string left, Attachment right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(string left, Attachment right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator ==(Attachment right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(Attachment right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/Gadget.cs b/BattleBitAPI/Common/Data/Gadget.cs index dbc4b54..08f3be0 100644 --- a/BattleBitAPI/Common/Data/Gadget.cs +++ b/BattleBitAPI/Common/Data/Gadget.cs @@ -1,69 +1,74 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public class Gadget : IEquatable, IEquatable { - public class Gadget : IEquatable, IEquatable + public Gadget(string name) { - public string Name { get; private set; } - public Gadget(string name) - { - Name = name; - } - - public override string ToString() - { - return this.Name; - } - public bool Equals(string other) - { - if (other == null) - return false; - return this.Name.Equals(other); - } - public bool Equals(Gadget other) - { - if (other == null) - return false; - return this.Name.Equals(other.Name); - } - - public static bool operator ==(string left, Gadget right) - { - bool leftNull = object.ReferenceEquals(left,null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(string left, Gadget right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator ==(Gadget right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(Gadget right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } + Name = name; } -} + + public string Name { get; } + + public bool Equals(Gadget other) + { + if (other == null) + return false; + return Name.Equals(other.Name); + } + + public bool Equals(string other) + { + if (other == null) + return false; + return Name.Equals(other); + } + + public override string ToString() + { + return Name; + } + + public static bool operator ==(string left, Gadget right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(string left, Gadget right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator ==(Gadget right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(Gadget right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/Gadgets.cs b/BattleBitAPI/Common/Data/Gadgets.cs index b8e6216..f5736bd 100644 --- a/BattleBitAPI/Common/Data/Gadgets.cs +++ b/BattleBitAPI/Common/Data/Gadgets.cs @@ -1,76 +1,73 @@ using System.Reflection; -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public static class Gadgets { - public static class Gadgets + // ----- Private Variables ----- + private static readonly Dictionary mGadgets; + + // ----- Public Variables ----- + public static readonly Gadget Bandage = new("Bandage"); + public static readonly Gadget Binoculars = new("Binoculars"); + public static readonly Gadget RangeFinder = new("Range Finder"); + public static readonly Gadget RepairTool = new("Repair Tool"); + public static readonly Gadget C4 = new("C4"); + public static readonly Gadget Claymore = new("Claymore"); + public static readonly Gadget M320SmokeGrenadeLauncher = new("M320 Smoke Grenade Launcher"); + public static readonly Gadget SmallAmmoKit = new("Small Ammo Kit"); + public static readonly Gadget AntiPersonnelMine = new("Anti Personnel Mine"); + public static readonly Gadget AntiVehicleMine = new("Anti Vehicle Mine"); + public static readonly Gadget MedicKit = new("Medic Kit"); + public static readonly Gadget Rpg7HeatExplosive = new("Rpg7 Heat Explosive"); + public static readonly Gadget RiotShield = new("Riot Shield"); + public static readonly Gadget FragGrenade = new("Frag Grenade"); + public static readonly Gadget ImpactGrenade = new("Impact Grenade"); + public static readonly Gadget AntiVehicleGrenade = new("Anti Vehicle Grenade"); + public static readonly Gadget SmokeGrenadeBlue = new("Smoke Grenade Blue"); + public static readonly Gadget SmokeGrenadeGreen = new("Smoke Grenade Green"); + public static readonly Gadget SmokeGrenadeRed = new("Smoke Grenade Red"); + public static readonly Gadget SmokeGrenadeWhite = new("Smoke Grenade White"); + public static readonly Gadget Flare = new("Flare"); + public static readonly Gadget SledgeHammer = new("Sledge Hammer"); + public static readonly Gadget AdvancedBinoculars = new("Advanced Binoculars"); + public static readonly Gadget Mdx201 = new("Mdx 201"); + public static readonly Gadget BinoSoflam = new("Bino Soflam"); + public static readonly Gadget HeavyAmmoKit = new("Heavy Ammo Kit"); + public static readonly Gadget Rpg7Pgo7Tandem = new("Rpg7 Pgo7 Tandem"); + public static readonly Gadget Rpg7Pgo7HeatExplosive = new("Rpg7 Pgo7 Heat Explosive"); + public static readonly Gadget Rpg7Pgo7Fragmentation = new("Rpg7 Pgo7 Fragmentation"); + public static readonly Gadget Rpg7Fragmentation = new("Rpg7 Fragmentation"); + public static readonly Gadget GrapplingHook = new("Grappling Hook"); + public static readonly Gadget AirDrone = new("Air Drone"); + public static readonly Gadget Flashbang = new("Flashbang"); + public static readonly Gadget Pickaxe = new("Pickaxe"); + public static readonly Gadget SuicideC4 = new("SuicideC4"); + public static readonly Gadget SledgeHammerSkinA = new("Sledge Hammer SkinA"); + public static readonly Gadget SledgeHammerSkinB = new("Sledge Hammer SkinB"); + public static readonly Gadget SledgeHammerSkinC = new("Sledge Hammer SkinC"); + public static readonly Gadget PickaxeIronPickaxe = new("Pickaxe IronPickaxe"); + + // ----- Init ----- + static Gadgets() { - // ----- Private Variables ----- - private static Dictionary mGadgets; - - // ----- Public Variables ----- - public static readonly Gadget Bandage = new Gadget("Bandage"); - public static readonly Gadget Binoculars = new Gadget("Binoculars"); - public static readonly Gadget RangeFinder = new Gadget("Range Finder"); - public static readonly Gadget RepairTool = new Gadget("Repair Tool"); - public static readonly Gadget C4 = new Gadget("C4"); - public static readonly Gadget Claymore = new Gadget("Claymore"); - public static readonly Gadget M320SmokeGrenadeLauncher = new Gadget("M320 Smoke Grenade Launcher"); - public static readonly Gadget SmallAmmoKit = new Gadget("Small Ammo Kit"); - public static readonly Gadget AntiPersonnelMine = new Gadget("Anti Personnel Mine"); - public static readonly Gadget AntiVehicleMine = new Gadget("Anti Vehicle Mine"); - public static readonly Gadget MedicKit = new Gadget("Medic Kit"); - public static readonly Gadget Rpg7HeatExplosive = new Gadget("Rpg7 Heat Explosive"); - public static readonly Gadget RiotShield = new Gadget("Riot Shield"); - public static readonly Gadget FragGrenade = new Gadget("Frag Grenade"); - public static readonly Gadget ImpactGrenade = new Gadget("Impact Grenade"); - public static readonly Gadget AntiVehicleGrenade = new Gadget("Anti Vehicle Grenade"); - public static readonly Gadget SmokeGrenadeBlue = new Gadget("Smoke Grenade Blue"); - public static readonly Gadget SmokeGrenadeGreen = new Gadget("Smoke Grenade Green"); - public static readonly Gadget SmokeGrenadeRed = new Gadget("Smoke Grenade Red"); - public static readonly Gadget SmokeGrenadeWhite = new Gadget("Smoke Grenade White"); - public static readonly Gadget Flare = new Gadget("Flare"); - public static readonly Gadget SledgeHammer = new Gadget("Sledge Hammer"); - public static readonly Gadget AdvancedBinoculars = new Gadget("Advanced Binoculars"); - public static readonly Gadget Mdx201 = new Gadget("Mdx 201"); - public static readonly Gadget BinoSoflam = new Gadget("Bino Soflam"); - public static readonly Gadget HeavyAmmoKit = new Gadget("Heavy Ammo Kit"); - public static readonly Gadget Rpg7Pgo7Tandem = new Gadget("Rpg7 Pgo7 Tandem"); - public static readonly Gadget Rpg7Pgo7HeatExplosive = new Gadget("Rpg7 Pgo7 Heat Explosive"); - public static readonly Gadget Rpg7Pgo7Fragmentation = new Gadget("Rpg7 Pgo7 Fragmentation"); - public static readonly Gadget Rpg7Fragmentation = new Gadget("Rpg7 Fragmentation"); - public static readonly Gadget GrapplingHook = new Gadget("Grappling Hook"); - public static readonly Gadget AirDrone = new Gadget("Air Drone"); - public static readonly Gadget Flashbang = new Gadget("Flashbang"); - public static readonly Gadget Pickaxe = new Gadget("Pickaxe"); - public static readonly Gadget SuicideC4 = new Gadget("SuicideC4"); - public static readonly Gadget SledgeHammerSkinA = new Gadget("Sledge Hammer SkinA"); - public static readonly Gadget SledgeHammerSkinB = new Gadget("Sledge Hammer SkinB"); - public static readonly Gadget SledgeHammerSkinC = new Gadget("Sledge Hammer SkinC"); - public static readonly Gadget PickaxeIronPickaxe = new Gadget("Pickaxe IronPickaxe"); - - // ----- Public Calls ----- - public static bool TryFind(string name, out Gadget item) - { - return mGadgets.TryGetValue(name, out item); - } - - // ----- Init ----- - static Gadgets() - { - var members = typeof(Gadgets).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); - mGadgets = new Dictionary(members.Length); - foreach (var memberInfo in members) + var members = typeof(Gadgets).GetMembers(BindingFlags.Public | BindingFlags.Static); + mGadgets = new Dictionary(members.Length); + foreach (var memberInfo in members) + if (memberInfo.MemberType == MemberTypes.Field) { - if (memberInfo.MemberType == System.Reflection.MemberTypes.Field) + var field = (FieldInfo)memberInfo; + if (field.FieldType == typeof(Gadget)) { - var field = ((FieldInfo)memberInfo); - if (field.FieldType == typeof(Gadget)) - { - var gad = (Gadget)field.GetValue(null); - mGadgets.Add(gad.Name, gad); - } + var gad = (Gadget)field.GetValue(null); + mGadgets.Add(gad.Name, gad); } } - } } -} + + // ----- Public Calls ----- + public static bool TryFind(string name, out Gadget item) + { + return mGadgets.TryGetValue(name, out item); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/Map.cs b/BattleBitAPI/Common/Data/Map.cs index b1d93ae..35bdd8b 100644 --- a/BattleBitAPI/Common/Data/Map.cs +++ b/BattleBitAPI/Common/Data/Map.cs @@ -1,69 +1,74 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public class Map : IEquatable, IEquatable { - public class Map : IEquatable, IEquatable + public Map(string name) { - public string Name { get; private set; } - public Map(string name) - { - Name = name; - } - - public override string ToString() - { - return this.Name; - } - public bool Equals(string other) - { - if (other == null) - return false; - return this.Name.Equals(other); - } - public bool Equals(Map other) - { - if (other == null) - return false; - return this.Name.Equals(other.Name); - } - - public static bool operator ==(string left, Map right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(string left, Map right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator ==(Map right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(Map right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } + Name = name; } -} + + public string Name { get; } + + public bool Equals(Map other) + { + if (other == null) + return false; + return Name.Equals(other.Name); + } + + public bool Equals(string other) + { + if (other == null) + return false; + return Name.Equals(other); + } + + public override string ToString() + { + return Name; + } + + public static bool operator ==(string left, Map right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(string left, Map right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator ==(Map right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(Map right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/PlayerLoadout.cs b/BattleBitAPI/Common/Data/PlayerLoadout.cs index c6f8a0e..ddcd3ea 100644 --- a/BattleBitAPI/Common/Data/PlayerLoadout.cs +++ b/BattleBitAPI/Common/Data/PlayerLoadout.cs @@ -1,348 +1,364 @@ -namespace BattleBitAPI.Common +using Stream = BattleBitAPI.Common.Serialization.Stream; + +namespace BattleBitAPI.Common; + +public struct PlayerLoadout { - public struct PlayerLoadout + public WeaponItem PrimaryWeapon; + public WeaponItem SecondaryWeapon; + public string FirstAidName; + public string LightGadgetName; + public string HeavyGadgetName; + public string ThrowableName; + + public byte PrimaryExtraMagazines; + public byte SecondaryExtraMagazines; + public byte FirstAidExtra; + public byte LightGadgetExtra; + public byte HeavyGadgetExtra; + public byte ThrowableExtra; + + public Gadget FirstAid { - public WeaponItem PrimaryWeapon; - public WeaponItem SecondaryWeapon; - public string FirstAidName; - public string LightGadgetName; - public string HeavyGadgetName; - public string ThrowableName; - - public byte PrimaryExtraMagazines; - public byte SecondaryExtraMagazines; - public byte FirstAidExtra; - public byte LightGadgetExtra; - public byte HeavyGadgetExtra; - public byte ThrowableExtra; - - public Gadget FirstAid + get { - get - { - if (Gadgets.TryFind(FirstAidName, out var gadget)) - return gadget; - return null; - } - set - { - if (value == null) - this.FirstAidName = "none"; - else - this.FirstAidName = value.Name; - } + if (Gadgets.TryFind(FirstAidName, out var gadget)) + return gadget; + return null; } - public Gadget LightGadget + set { - get - { - if (Gadgets.TryFind(LightGadgetName, out var gadget)) - return gadget; - return null; - } - set - { - if (value == null) - this.LightGadgetName = "none"; - else - this.LightGadgetName = value.Name; - } - } - public Gadget HeavyGadget - { - get - { - if (Gadgets.TryFind(HeavyGadgetName, out var gadget)) - return gadget; - return null; - } - set - { - if (value == null) - this.HeavyGadgetName = "none"; - else - this.HeavyGadgetName = value.Name; - } - } - public Gadget Throwable - { - get - { - if (Gadgets.TryFind(ThrowableName, out var gadget)) - return gadget; - return null; - } - set - { - if (value == null) - this.ThrowableName = "none"; - else - this.ThrowableName = value.Name; - } - } - - public bool HasGadget(Gadget gadget) - { - if (this.FirstAid == gadget) - return true; - if (this.LightGadget == gadget) - return true; - if (this.HeavyGadget == gadget) - return true; - if (this.Throwable == gadget) - return true; - return false; - } - - public void Write(Common.Serialization.Stream ser) - { - this.PrimaryWeapon.Write(ser); - this.SecondaryWeapon.Write(ser); - ser.WriteStringItem(this.FirstAidName); - ser.WriteStringItem(this.LightGadgetName); - ser.WriteStringItem(this.HeavyGadgetName); - ser.WriteStringItem(this.ThrowableName); - - ser.Write(this.PrimaryExtraMagazines); - ser.Write(this.SecondaryExtraMagazines); - ser.Write(this.FirstAidExtra); - ser.Write(this.LightGadgetExtra); - ser.Write(this.HeavyGadgetExtra); - ser.Write(this.ThrowableExtra); - } - public void Read(Common.Serialization.Stream ser) - { - this.PrimaryWeapon.Read(ser); - this.SecondaryWeapon.Read(ser); - ser.TryReadString(out this.FirstAidName); - ser.TryReadString(out this.LightGadgetName); - ser.TryReadString(out this.HeavyGadgetName); - ser.TryReadString(out this.ThrowableName); - - this.PrimaryExtraMagazines = ser.ReadInt8(); - this.SecondaryExtraMagazines = ser.ReadInt8(); - this.FirstAidExtra = ser.ReadInt8(); - this.LightGadgetExtra = ser.ReadInt8(); - this.HeavyGadgetExtra = ser.ReadInt8(); - this.ThrowableExtra = ser.ReadInt8(); + if (value == null) + FirstAidName = "none"; + else + FirstAidName = value.Name; } } - public struct WeaponItem + + public Gadget LightGadget { - public string ToolName; - public string MainSightName; - public string TopSightName; - public string CantedSightName; - public string BarrelName; - public string SideRailName; - public string UnderRailName; - public string BoltActionName; - public byte SkinIndex; - public byte MagazineIndex; + get + { + if (Gadgets.TryFind(LightGadgetName, out var gadget)) + return gadget; + return null; + } + set + { + if (value == null) + LightGadgetName = "none"; + else + LightGadgetName = value.Name; + } + } - public Weapon Tool + public Gadget HeavyGadget + { + get { - get - { - if (Weapons.TryFind(ToolName, out var weapon)) - return weapon; - return null; - } - set - { - if (value == null) - this.ToolName = "none"; - else - this.ToolName = value.Name; - } + if (Gadgets.TryFind(HeavyGadgetName, out var gadget)) + return gadget; + return null; } - public Attachment MainSight + set { - get - { - if (Attachments.TryFind(MainSightName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.MainSightName = "none"; - else - this.MainSightName = value.Name; - } - } - public Attachment TopSight - { - get - { - if (Attachments.TryFind(TopSightName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.TopSightName = "none"; - else - this.TopSightName = value.Name; - } - } - public Attachment CantedSight - { - get - { - if (Attachments.TryFind(CantedSightName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.CantedSightName = "none"; - else - this.CantedSightName = value.Name; - } - } - public Attachment Barrel - { - get - { - if (Attachments.TryFind(BarrelName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.BarrelName = "none"; - else - this.BarrelName = value.Name; - } - } - public Attachment SideRail - { - get - { - if (Attachments.TryFind(SideRailName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.SideRailName = "none"; - else - this.SideRailName = value.Name; - } - } - public Attachment UnderRail - { - get - { - if (Attachments.TryFind(UnderRailName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.UnderRailName = "none"; - else - this.UnderRailName = value.Name; - } - } - public Attachment BoltAction - { - get - { - if (Attachments.TryFind(BoltActionName, out var attachment)) - return attachment; - return null; - } - set - { - if (value == null) - this.BoltActionName = "none"; - else - this.BoltActionName = value.Name; - } + if (value == null) + HeavyGadgetName = "none"; + else + HeavyGadgetName = value.Name; } + } - public bool HasAttachment(Attachment attachment) + public Gadget Throwable + { + get { - switch (attachment.AttachmentType) - { - case AttachmentType.MainSight: - return this.MainSight == attachment; - case AttachmentType.TopSight: - return this.TopSight == attachment; - case AttachmentType.CantedSight: - return this.CantedSight == attachment; - case AttachmentType.Barrel: - return this.Barrel == attachment; - case AttachmentType.UnderRail: - return this.Barrel == attachment; - case AttachmentType.SideRail: - return this.SideRail == attachment; - case AttachmentType.Bolt: - return this.BoltAction == attachment; - } - return false; + if (Gadgets.TryFind(ThrowableName, out var gadget)) + return gadget; + return null; } - public void SetAttachment(Attachment attachment) + set { - switch (attachment.AttachmentType) - { - case AttachmentType.MainSight: - this.MainSight = attachment; - break; - case AttachmentType.TopSight: - this.TopSight = attachment; - break; - case AttachmentType.CantedSight: - this.CantedSight = attachment; - break; - case AttachmentType.Barrel: - this.Barrel = attachment; - break; - case AttachmentType.UnderRail: - this.Barrel = attachment; - break; - case AttachmentType.SideRail: - this.SideRail = attachment; - break; - case AttachmentType.Bolt: - this.BoltAction = attachment; - break; - } + if (value == null) + ThrowableName = "none"; + else + ThrowableName = value.Name; } + } - public void Write(Common.Serialization.Stream ser) - { - ser.WriteStringItem(this.ToolName); - ser.WriteStringItem(this.MainSightName); - ser.WriteStringItem(this.TopSightName); - ser.WriteStringItem(this.CantedSightName); - ser.WriteStringItem(this.BarrelName); - ser.WriteStringItem(this.SideRailName); - ser.WriteStringItem(this.UnderRailName); - ser.WriteStringItem(this.BoltActionName); - ser.Write(this.SkinIndex); - ser.Write(this.MagazineIndex); - } - public void Read(Common.Serialization.Stream ser) - { - ser.TryReadString(out this.ToolName); - ser.TryReadString(out this.MainSightName); - ser.TryReadString(out this.TopSightName); - ser.TryReadString(out this.CantedSightName); - ser.TryReadString(out this.BarrelName); - ser.TryReadString(out this.SideRailName); - ser.TryReadString(out this.UnderRailName); - ser.TryReadString(out this.BoltActionName); - this.SkinIndex = ser.ReadInt8(); - this.MagazineIndex = ser.ReadInt8(); - } + public bool HasGadget(Gadget gadget) + { + if (FirstAid == gadget) + return true; + if (LightGadget == gadget) + return true; + if (HeavyGadget == gadget) + return true; + if (Throwable == gadget) + return true; + return false; + } + + public void Write(Stream ser) + { + PrimaryWeapon.Write(ser); + SecondaryWeapon.Write(ser); + ser.WriteStringItem(FirstAidName); + ser.WriteStringItem(LightGadgetName); + ser.WriteStringItem(HeavyGadgetName); + ser.WriteStringItem(ThrowableName); + + ser.Write(PrimaryExtraMagazines); + ser.Write(SecondaryExtraMagazines); + ser.Write(FirstAidExtra); + ser.Write(LightGadgetExtra); + ser.Write(HeavyGadgetExtra); + ser.Write(ThrowableExtra); + } + + public void Read(Stream ser) + { + PrimaryWeapon.Read(ser); + SecondaryWeapon.Read(ser); + ser.TryReadString(out FirstAidName); + ser.TryReadString(out LightGadgetName); + ser.TryReadString(out HeavyGadgetName); + ser.TryReadString(out ThrowableName); + + PrimaryExtraMagazines = ser.ReadInt8(); + SecondaryExtraMagazines = ser.ReadInt8(); + FirstAidExtra = ser.ReadInt8(); + LightGadgetExtra = ser.ReadInt8(); + HeavyGadgetExtra = ser.ReadInt8(); + ThrowableExtra = ser.ReadInt8(); } } + +public struct WeaponItem +{ + public string ToolName; + public string MainSightName; + public string TopSightName; + public string CantedSightName; + public string BarrelName; + public string SideRailName; + public string UnderRailName; + public string BoltActionName; + public byte SkinIndex; + public byte MagazineIndex; + + public Weapon Tool + { + get + { + if (Weapons.TryFind(ToolName, out var weapon)) + return weapon; + return null; + } + set + { + if (value == null) + ToolName = "none"; + else + ToolName = value.Name; + } + } + + public Attachment MainSight + { + get + { + if (Attachments.TryFind(MainSightName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + MainSightName = "none"; + else + MainSightName = value.Name; + } + } + + public Attachment TopSight + { + get + { + if (Attachments.TryFind(TopSightName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + TopSightName = "none"; + else + TopSightName = value.Name; + } + } + + public Attachment CantedSight + { + get + { + if (Attachments.TryFind(CantedSightName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + CantedSightName = "none"; + else + CantedSightName = value.Name; + } + } + + public Attachment Barrel + { + get + { + if (Attachments.TryFind(BarrelName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + BarrelName = "none"; + else + BarrelName = value.Name; + } + } + + public Attachment SideRail + { + get + { + if (Attachments.TryFind(SideRailName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + SideRailName = "none"; + else + SideRailName = value.Name; + } + } + + public Attachment UnderRail + { + get + { + if (Attachments.TryFind(UnderRailName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + UnderRailName = "none"; + else + UnderRailName = value.Name; + } + } + + public Attachment BoltAction + { + get + { + if (Attachments.TryFind(BoltActionName, out var attachment)) + return attachment; + return null; + } + set + { + if (value == null) + BoltActionName = "none"; + else + BoltActionName = value.Name; + } + } + + public bool HasAttachment(Attachment attachment) + { + switch (attachment.AttachmentType) + { + case AttachmentType.MainSight: + return MainSight == attachment; + case AttachmentType.TopSight: + return TopSight == attachment; + case AttachmentType.CantedSight: + return CantedSight == attachment; + case AttachmentType.Barrel: + return Barrel == attachment; + case AttachmentType.UnderRail: + return Barrel == attachment; + case AttachmentType.SideRail: + return SideRail == attachment; + case AttachmentType.Bolt: + return BoltAction == attachment; + } + + return false; + } + + public void SetAttachment(Attachment attachment) + { + switch (attachment.AttachmentType) + { + case AttachmentType.MainSight: + MainSight = attachment; + break; + case AttachmentType.TopSight: + TopSight = attachment; + break; + case AttachmentType.CantedSight: + CantedSight = attachment; + break; + case AttachmentType.Barrel: + Barrel = attachment; + break; + case AttachmentType.UnderRail: + Barrel = attachment; + break; + case AttachmentType.SideRail: + SideRail = attachment; + break; + case AttachmentType.Bolt: + BoltAction = attachment; + break; + } + } + + public void Write(Stream ser) + { + ser.WriteStringItem(ToolName); + ser.WriteStringItem(MainSightName); + ser.WriteStringItem(TopSightName); + ser.WriteStringItem(CantedSightName); + ser.WriteStringItem(BarrelName); + ser.WriteStringItem(SideRailName); + ser.WriteStringItem(UnderRailName); + ser.WriteStringItem(BoltActionName); + ser.Write(SkinIndex); + ser.Write(MagazineIndex); + } + + public void Read(Stream ser) + { + ser.TryReadString(out ToolName); + ser.TryReadString(out MainSightName); + ser.TryReadString(out TopSightName); + ser.TryReadString(out CantedSightName); + ser.TryReadString(out BarrelName); + ser.TryReadString(out SideRailName); + ser.TryReadString(out UnderRailName); + ser.TryReadString(out BoltActionName); + SkinIndex = ser.ReadInt8(); + MagazineIndex = ser.ReadInt8(); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/PlayerStats.cs b/BattleBitAPI/Common/Data/PlayerStats.cs index b649407..2a75a84 100644 --- a/BattleBitAPI/Common/Data/PlayerStats.cs +++ b/BattleBitAPI/Common/Data/PlayerStats.cs @@ -1,326 +1,342 @@ -namespace BattleBitAPI.Common +using Stream = BattleBitAPI.Common.Serialization.Stream; + +namespace BattleBitAPI.Common; + +public class PlayerStats { - public class PlayerStats + public byte[] Achievements; + + public bool IsBanned; + public PlayerProgess Progress = new(); + public Roles Roles; + public byte[] Selections; + public byte[] ToolProgress; + + public PlayerStats() { - public PlayerStats() { } - public PlayerStats(byte[] data) { Load(data); } + } - public bool IsBanned; - public Roles Roles; - public PlayerProgess Progress = new PlayerProgess(); - public byte[] ToolProgress; - public byte[] Achievements; - public byte[] Selections; + public PlayerStats(byte[] data) + { + Load(data); + } - public void Write(Common.Serialization.Stream ser) + public void Write(Stream ser) + { + ser.Write(IsBanned); + ser.Write((ulong)Roles); + + Progress.Write(ser); + + if (ToolProgress != null) { - ser.Write(this.IsBanned); - ser.Write((ulong)this.Roles); - - Progress.Write(ser); - - if (ToolProgress != null) - { - ser.Write((ushort)ToolProgress.Length); - ser.Write(ToolProgress, 0, ToolProgress.Length); - } - else - { - ser.Write((ushort)0); - } - - if (Achievements != null) - { - ser.Write((ushort)Achievements.Length); - ser.Write(Achievements, 0, Achievements.Length); - } - else - { - ser.Write((ushort)0); - } - - if (Selections != null) - { - ser.Write((ushort)Selections.Length); - ser.Write(Selections, 0, Selections.Length); - } - else - { - ser.Write((ushort)0); - } + ser.Write((ushort)ToolProgress.Length); + ser.Write(ToolProgress, 0, ToolProgress.Length); } - public void Read(Common.Serialization.Stream ser) + else { - this.IsBanned = ser.ReadBool(); - this.Roles = (Roles)ser.ReadUInt64(); - - this.Progress.Read(ser); - - int size = ser.ReadInt16(); - this.ToolProgress = ser.ReadByteArray(size); - - size = ser.ReadInt16(); - this.Achievements = ser.ReadByteArray(size); - - size = ser.ReadInt16(); - this.Selections = ser.ReadByteArray(size); + ser.Write((ushort)0); } - public byte[] SerializeToByteArray() + if (Achievements != null) { - using (var ser = Common.Serialization.Stream.Get()) - { - Write(ser); - return ser.AsByteArrayData(); - } + ser.Write((ushort)Achievements.Length); + ser.Write(Achievements, 0, Achievements.Length); } - public void Load(byte[] data) + else { - var ser = new Common.Serialization.Stream() - { - Buffer = data, - InPool = false, - ReadPosition = 0, - WritePosition = data.Length, - }; - Read(ser); + ser.Write((ushort)0); } - public class PlayerProgess + if (Selections != null) { - private const uint ParamCount = 42; - - public uint KillCount; - public uint LeaderKills; - public uint AssaultKills; - public uint MedicKills; - public uint EngineerKills; - public uint SupportKills; - public uint ReconKills; - public uint DeathCount; - public uint WinCount; - public uint LoseCount; - public uint FriendlyShots; - public uint FriendlyKills; - public uint Revived; - public uint RevivedTeamMates; - public uint Assists; - public uint Prestige; - public uint Rank; - public uint EXP; - public uint ShotsFired; - public uint ShotsHit; - public uint Headshots; - public uint ObjectivesComplated; - public uint HealedHPs; - public uint RoadKills; - public uint Suicides; - public uint VehiclesDestroyed; - public uint VehicleHPRepaired; - public uint LongestKill; - public uint PlayTimeSeconds; - public uint LeaderPlayTime; - public uint AssaultPlayTime; - public uint MedicPlayTime; - public uint EngineerPlayTime; - public uint SupportPlayTime; - public uint ReconPlayTime; - public uint LeaderScore; - public uint AssaultScore; - public uint MedicScore; - public uint EngineerScore; - public uint SupportScore; - public uint ReconScore; - public uint TotalScore; - - public void Write(Common.Serialization.Stream ser) - { - ser.Write(ParamCount); - { - ser.Write(KillCount); - ser.Write(LeaderKills); - ser.Write(AssaultKills); - ser.Write(MedicKills); - ser.Write(EngineerKills); - ser.Write(SupportKills); - ser.Write(ReconKills); - ser.Write(DeathCount); - ser.Write(WinCount); - ser.Write(LoseCount); - ser.Write(FriendlyShots); - ser.Write(FriendlyKills); - ser.Write(Revived); - ser.Write(RevivedTeamMates); - ser.Write(Assists); - ser.Write(Prestige); - ser.Write(Rank); - ser.Write(EXP); - ser.Write(ShotsFired); - ser.Write(ShotsHit); - ser.Write(Headshots); - ser.Write(ObjectivesComplated); - ser.Write(HealedHPs); - ser.Write(RoadKills); - ser.Write(Suicides); - ser.Write(VehiclesDestroyed); - ser.Write(VehicleHPRepaired); - ser.Write(LongestKill); - ser.Write(PlayTimeSeconds); - ser.Write(LeaderPlayTime); - ser.Write(AssaultPlayTime); - ser.Write(MedicPlayTime); - ser.Write(EngineerPlayTime); - ser.Write(SupportPlayTime); - ser.Write(ReconPlayTime); - ser.Write(LeaderScore); - ser.Write(AssaultScore); - ser.Write(MedicScore); - ser.Write(EngineerScore); - ser.Write(SupportScore); - ser.Write(ReconScore); - ser.Write(TotalScore); - } - } - public void Read(Common.Serialization.Stream ser) - { - Reset(); - - uint mParamCount = ser.ReadUInt32(); - int maxReadPosition = ser.ReadPosition + (int)(mParamCount * 4); - { - bool canRead() => ser.ReadPosition < maxReadPosition; - if (canRead()) - this.KillCount = ser.ReadUInt32(); - if (canRead()) - this.LeaderKills = ser.ReadUInt32(); - if (canRead()) - this.AssaultKills = ser.ReadUInt32(); - if (canRead()) - this.MedicKills = ser.ReadUInt32(); - if (canRead()) - this.EngineerKills = ser.ReadUInt32(); - if (canRead()) - this.SupportKills = ser.ReadUInt32(); - if (canRead()) - this.ReconKills = ser.ReadUInt32(); - if (canRead()) - this.DeathCount = ser.ReadUInt32(); - if (canRead()) - this.WinCount = ser.ReadUInt32(); - if (canRead()) - this.LoseCount = ser.ReadUInt32(); - if (canRead()) - this.FriendlyShots = ser.ReadUInt32(); - if (canRead()) - this.FriendlyKills = ser.ReadUInt32(); - if (canRead()) - this.Revived = ser.ReadUInt32(); - if (canRead()) - this.RevivedTeamMates = ser.ReadUInt32(); - if (canRead()) - this.Assists = ser.ReadUInt32(); - if (canRead()) - this.Prestige = ser.ReadUInt32(); - if (canRead()) - this.Rank = ser.ReadUInt32(); - if (canRead()) - this.EXP = ser.ReadUInt32(); - if (canRead()) - this.ShotsFired = ser.ReadUInt32(); - if (canRead()) - this.ShotsHit = ser.ReadUInt32(); - if (canRead()) - this.Headshots = ser.ReadUInt32(); - if (canRead()) - this.ObjectivesComplated = ser.ReadUInt32(); - if (canRead()) - this.HealedHPs = ser.ReadUInt32(); - if (canRead()) - this.RoadKills = ser.ReadUInt32(); - if (canRead()) - this.Suicides = ser.ReadUInt32(); - if (canRead()) - this.VehiclesDestroyed = ser.ReadUInt32(); - if (canRead()) - this.VehicleHPRepaired = ser.ReadUInt32(); - if (canRead()) - this.LongestKill = ser.ReadUInt32(); - if (canRead()) - this.PlayTimeSeconds = ser.ReadUInt32(); - if (canRead()) - this.LeaderPlayTime = ser.ReadUInt32(); - if (canRead()) - this.AssaultPlayTime = ser.ReadUInt32(); - if (canRead()) - this.MedicPlayTime = ser.ReadUInt32(); - if (canRead()) - this.EngineerPlayTime = ser.ReadUInt32(); - if (canRead()) - this.SupportPlayTime = ser.ReadUInt32(); - if (canRead()) - this.ReconPlayTime = ser.ReadUInt32(); - if (canRead()) - this.LeaderScore = ser.ReadUInt32(); - if (canRead()) - this.AssaultScore = ser.ReadUInt32(); - if (canRead()) - this.MedicScore = ser.ReadUInt32(); - if (canRead()) - this.EngineerScore = ser.ReadUInt32(); - if (canRead()) - this.SupportScore = ser.ReadUInt32(); - if (canRead()) - this.ReconScore = ser.ReadUInt32(); - if (canRead()) - this.TotalScore = ser.ReadUInt32(); - } - ser.ReadPosition = maxReadPosition; - } - public void Reset() - { - KillCount = 0; - LeaderKills = 0; - AssaultKills = 0; - MedicKills = 0; - EngineerKills = 0; - SupportKills = 0; - ReconKills = 0; - DeathCount = 0; - WinCount = 0; - LoseCount = 0; - FriendlyShots = 0; - FriendlyKills = 0; - Revived = 0; - RevivedTeamMates = 0; - Assists = 0; - Prestige = 0; - Rank = 0; - EXP = 0; - ShotsFired = 0; - ShotsHit = 0; - Headshots = 0; - ObjectivesComplated = 0; - HealedHPs = 0; - RoadKills = 0; - Suicides = 0; - VehiclesDestroyed = 0; - VehicleHPRepaired = 0; - LongestKill = 0; - PlayTimeSeconds = 0; - LeaderPlayTime = 0; - AssaultPlayTime = 0; - MedicPlayTime = 0; - EngineerPlayTime = 0; - SupportPlayTime = 0; - ReconPlayTime = 0; - LeaderScore = 0; - AssaultScore = 0; - MedicScore = 0; - EngineerScore = 0; - SupportScore = 0; - ReconScore = 0; - TotalScore = 0; - } + ser.Write((ushort)Selections.Length); + ser.Write(Selections, 0, Selections.Length); + } + else + { + ser.Write((ushort)0); } } -} + + public void Read(Stream ser) + { + IsBanned = ser.ReadBool(); + Roles = (Roles)ser.ReadUInt64(); + + Progress.Read(ser); + + int size = ser.ReadInt16(); + ToolProgress = ser.ReadByteArray(size); + + size = ser.ReadInt16(); + Achievements = ser.ReadByteArray(size); + + size = ser.ReadInt16(); + Selections = ser.ReadByteArray(size); + } + + public byte[] SerializeToByteArray() + { + using (var ser = Stream.Get()) + { + Write(ser); + return ser.AsByteArrayData(); + } + } + + public void Load(byte[] data) + { + var ser = new Stream + { + Buffer = data, + InPool = false, + ReadPosition = 0, + WritePosition = data.Length + }; + Read(ser); + } + + public class PlayerProgess + { + private const uint ParamCount = 42; + public uint AssaultKills; + public uint AssaultPlayTime; + public uint AssaultScore; + public uint Assists; + public uint DeathCount; + public uint EngineerKills; + public uint EngineerPlayTime; + public uint EngineerScore; + public uint EXP; + public uint FriendlyKills; + public uint FriendlyShots; + public uint Headshots; + public uint HealedHPs; + + public uint KillCount; + public uint LeaderKills; + public uint LeaderPlayTime; + public uint LeaderScore; + public uint LongestKill; + public uint LoseCount; + public uint MedicKills; + public uint MedicPlayTime; + public uint MedicScore; + public uint ObjectivesComplated; + public uint PlayTimeSeconds; + public uint Prestige; + public uint Rank; + public uint ReconKills; + public uint ReconPlayTime; + public uint ReconScore; + public uint Revived; + public uint RevivedTeamMates; + public uint RoadKills; + public uint ShotsFired; + public uint ShotsHit; + public uint Suicides; + public uint SupportKills; + public uint SupportPlayTime; + public uint SupportScore; + public uint TotalScore; + public uint VehicleHPRepaired; + public uint VehiclesDestroyed; + public uint WinCount; + + public void Write(Stream ser) + { + ser.Write(ParamCount); + { + ser.Write(KillCount); + ser.Write(LeaderKills); + ser.Write(AssaultKills); + ser.Write(MedicKills); + ser.Write(EngineerKills); + ser.Write(SupportKills); + ser.Write(ReconKills); + ser.Write(DeathCount); + ser.Write(WinCount); + ser.Write(LoseCount); + ser.Write(FriendlyShots); + ser.Write(FriendlyKills); + ser.Write(Revived); + ser.Write(RevivedTeamMates); + ser.Write(Assists); + ser.Write(Prestige); + ser.Write(Rank); + ser.Write(EXP); + ser.Write(ShotsFired); + ser.Write(ShotsHit); + ser.Write(Headshots); + ser.Write(ObjectivesComplated); + ser.Write(HealedHPs); + ser.Write(RoadKills); + ser.Write(Suicides); + ser.Write(VehiclesDestroyed); + ser.Write(VehicleHPRepaired); + ser.Write(LongestKill); + ser.Write(PlayTimeSeconds); + ser.Write(LeaderPlayTime); + ser.Write(AssaultPlayTime); + ser.Write(MedicPlayTime); + ser.Write(EngineerPlayTime); + ser.Write(SupportPlayTime); + ser.Write(ReconPlayTime); + ser.Write(LeaderScore); + ser.Write(AssaultScore); + ser.Write(MedicScore); + ser.Write(EngineerScore); + ser.Write(SupportScore); + ser.Write(ReconScore); + ser.Write(TotalScore); + } + } + + public void Read(Stream ser) + { + Reset(); + + var mParamCount = ser.ReadUInt32(); + var maxReadPosition = ser.ReadPosition + (int)(mParamCount * 4); + { + bool canRead() + { + return ser.ReadPosition < maxReadPosition; + } + + if (canRead()) + KillCount = ser.ReadUInt32(); + if (canRead()) + LeaderKills = ser.ReadUInt32(); + if (canRead()) + AssaultKills = ser.ReadUInt32(); + if (canRead()) + MedicKills = ser.ReadUInt32(); + if (canRead()) + EngineerKills = ser.ReadUInt32(); + if (canRead()) + SupportKills = ser.ReadUInt32(); + if (canRead()) + ReconKills = ser.ReadUInt32(); + if (canRead()) + DeathCount = ser.ReadUInt32(); + if (canRead()) + WinCount = ser.ReadUInt32(); + if (canRead()) + LoseCount = ser.ReadUInt32(); + if (canRead()) + FriendlyShots = ser.ReadUInt32(); + if (canRead()) + FriendlyKills = ser.ReadUInt32(); + if (canRead()) + Revived = ser.ReadUInt32(); + if (canRead()) + RevivedTeamMates = ser.ReadUInt32(); + if (canRead()) + Assists = ser.ReadUInt32(); + if (canRead()) + Prestige = ser.ReadUInt32(); + if (canRead()) + Rank = ser.ReadUInt32(); + if (canRead()) + EXP = ser.ReadUInt32(); + if (canRead()) + ShotsFired = ser.ReadUInt32(); + if (canRead()) + ShotsHit = ser.ReadUInt32(); + if (canRead()) + Headshots = ser.ReadUInt32(); + if (canRead()) + ObjectivesComplated = ser.ReadUInt32(); + if (canRead()) + HealedHPs = ser.ReadUInt32(); + if (canRead()) + RoadKills = ser.ReadUInt32(); + if (canRead()) + Suicides = ser.ReadUInt32(); + if (canRead()) + VehiclesDestroyed = ser.ReadUInt32(); + if (canRead()) + VehicleHPRepaired = ser.ReadUInt32(); + if (canRead()) + LongestKill = ser.ReadUInt32(); + if (canRead()) + PlayTimeSeconds = ser.ReadUInt32(); + if (canRead()) + LeaderPlayTime = ser.ReadUInt32(); + if (canRead()) + AssaultPlayTime = ser.ReadUInt32(); + if (canRead()) + MedicPlayTime = ser.ReadUInt32(); + if (canRead()) + EngineerPlayTime = ser.ReadUInt32(); + if (canRead()) + SupportPlayTime = ser.ReadUInt32(); + if (canRead()) + ReconPlayTime = ser.ReadUInt32(); + if (canRead()) + LeaderScore = ser.ReadUInt32(); + if (canRead()) + AssaultScore = ser.ReadUInt32(); + if (canRead()) + MedicScore = ser.ReadUInt32(); + if (canRead()) + EngineerScore = ser.ReadUInt32(); + if (canRead()) + SupportScore = ser.ReadUInt32(); + if (canRead()) + ReconScore = ser.ReadUInt32(); + if (canRead()) + TotalScore = ser.ReadUInt32(); + } + ser.ReadPosition = maxReadPosition; + } + + public void Reset() + { + KillCount = 0; + LeaderKills = 0; + AssaultKills = 0; + MedicKills = 0; + EngineerKills = 0; + SupportKills = 0; + ReconKills = 0; + DeathCount = 0; + WinCount = 0; + LoseCount = 0; + FriendlyShots = 0; + FriendlyKills = 0; + Revived = 0; + RevivedTeamMates = 0; + Assists = 0; + Prestige = 0; + Rank = 0; + EXP = 0; + ShotsFired = 0; + ShotsHit = 0; + Headshots = 0; + ObjectivesComplated = 0; + HealedHPs = 0; + RoadKills = 0; + Suicides = 0; + VehiclesDestroyed = 0; + VehicleHPRepaired = 0; + LongestKill = 0; + PlayTimeSeconds = 0; + LeaderPlayTime = 0; + AssaultPlayTime = 0; + MedicPlayTime = 0; + EngineerPlayTime = 0; + SupportPlayTime = 0; + ReconPlayTime = 0; + LeaderScore = 0; + AssaultScore = 0; + MedicScore = 0; + EngineerScore = 0; + SupportScore = 0; + ReconScore = 0; + TotalScore = 0; + } + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/PlayerWearings.cs b/BattleBitAPI/Common/Data/PlayerWearings.cs index aa043cb..de258e3 100644 --- a/BattleBitAPI/Common/Data/PlayerWearings.cs +++ b/BattleBitAPI/Common/Data/PlayerWearings.cs @@ -1,43 +1,45 @@ -namespace BattleBitAPI.Common -{ - public struct PlayerWearings - { - public string Head; - public string Chest; - public string Belt; - public string Backbag; - public string Eye; - public string Face; - public string Hair; - public string Skin; - public string Uniform; - public string Camo; +using Stream = BattleBitAPI.Common.Serialization.Stream; - public void Write(Common.Serialization.Stream ser) - { - ser.WriteStringItem(this.Head); - ser.WriteStringItem(this.Chest); - ser.WriteStringItem(this.Belt); - ser.WriteStringItem(this.Backbag); - ser.WriteStringItem(this.Eye); - ser.WriteStringItem(this.Face); - ser.WriteStringItem(this.Hair); - ser.WriteStringItem(this.Skin); - ser.WriteStringItem(this.Uniform); - ser.WriteStringItem(this.Camo); - } - public void Read(Common.Serialization.Stream ser) - { - ser.TryReadString(out this.Head); - ser.TryReadString(out this.Chest); - ser.TryReadString(out this.Belt); - ser.TryReadString(out this.Backbag); - ser.TryReadString(out this.Eye); - ser.TryReadString(out this.Face); - ser.TryReadString(out this.Hair); - ser.TryReadString(out this.Skin); - ser.TryReadString(out this.Uniform); - ser.TryReadString(out this.Camo); - } +namespace BattleBitAPI.Common; + +public struct PlayerWearings +{ + public string Head; + public string Chest; + public string Belt; + public string Backbag; + public string Eye; + public string Face; + public string Hair; + public string Skin; + public string Uniform; + public string Camo; + + public void Write(Stream ser) + { + ser.WriteStringItem(Head); + ser.WriteStringItem(Chest); + ser.WriteStringItem(Belt); + ser.WriteStringItem(Backbag); + ser.WriteStringItem(Eye); + ser.WriteStringItem(Face); + ser.WriteStringItem(Hair); + ser.WriteStringItem(Skin); + ser.WriteStringItem(Uniform); + ser.WriteStringItem(Camo); } -} + + public void Read(Stream ser) + { + ser.TryReadString(out Head); + ser.TryReadString(out Chest); + ser.TryReadString(out Belt); + ser.TryReadString(out Backbag); + ser.TryReadString(out Eye); + ser.TryReadString(out Face); + ser.TryReadString(out Hair); + ser.TryReadString(out Skin); + ser.TryReadString(out Uniform); + ser.TryReadString(out Camo); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Data/Weapon.cs b/BattleBitAPI/Common/Data/Weapon.cs index 751a58d..232bcec 100644 --- a/BattleBitAPI/Common/Data/Weapon.cs +++ b/BattleBitAPI/Common/Data/Weapon.cs @@ -1,73 +1,76 @@ -using System; +namespace BattleBitAPI.Common; -namespace BattleBitAPI.Common +public class Weapon : IEquatable, IEquatable { - public class Weapon : IEquatable, IEquatable + public Weapon(string name, WeaponType weaponType) { - public string Name { get; private set; } - public WeaponType WeaponType { get; private set; } - public Weapon(string name, WeaponType weaponType) - { - Name = name; - WeaponType = weaponType; - } + Name = name; + WeaponType = weaponType; + } - public override string ToString() - { - return this.Name; - } - public bool Equals(string other) - { - if (other == null) - return false; - return this.Name.Equals(other); - } - public bool Equals(Weapon other) - { - if (other == null) - return false; - return this.Name.Equals(other.Name); - } + public string Name { get; } + public WeaponType WeaponType { get; private set; } - public static bool operator ==(string left, Weapon right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(string left, Weapon right) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator ==(Weapon right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } - public static bool operator !=(Weapon right, string left) - { - bool leftNull = object.ReferenceEquals(left, null); - bool rightNull = object.ReferenceEquals(right, null); - if (leftNull && rightNull) - return true; - if (leftNull || rightNull) - return false; - return right.Name.Equals(left); - } + public bool Equals(string other) + { + if (other == null) + return false; + return Name.Equals(other); + } + + public bool Equals(Weapon other) + { + if (other == null) + return false; + return Name.Equals(other.Name); + } + + public override string ToString() + { + return Name; + } + + public static bool operator ==(string left, Weapon right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(string left, Weapon right) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator ==(Weapon right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); + } + + public static bool operator !=(Weapon right, string left) + { + var leftNull = ReferenceEquals(left, null); + var rightNull = ReferenceEquals(right, null); + if (leftNull && rightNull) + return true; + if (leftNull || rightNull) + return false; + return right.Name.Equals(left); } } \ No newline at end of file diff --git a/BattleBitAPI/Common/Datasets/Attachments.cs b/BattleBitAPI/Common/Datasets/Attachments.cs index 63fbeb9..88dc06d 100644 --- a/BattleBitAPI/Common/Datasets/Attachments.cs +++ b/BattleBitAPI/Common/Datasets/Attachments.cs @@ -1,127 +1,124 @@ using System.Reflection; -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public static class Attachments { - public static class Attachments + // ----- Private Variables ----- + private static readonly Dictionary mAttachments; + + // ----- Barrels ----- + public static readonly Attachment Basic = new("Basic", AttachmentType.Barrel); + public static readonly Attachment Compensator = new("Compensator", AttachmentType.Barrel); + public static readonly Attachment Heavy = new("Heavy", AttachmentType.Barrel); + public static readonly Attachment LongBarrel = new("Long_Barrel", AttachmentType.Barrel); + public static readonly Attachment MuzzleBreak = new("Muzzle_Break", AttachmentType.Barrel); + public static readonly Attachment Ranger = new("Ranger", AttachmentType.Barrel); + public static readonly Attachment SuppressorLong = new("Suppressor_Long", AttachmentType.Barrel); + public static readonly Attachment SuppressorShort = new("Suppressor_Short", AttachmentType.Barrel); + public static readonly Attachment Tactical = new("Tactical", AttachmentType.Barrel); + public static readonly Attachment FlashHider = new("Flash_Hider", AttachmentType.Barrel); + public static readonly Attachment Osprey9 = new("Osprey_9", AttachmentType.Barrel); + public static readonly Attachment DGN308 = new("DGN-308", AttachmentType.Barrel); + public static readonly Attachment VAMB762 = new("VAMB-762", AttachmentType.Barrel); + public static readonly Attachment SDN6762 = new("SDN-6_762", AttachmentType.Barrel); + public static readonly Attachment NT4556 = new("NT-4_556", AttachmentType.Barrel); + + // ----- Canted Sights ----- + public static readonly Attachment Ironsight = new("Ironsight", AttachmentType.CantedSight); + public static readonly Attachment CantedRedDot = new("Canted_Red_Dot", AttachmentType.CantedSight); + public static readonly Attachment FYouCanted = new("FYou_Canted", AttachmentType.CantedSight); + public static readonly Attachment HoloDot = new("Holo_Dot", AttachmentType.CantedSight); + + // ----- Scope ----- + public static readonly Attachment _6xScope = new("6x_Scope", AttachmentType.MainSight); + public static readonly Attachment _8xScope = new("8x_Scope", AttachmentType.MainSight); + public static readonly Attachment _15xScope = new("15x_Scope", AttachmentType.MainSight); + public static readonly Attachment _20xScope = new("20x_Scope", AttachmentType.MainSight); + public static readonly Attachment PTR40Hunter = new("PTR-40_Hunter", AttachmentType.MainSight); + public static readonly Attachment _1P78 = new("1P78", AttachmentType.MainSight); + public static readonly Attachment Acog = new("Acog", AttachmentType.MainSight); + public static readonly Attachment M125 = new("M_125", AttachmentType.MainSight); + public static readonly Attachment Prisma = new("Prisma", AttachmentType.MainSight); + public static readonly Attachment Slip = new("Slip", AttachmentType.MainSight); + public static readonly Attachment PistolDeltaSight = new("Pistol_Delta_Sight", AttachmentType.MainSight); + public static readonly Attachment PistolRedDot = new("Pistol_Red_Dot", AttachmentType.MainSight); + public static readonly Attachment AimComp = new("Aim_Comp", AttachmentType.MainSight); + public static readonly Attachment Holographic = new("Holographic", AttachmentType.MainSight); + public static readonly Attachment Kobra = new("Kobra", AttachmentType.MainSight); + public static readonly Attachment OKP7 = new("OKP7", AttachmentType.MainSight); + public static readonly Attachment PKAS = new("PK-AS", AttachmentType.MainSight); + public static readonly Attachment RedDot = new("Red_Dot", AttachmentType.MainSight); + public static readonly Attachment Reflex = new("Reflex", AttachmentType.MainSight); + public static readonly Attachment Strikefire = new("Strikefire", AttachmentType.MainSight); + public static readonly Attachment Razor = new("Razor", AttachmentType.MainSight); + public static readonly Attachment Flir = new("Flir", AttachmentType.MainSight); + public static readonly Attachment Echo = new("Echo", AttachmentType.MainSight); + public static readonly Attachment TRI4X32 = new("TRI4X32", AttachmentType.MainSight); + public static readonly Attachment FYouSight = new("FYou_Sight", AttachmentType.MainSight); + public static readonly Attachment HoloPK120 = new("Holo_PK-120", AttachmentType.MainSight); + public static readonly Attachment Pistol8xScope = new("Pistol_8x_Scope", AttachmentType.MainSight); + public static readonly Attachment BurrisAR332 = new("BurrisAR332", AttachmentType.MainSight); + public static readonly Attachment HS401G5 = new("HS401G5", AttachmentType.MainSight); + + // ----- Top Scope ----- + public static readonly Attachment DeltaSightTop = new("Delta_Sight_Top", AttachmentType.TopSight); + public static readonly Attachment RedDotTop = new("Red_Dot_Top", AttachmentType.TopSight); + public static readonly Attachment CRedDotTop = new("C_Red_Dot_Top", AttachmentType.TopSight); + public static readonly Attachment FYouTop = new("FYou_Top", AttachmentType.TopSight); + + // ----- Under Rails ----- + public static readonly Attachment AngledGrip = new("Angled_Grip", AttachmentType.UnderRail); + public static readonly Attachment Bipod = new("Bipod", AttachmentType.UnderRail); + public static readonly Attachment VerticalGrip = new("Vertical_Grip", AttachmentType.UnderRail); + public static readonly Attachment StubbyGrip = new("Stubby_Grip", AttachmentType.UnderRail); + public static readonly Attachment StabilGrip = new("Stabil_Grip", AttachmentType.UnderRail); + public static readonly Attachment VerticalSkeletonGrip = new("Vertical_Skeleton_Grip", AttachmentType.UnderRail); + public static readonly Attachment FABDTFG = new("FAB-DTFG", AttachmentType.UnderRail); + public static readonly Attachment MagpulAngled = new("Magpul_Angled", AttachmentType.UnderRail); + public static readonly Attachment BCMGunFighter = new("BCM-Gun_Fighter", AttachmentType.UnderRail); + public static readonly Attachment ShiftShortAngledGrip = new("Shift_Short_Angled_Grip", AttachmentType.UnderRail); + public static readonly Attachment SE5Grip = new("SE-5_Grip", AttachmentType.UnderRail); + public static readonly Attachment RK6Foregrip = new("RK-6_Foregrip", AttachmentType.UnderRail); + public static readonly Attachment HeraCQRFront = new("HeraCQR_Front", AttachmentType.UnderRail); + public static readonly Attachment B25URK = new("B-25URK", AttachmentType.UnderRail); + public static readonly Attachment VTACUVGTacticalGrip = new("VTAC_UVG_TacticalGrip", AttachmentType.UnderRail); + + // ----- Side Rails ----- + public static readonly Attachment Flashlight = new("Flashlight", AttachmentType.SideRail); + public static readonly Attachment Rangefinder = new("Rangefinder", AttachmentType.SideRail); + public static readonly Attachment Redlaser = new("Redlaser", AttachmentType.SideRail); + public static readonly Attachment TacticalFlashlight = new("Tactical_Flashlight", AttachmentType.SideRail); + public static readonly Attachment Greenlaser = new("Greenlaser", AttachmentType.SideRail); + public static readonly Attachment Searchlight = new("Searchlight", AttachmentType.SideRail); + + // ----- Bolts ----- + public static readonly Attachment BoltActionA = new("Bolt_Action_A", AttachmentType.Bolt); + public static readonly Attachment BoltActionB = new("Bolt_Action_B", AttachmentType.Bolt); + public static readonly Attachment BoltActionC = new("Bolt_Action_C", AttachmentType.Bolt); + public static readonly Attachment BoltActionD = new("Bolt_Action_D", AttachmentType.Bolt); + public static readonly Attachment BoltActionE = new("Bolt_Action_E", AttachmentType.Bolt); + + // ----- Init ----- + static Attachments() { - // ----- Private Variables ----- - private static Dictionary mAttachments; - - // ----- Barrels ----- - public static readonly Attachment Basic = new Attachment("Basic", AttachmentType.Barrel); - public static readonly Attachment Compensator = new Attachment("Compensator", AttachmentType.Barrel); - public static readonly Attachment Heavy = new Attachment("Heavy", AttachmentType.Barrel); - public static readonly Attachment LongBarrel = new Attachment("Long_Barrel", AttachmentType.Barrel); - public static readonly Attachment MuzzleBreak = new Attachment("Muzzle_Break", AttachmentType.Barrel); - public static readonly Attachment Ranger = new Attachment("Ranger", AttachmentType.Barrel); - public static readonly Attachment SuppressorLong = new Attachment("Suppressor_Long", AttachmentType.Barrel); - public static readonly Attachment SuppressorShort = new Attachment("Suppressor_Short", AttachmentType.Barrel); - public static readonly Attachment Tactical = new Attachment("Tactical", AttachmentType.Barrel); - public static readonly Attachment FlashHider = new Attachment("Flash_Hider", AttachmentType.Barrel); - public static readonly Attachment Osprey9 = new Attachment("Osprey_9", AttachmentType.Barrel); - public static readonly Attachment DGN308 = new Attachment("DGN-308", AttachmentType.Barrel); - public static readonly Attachment VAMB762 = new Attachment("VAMB-762", AttachmentType.Barrel); - public static readonly Attachment SDN6762 = new Attachment("SDN-6_762", AttachmentType.Barrel); - public static readonly Attachment NT4556 = new Attachment("NT-4_556", AttachmentType.Barrel); - - // ----- Canted Sights ----- - public static readonly Attachment Ironsight = new Attachment("Ironsight", AttachmentType.CantedSight); - public static readonly Attachment CantedRedDot = new Attachment("Canted_Red_Dot", AttachmentType.CantedSight); - public static readonly Attachment FYouCanted = new Attachment("FYou_Canted", AttachmentType.CantedSight); - public static readonly Attachment HoloDot = new Attachment("Holo_Dot", AttachmentType.CantedSight); - - // ----- Scope ----- - public static readonly Attachment _6xScope = new Attachment("6x_Scope", AttachmentType.MainSight); - public static readonly Attachment _8xScope = new Attachment("8x_Scope", AttachmentType.MainSight); - public static readonly Attachment _15xScope = new Attachment("15x_Scope", AttachmentType.MainSight); - public static readonly Attachment _20xScope = new Attachment("20x_Scope", AttachmentType.MainSight); - public static readonly Attachment PTR40Hunter = new Attachment("PTR-40_Hunter", AttachmentType.MainSight); - public static readonly Attachment _1P78 = new Attachment("1P78", AttachmentType.MainSight); - public static readonly Attachment Acog = new Attachment("Acog", AttachmentType.MainSight); - public static readonly Attachment M125 = new Attachment("M_125", AttachmentType.MainSight); - public static readonly Attachment Prisma = new Attachment("Prisma", AttachmentType.MainSight); - public static readonly Attachment Slip = new Attachment("Slip", AttachmentType.MainSight); - public static readonly Attachment PistolDeltaSight = new Attachment("Pistol_Delta_Sight", AttachmentType.MainSight); - public static readonly Attachment PistolRedDot = new Attachment("Pistol_Red_Dot", AttachmentType.MainSight); - public static readonly Attachment AimComp = new Attachment("Aim_Comp", AttachmentType.MainSight); - public static readonly Attachment Holographic = new Attachment("Holographic", AttachmentType.MainSight); - public static readonly Attachment Kobra = new Attachment("Kobra", AttachmentType.MainSight); - public static readonly Attachment OKP7 = new Attachment("OKP7", AttachmentType.MainSight); - public static readonly Attachment PKAS = new Attachment("PK-AS", AttachmentType.MainSight); - public static readonly Attachment RedDot = new Attachment("Red_Dot", AttachmentType.MainSight); - public static readonly Attachment Reflex = new Attachment("Reflex", AttachmentType.MainSight); - public static readonly Attachment Strikefire = new Attachment("Strikefire", AttachmentType.MainSight); - public static readonly Attachment Razor = new Attachment("Razor", AttachmentType.MainSight); - public static readonly Attachment Flir = new Attachment("Flir", AttachmentType.MainSight); - public static readonly Attachment Echo = new Attachment("Echo", AttachmentType.MainSight); - public static readonly Attachment TRI4X32 = new Attachment("TRI4X32", AttachmentType.MainSight); - public static readonly Attachment FYouSight = new Attachment("FYou_Sight", AttachmentType.MainSight); - public static readonly Attachment HoloPK120 = new Attachment("Holo_PK-120", AttachmentType.MainSight); - public static readonly Attachment Pistol8xScope = new Attachment("Pistol_8x_Scope", AttachmentType.MainSight); - public static readonly Attachment BurrisAR332 = new Attachment("BurrisAR332", AttachmentType.MainSight); - public static readonly Attachment HS401G5 = new Attachment("HS401G5", AttachmentType.MainSight); - - // ----- Top Scope ----- - public static readonly Attachment DeltaSightTop = new Attachment("Delta_Sight_Top", AttachmentType.TopSight); - public static readonly Attachment RedDotTop = new Attachment("Red_Dot_Top", AttachmentType.TopSight); - public static readonly Attachment CRedDotTop = new Attachment("C_Red_Dot_Top", AttachmentType.TopSight); - public static readonly Attachment FYouTop = new Attachment("FYou_Top", AttachmentType.TopSight); - - // ----- Under Rails ----- - public static readonly Attachment AngledGrip = new Attachment("Angled_Grip", AttachmentType.UnderRail); - public static readonly Attachment Bipod = new Attachment("Bipod", AttachmentType.UnderRail); - public static readonly Attachment VerticalGrip = new Attachment("Vertical_Grip", AttachmentType.UnderRail); - public static readonly Attachment StubbyGrip = new Attachment("Stubby_Grip", AttachmentType.UnderRail); - public static readonly Attachment StabilGrip = new Attachment("Stabil_Grip", AttachmentType.UnderRail); - public static readonly Attachment VerticalSkeletonGrip = new Attachment("Vertical_Skeleton_Grip", AttachmentType.UnderRail); - public static readonly Attachment FABDTFG = new Attachment("FAB-DTFG", AttachmentType.UnderRail); - public static readonly Attachment MagpulAngled = new Attachment("Magpul_Angled", AttachmentType.UnderRail); - public static readonly Attachment BCMGunFighter = new Attachment("BCM-Gun_Fighter", AttachmentType.UnderRail); - public static readonly Attachment ShiftShortAngledGrip = new Attachment("Shift_Short_Angled_Grip", AttachmentType.UnderRail); - public static readonly Attachment SE5Grip = new Attachment("SE-5_Grip", AttachmentType.UnderRail); - public static readonly Attachment RK6Foregrip = new Attachment("RK-6_Foregrip", AttachmentType.UnderRail); - public static readonly Attachment HeraCQRFront = new Attachment("HeraCQR_Front", AttachmentType.UnderRail); - public static readonly Attachment B25URK = new Attachment("B-25URK", AttachmentType.UnderRail); - public static readonly Attachment VTACUVGTacticalGrip = new Attachment("VTAC_UVG_TacticalGrip", AttachmentType.UnderRail); - - // ----- Side Rails ----- - public static readonly Attachment Flashlight = new Attachment("Flashlight", AttachmentType.SideRail); - public static readonly Attachment Rangefinder = new Attachment("Rangefinder", AttachmentType.SideRail); - public static readonly Attachment Redlaser = new Attachment("Redlaser", AttachmentType.SideRail); - public static readonly Attachment TacticalFlashlight = new Attachment("Tactical_Flashlight", AttachmentType.SideRail); - public static readonly Attachment Greenlaser = new Attachment("Greenlaser", AttachmentType.SideRail); - public static readonly Attachment Searchlight = new Attachment("Searchlight", AttachmentType.SideRail); - - // ----- Bolts ----- - public static readonly Attachment BoltActionA = new Attachment("Bolt_Action_A", AttachmentType.Bolt); - public static readonly Attachment BoltActionB = new Attachment("Bolt_Action_B", AttachmentType.Bolt); - public static readonly Attachment BoltActionC = new Attachment("Bolt_Action_C", AttachmentType.Bolt); - public static readonly Attachment BoltActionD = new Attachment("Bolt_Action_D", AttachmentType.Bolt); - public static readonly Attachment BoltActionE = new Attachment("Bolt_Action_E", AttachmentType.Bolt); - - // ----- Public Calls ----- - public static bool TryFind(string name, out Attachment item) - { - return mAttachments.TryGetValue(name, out item); - } - - // ----- Init ----- - static Attachments() - { - var members = typeof(Attachments).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); - mAttachments = new Dictionary(members.Length); - foreach (var memberInfo in members) + var members = typeof(Attachments).GetMembers(BindingFlags.Public | BindingFlags.Static); + mAttachments = new Dictionary(members.Length); + foreach (var memberInfo in members) + if (memberInfo.MemberType == MemberTypes.Field) { - if (memberInfo.MemberType == System.Reflection.MemberTypes.Field) + var field = (FieldInfo)memberInfo; + if (field.FieldType == typeof(Attachment)) { - var field = ((FieldInfo)memberInfo); - if (field.FieldType == typeof(Attachment)) - { - var att = (Attachment)field.GetValue(null); - mAttachments.Add(att.Name, att); - } + var att = (Attachment)field.GetValue(null); + mAttachments.Add(att.Name, att); } } - } } -} + + // ----- Public Calls ----- + public static bool TryFind(string name, out Attachment item) + { + return mAttachments.TryGetValue(name, out item); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Datasets/Weapons.cs b/BattleBitAPI/Common/Datasets/Weapons.cs index 49cd6f3..7449ab0 100644 --- a/BattleBitAPI/Common/Datasets/Weapons.cs +++ b/BattleBitAPI/Common/Datasets/Weapons.cs @@ -1,82 +1,78 @@ -using Microsoft.VisualBasic; -using System.Reflection; +using System.Reflection; -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public static class Weapons { - public static class Weapons + // ----- Private Variables ----- + private static readonly Dictionary mWeapons; + + // ----- Public Variables ----- + public static readonly Weapon ACR = new("ACR", WeaponType.Rifle); + public static readonly Weapon AK15 = new("AK15", WeaponType.Rifle); + public static readonly Weapon AK74 = new("AK74", WeaponType.Rifle); + public static readonly Weapon G36C = new("G36C", WeaponType.Rifle); + public static readonly Weapon HoneyBadger = new("Honey Badger", WeaponType.PersonalDefenseWeapon_PDW); + public static readonly Weapon KrissVector = new("Kriss Vector", WeaponType.SubmachineGun_SMG); + public static readonly Weapon L86A1 = new("L86A1", WeaponType.LightSupportGun_LSG); + public static readonly Weapon L96 = new("L96", WeaponType.SniperRifle); + public static readonly Weapon M4A1 = new("M4A1", WeaponType.Rifle); + public static readonly Weapon M9 = new("M9", WeaponType.Pistol); + public static readonly Weapon M110 = new("M110", WeaponType.DMR); + public static readonly Weapon M249 = new("M249", WeaponType.LightMachineGun_LMG); + public static readonly Weapon MK14EBR = new("MK14 EBR", WeaponType.DMR); + public static readonly Weapon MK20 = new("MK20", WeaponType.DMR); + public static readonly Weapon MP7 = new("MP7", WeaponType.SubmachineGun_SMG); + public static readonly Weapon PP2000 = new("PP2000", WeaponType.SubmachineGun_SMG); + public static readonly Weapon SCARH = new("SCAR-H", WeaponType.Rifle); + public static readonly Weapon SSG69 = new("SSG 69", WeaponType.SniperRifle); + public static readonly Weapon SV98 = new("SV-98", WeaponType.SniperRifle); + public static readonly Weapon UMP45 = new("UMP-45", WeaponType.SubmachineGun_SMG); + public static readonly Weapon Unica = new("Unica", WeaponType.HeavyPistol); + public static readonly Weapon USP = new("USP", WeaponType.Pistol); + public static readonly Weapon AsVal = new("As Val", WeaponType.Carbine); + public static readonly Weapon AUGA3 = new("AUG A3", WeaponType.Rifle); + public static readonly Weapon DesertEagle = new("Desert Eagle", WeaponType.HeavyPistol); + public static readonly Weapon FAL = new("FAL", WeaponType.Rifle); + public static readonly Weapon Glock18 = new("Glock 18", WeaponType.AutoPistol); + public static readonly Weapon M200 = new("M200", WeaponType.SniperRifle); + public static readonly Weapon MP443 = new("MP 443", WeaponType.Pistol); + public static readonly Weapon FAMAS = new("FAMAS", WeaponType.Rifle); + public static readonly Weapon MP5 = new("MP5", WeaponType.SubmachineGun_SMG); + public static readonly Weapon P90 = new("P90", WeaponType.PersonalDefenseWeapon_PDW); + public static readonly Weapon MSR = new("MSR", WeaponType.SniperRifle); + public static readonly Weapon PP19 = new("PP19", WeaponType.SubmachineGun_SMG); + public static readonly Weapon SVD = new("SVD", WeaponType.DMR); + public static readonly Weapon Rem700 = new("Rem700", WeaponType.SniperRifle); + public static readonly Weapon SG550 = new("SG550", WeaponType.Rifle); + public static readonly Weapon Groza = new("Groza", WeaponType.PersonalDefenseWeapon_PDW); + public static readonly Weapon HK419 = new("HK419", WeaponType.Rifle); + public static readonly Weapon ScorpionEVO = new("ScorpionEVO", WeaponType.Carbine); + public static readonly Weapon Rsh12 = new("Rsh12", WeaponType.HeavyPistol); + public static readonly Weapon MG36 = new("MG36", WeaponType.LightSupportGun_LSG); + public static readonly Weapon AK5C = new("AK5C", WeaponType.Rifle); + public static readonly Weapon Ultimax100 = new("Ultimax100", WeaponType.LightMachineGun_LMG); + + // ----- Init ----- + static Weapons() { - // ----- Private Variables ----- - private static Dictionary mWeapons; - - // ----- Public Variables ----- - public readonly static Weapon ACR = new Weapon("ACR", WeaponType.Rifle); - public readonly static Weapon AK15 = new Weapon("AK15", WeaponType.Rifle); - public readonly static Weapon AK74 = new Weapon("AK74", WeaponType.Rifle); - public readonly static Weapon G36C = new Weapon("G36C", WeaponType.Rifle); - public readonly static Weapon HoneyBadger = new Weapon("Honey Badger", WeaponType.PersonalDefenseWeapon_PDW); - public readonly static Weapon KrissVector = new Weapon("Kriss Vector", WeaponType.SubmachineGun_SMG); - public readonly static Weapon L86A1 = new Weapon("L86A1", WeaponType.LightSupportGun_LSG); - public readonly static Weapon L96 = new Weapon("L96", WeaponType.SniperRifle); - public readonly static Weapon M4A1 = new Weapon("M4A1", WeaponType.Rifle); - public readonly static Weapon M9 = new Weapon("M9", WeaponType.Pistol); - public readonly static Weapon M110 = new Weapon("M110", WeaponType.DMR); - public readonly static Weapon M249 = new Weapon("M249", WeaponType.LightMachineGun_LMG); - public readonly static Weapon MK14EBR = new Weapon("MK14 EBR", WeaponType.DMR); - public readonly static Weapon MK20 = new Weapon("MK20", WeaponType.DMR); - public readonly static Weapon MP7 = new Weapon("MP7", WeaponType.SubmachineGun_SMG); - public readonly static Weapon PP2000 = new Weapon("PP2000", WeaponType.SubmachineGun_SMG); - public readonly static Weapon SCARH = new Weapon("SCAR-H", WeaponType.Rifle); - public readonly static Weapon SSG69 = new Weapon("SSG 69", WeaponType.SniperRifle); - public readonly static Weapon SV98 = new Weapon("SV-98", WeaponType.SniperRifle); - public readonly static Weapon UMP45 = new Weapon("UMP-45", WeaponType.SubmachineGun_SMG); - public readonly static Weapon Unica = new Weapon("Unica", WeaponType.HeavyPistol); - public readonly static Weapon USP = new Weapon("USP", WeaponType.Pistol); - public readonly static Weapon AsVal = new Weapon("As Val", WeaponType.Carbine); - public readonly static Weapon AUGA3 = new Weapon("AUG A3", WeaponType.Rifle); - public readonly static Weapon DesertEagle = new Weapon("Desert Eagle", WeaponType.HeavyPistol); - public readonly static Weapon FAL = new Weapon("FAL", WeaponType.Rifle); - public readonly static Weapon Glock18 = new Weapon("Glock 18", WeaponType.AutoPistol); - public readonly static Weapon M200 = new Weapon("M200", WeaponType.SniperRifle); - public readonly static Weapon MP443 = new Weapon("MP 443", WeaponType.Pistol); - public readonly static Weapon FAMAS = new Weapon("FAMAS", WeaponType.Rifle); - public readonly static Weapon MP5 = new Weapon("MP5", WeaponType.SubmachineGun_SMG); - public readonly static Weapon P90 = new Weapon("P90", WeaponType.PersonalDefenseWeapon_PDW); - public readonly static Weapon MSR = new Weapon("MSR", WeaponType.SniperRifle); - public readonly static Weapon PP19 = new Weapon("PP19", WeaponType.SubmachineGun_SMG); - public readonly static Weapon SVD = new Weapon("SVD", WeaponType.DMR); - public readonly static Weapon Rem700 = new Weapon("Rem700", WeaponType.SniperRifle); - public readonly static Weapon SG550 = new Weapon("SG550", WeaponType.Rifle); - public readonly static Weapon Groza = new Weapon("Groza", WeaponType.PersonalDefenseWeapon_PDW); - public readonly static Weapon HK419 = new Weapon("HK419", WeaponType.Rifle); - public readonly static Weapon ScorpionEVO = new Weapon("ScorpionEVO", WeaponType.Carbine); - public readonly static Weapon Rsh12 = new Weapon("Rsh12", WeaponType.HeavyPistol); - public readonly static Weapon MG36 = new Weapon("MG36", WeaponType.LightSupportGun_LSG); - public readonly static Weapon AK5C = new Weapon("AK5C", WeaponType.Rifle); - public readonly static Weapon Ultimax100 = new Weapon("Ultimax100", WeaponType.LightMachineGun_LMG); - - // ----- Public Calls ----- - public static bool TryFind(string name, out Weapon item) - { - return mWeapons.TryGetValue(name, out item); - } - - // ----- Init ----- - static Weapons() - { - var members = typeof(Weapons).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); - mWeapons = new Dictionary(members.Length); - foreach (var memberInfo in members) + var members = typeof(Weapons).GetMembers(BindingFlags.Public | BindingFlags.Static); + mWeapons = new Dictionary(members.Length); + foreach (var memberInfo in members) + if (memberInfo.MemberType == MemberTypes.Field) { - if (memberInfo.MemberType == System.Reflection.MemberTypes.Field) + var field = (FieldInfo)memberInfo; + if (field.FieldType == typeof(Weapon)) { - var field = ((FieldInfo)memberInfo); - if (field.FieldType == typeof(Weapon)) - { - var wep = (Weapon)field.GetValue(null); - mWeapons.Add(wep.Name, wep); - } + var wep = (Weapon)field.GetValue(null); + mWeapons.Add(wep.Name, wep); } } - } } -} + + // ----- Public Calls ----- + public static bool TryFind(string name, out Weapon item) + { + return mWeapons.TryGetValue(name, out item); + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/AttachmentType.cs b/BattleBitAPI/Common/Enums/AttachmentType.cs index 89ce99d..c58f3a9 100644 --- a/BattleBitAPI/Common/Enums/AttachmentType.cs +++ b/BattleBitAPI/Common/Enums/AttachmentType.cs @@ -1,13 +1,12 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum AttachmentType { - public enum AttachmentType - { - MainSight, - TopSight, - CantedSight, - Barrel, - UnderRail, - SideRail, - Bolt, - } -} + MainSight, + TopSight, + CantedSight, + Barrel, + UnderRail, + SideRail, + Bolt +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/ChatChannel.cs b/BattleBitAPI/Common/Enums/ChatChannel.cs index 5c36756..384dd44 100644 --- a/BattleBitAPI/Common/Enums/ChatChannel.cs +++ b/BattleBitAPI/Common/Enums/ChatChannel.cs @@ -1,9 +1,8 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum ChatChannel { - public enum ChatChannel - { - AllChat, - TeamChat, - SquadChat - } -} + AllChat, + TeamChat, + SquadChat +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/DamageReason.cs b/BattleBitAPI/Common/Enums/DamageReason.cs index 5d69631..5ec5220 100644 --- a/BattleBitAPI/Common/Enums/DamageReason.cs +++ b/BattleBitAPI/Common/Enums/DamageReason.cs @@ -1,27 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace BattleBitAPI.Common; -namespace BattleBitAPI.Common +public enum ReasonOfDamage : byte { - public enum ReasonOfDamage : byte - { - Server = 0, - Weapon = 1, - Bleeding = 2, - Fall = 3, - HelicopterBlade = 4, - VehicleExplosion = 5, - Explosion = 6, - vehicleRunOver = 7, - BuildingCollapsing = 8, - SledgeHammer = 9, - TreeFall = 10, - CountAsKill = 11, - Suicide = 12, - HelicopterCrash = 13, - BarbedWire = 14, - } -} + Server = 0, + Weapon = 1, + Bleeding = 2, + Fall = 3, + HelicopterBlade = 4, + VehicleExplosion = 5, + Explosion = 6, + vehicleRunOver = 7, + BuildingCollapsing = 8, + SledgeHammer = 9, + TreeFall = 10, + CountAsKill = 11, + Suicide = 12, + HelicopterCrash = 13, + BarbedWire = 14 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/GameRole.cs b/BattleBitAPI/Common/Enums/GameRole.cs index 3c99489..24ce37c 100644 --- a/BattleBitAPI/Common/Enums/GameRole.cs +++ b/BattleBitAPI/Common/Enums/GameRole.cs @@ -1,7 +1,11 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum GameRole { - public enum GameRole - { - Assault = 0, Medic = 1, Support = 2, Engineer = 3, Recon = 4, Leader = 5 - } -} + Assault = 0, + Medic = 1, + Support = 2, + Engineer = 3, + Recon = 4, + Leader = 5 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/GameState.cs b/BattleBitAPI/Common/Enums/GameState.cs index 49c2f3e..3b2603f 100644 --- a/BattleBitAPI/Common/Enums/GameState.cs +++ b/BattleBitAPI/Common/Enums/GameState.cs @@ -1,10 +1,9 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum GameState : byte { - public enum GameState : byte - { - WaitingForPlayers = 0, - CountingDown = 1, - Playing = 2, - EndingGame = 3 - } -} + WaitingForPlayers = 0, + CountingDown = 1, + Playing = 2, + EndingGame = 3 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/LeaningSide.cs b/BattleBitAPI/Common/Enums/LeaningSide.cs index c44d82b..c7a3e87 100644 --- a/BattleBitAPI/Common/Enums/LeaningSide.cs +++ b/BattleBitAPI/Common/Enums/LeaningSide.cs @@ -1,7 +1,8 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum LeaningSide { - public enum LeaningSide - { - Left, None, Right - } -} + Left, + None, + Right +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/LoadoutIndex.cs b/BattleBitAPI/Common/Enums/LoadoutIndex.cs index 1737960..1164cf4 100644 --- a/BattleBitAPI/Common/Enums/LoadoutIndex.cs +++ b/BattleBitAPI/Common/Enums/LoadoutIndex.cs @@ -1,12 +1,11 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum LoadoutIndex : byte { - public enum LoadoutIndex : byte - { - Primary = 0, - Secondary = 1, - FirstAid = 2, - LightGadget = 3, - HeavyGadget = 4, - Throwable = 5, - } -} + Primary = 0, + Secondary = 1, + FirstAid = 2, + LightGadget = 3, + HeavyGadget = 4, + Throwable = 5 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/MapDayNight.cs b/BattleBitAPI/Common/Enums/MapDayNight.cs index 9f54ec1..11c0355 100644 --- a/BattleBitAPI/Common/Enums/MapDayNight.cs +++ b/BattleBitAPI/Common/Enums/MapDayNight.cs @@ -1,8 +1,7 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum MapDayNight : byte { - public enum MapDayNight : byte - { - Day = 0, - Night = 1, - } -} + Day = 0, + Night = 1 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/MapSize.cs b/BattleBitAPI/Common/Enums/MapSize.cs index f623976..7345c6c 100644 --- a/BattleBitAPI/Common/Enums/MapSize.cs +++ b/BattleBitAPI/Common/Enums/MapSize.cs @@ -1,12 +1,11 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum MapSize : byte { - public enum MapSize : byte - { - None = 0, - _8v8=8, - _16vs16 = 16, - _32vs32 = 32, - _64vs64 = 64, - _127vs127 = 90, - } -} + None = 0, + _8v8 = 8, + _16vs16 = 16, + _32vs32 = 32, + _64vs64 = 64, + _127vs127 = 90 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/PlayerBody.cs b/BattleBitAPI/Common/Enums/PlayerBody.cs index 90b8b84..7ea11a2 100644 --- a/BattleBitAPI/Common/Enums/PlayerBody.cs +++ b/BattleBitAPI/Common/Enums/PlayerBody.cs @@ -1,15 +1,13 @@ -namespace BattleBitAPI.Common -{ - public enum PlayerBody : byte - { - None = 0, - Head = 2, - Neck = 3, - Shoulder = 4, - Arm = 5, - Leg = 6, - Foot = 7, - Chest = 10, - } +namespace BattleBitAPI.Common; -} +public enum PlayerBody : byte +{ + None = 0, + Head = 2, + Neck = 3, + Shoulder = 4, + Arm = 5, + Leg = 6, + Foot = 7, + Chest = 10 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/PlayerSpawningPoint.cs b/BattleBitAPI/Common/Enums/PlayerSpawningPoint.cs index 8501baa..5477be1 100644 --- a/BattleBitAPI/Common/Enums/PlayerSpawningPoint.cs +++ b/BattleBitAPI/Common/Enums/PlayerSpawningPoint.cs @@ -1,7 +1,10 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum PlayerSpawningPosition : byte { - public enum PlayerSpawningPosition : byte - { - SpawnAtPoint, SpawnAtRally, SpawnAtFriend, SpawnAtVehicle, Null - } -} + SpawnAtPoint, + SpawnAtRally, + SpawnAtFriend, + SpawnAtVehicle, + Null +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/PlayerStand.cs b/BattleBitAPI/Common/Enums/PlayerStand.cs index 84102e1..68d0ebb 100644 --- a/BattleBitAPI/Common/Enums/PlayerStand.cs +++ b/BattleBitAPI/Common/Enums/PlayerStand.cs @@ -1,7 +1,8 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum PlayerStand : byte { - public enum PlayerStand : byte - { - Standing = 0, Crouching = 1, Proning = 2 - } -} + Standing = 0, + Crouching = 1, + Proning = 2 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/ReportReason.cs b/BattleBitAPI/Common/Enums/ReportReason.cs index 1bc94cb..6a5566b 100644 --- a/BattleBitAPI/Common/Enums/ReportReason.cs +++ b/BattleBitAPI/Common/Enums/ReportReason.cs @@ -1,23 +1,22 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum ReportReason { - public enum ReportReason - { - Cheating_WallHack = 0, - Cheating_Aimbot = 1, - Cheating_Speedhack = 2, + Cheating_WallHack = 0, + Cheating_Aimbot = 1, + Cheating_Speedhack = 2, - Racism_Discrimination_Text = 3, - Racism_Discrimination_Voice = 4, + Racism_Discrimination_Text = 3, + Racism_Discrimination_Voice = 4, - Spamming_Text = 5, - Spamming_Voice = 6, + Spamming_Text = 5, + Spamming_Voice = 6, - Bad_Language_Text = 7, - Bad_Language_Voice = 8, + Bad_Language_Text = 7, + Bad_Language_Voice = 8, - Griefing = 9, - Exploiting = 10, - OtherToxicBehaviour = 11, - UserProfileNamePicture = 12, - } -} + Griefing = 9, + Exploiting = 10, + OtherToxicBehaviour = 11, + UserProfileNamePicture = 12 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/Roles.cs b/BattleBitAPI/Common/Enums/Roles.cs index 4b41891..d6ae7b7 100644 --- a/BattleBitAPI/Common/Enums/Roles.cs +++ b/BattleBitAPI/Common/Enums/Roles.cs @@ -1,12 +1,11 @@ -namespace BattleBitAPI.Common -{ - public enum Roles : ulong - { - None = 0, +namespace BattleBitAPI.Common; - Admin = 1 << 0, - Moderator = 1 << 1, - Special = 1 << 2, - Vip = 1 << 3, - } -} +public enum Roles : ulong +{ + None = 0, + + Admin = 1 << 0, + Moderator = 1 << 1, + Special = 1 << 2, + Vip = 1 << 3 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/Squads.cs b/BattleBitAPI/Common/Enums/Squads.cs index a152faf..000baf0 100644 --- a/BattleBitAPI/Common/Enums/Squads.cs +++ b/BattleBitAPI/Common/Enums/Squads.cs @@ -1,72 +1,71 @@ -namespace BattleBitAPI.Common -{ - public enum Squads - { - NoSquad = 0, +namespace BattleBitAPI.Common; - Alpha = 1, - Bravo = 2, - Charlie = 3, - Delta = 4, - Echo = 5, - Foxtrot = 6, - Golf = 7, - Hotel = 8, - India = 9, - Juliett = 10, - Kilo = 11, - Lima = 12, - Mike = 13, - November = 14, - Oscar = 15, - Papa = 16, - Quebec = 17, - Romeo = 18, - Sierra = 19, - Tango = 20, - Uniform = 21, - Whiskey = 22, - Xray = 23, - Yankee = 24, - Zulu = 25, - Ash = 26, - Baker = 27, - Cast = 28, - Diver = 29, - Eagle = 30, - Fisher = 31, - George = 32, - Hanover = 33, - Ice = 34, - Jake = 35, - King = 36, - Lash = 37, - Mule = 38, - Neptune = 39, - Ostend = 40, - Page = 41, - Quail = 42, - Raft = 43, - Scout = 44, - Tare = 45, - Unit = 46, - William = 47, - Xaintrie = 48, - Yoke = 49, - Zebra = 50, - Ace = 51, - Beer = 52, - Cast2 = 53, - Duff = 54, - Edward = 55, - Freddy = 56, - Gustav = 57, - Henry = 58, - Ivar = 59, - Jazz = 60, - Key = 61, - Lincoln = 62, - Mary = 63, - Nora = 64 - } -} +public enum Squads +{ + NoSquad = 0, + + Alpha = 1, + Bravo = 2, + Charlie = 3, + Delta = 4, + Echo = 5, + Foxtrot = 6, + Golf = 7, + Hotel = 8, + India = 9, + Juliett = 10, + Kilo = 11, + Lima = 12, + Mike = 13, + November = 14, + Oscar = 15, + Papa = 16, + Quebec = 17, + Romeo = 18, + Sierra = 19, + Tango = 20, + Uniform = 21, + Whiskey = 22, + Xray = 23, + Yankee = 24, + Zulu = 25, + Ash = 26, + Baker = 27, + Cast = 28, + Diver = 29, + Eagle = 30, + Fisher = 31, + George = 32, + Hanover = 33, + Ice = 34, + Jake = 35, + King = 36, + Lash = 37, + Mule = 38, + Neptune = 39, + Ostend = 40, + Page = 41, + Quail = 42, + Raft = 43, + Scout = 44, + Tare = 45, + Unit = 46, + William = 47, + Xaintrie = 48, + Yoke = 49, + Zebra = 50, + Ace = 51, + Beer = 52, + Cast2 = 53, + Duff = 54, + Edward = 55, + Freddy = 56, + Gustav = 57, + Henry = 58, + Ivar = 59, + Jazz = 60, + Key = 61, + Lincoln = 62, + Mary = 63, + Nora = 64 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/Team.cs b/BattleBitAPI/Common/Enums/Team.cs index 370b3b2..00f970e 100644 --- a/BattleBitAPI/Common/Enums/Team.cs +++ b/BattleBitAPI/Common/Enums/Team.cs @@ -1,9 +1,8 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum Team : byte { - public enum Team : byte - { - TeamA = 0, - TeamB = 1, - None = 2 - } -} + TeamA = 0, + TeamB = 1, + None = 2 +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Enums/WeaponType.cs b/BattleBitAPI/Common/Enums/WeaponType.cs index 5bd1f23..ea2d931 100644 --- a/BattleBitAPI/Common/Enums/WeaponType.cs +++ b/BattleBitAPI/Common/Enums/WeaponType.cs @@ -1,17 +1,16 @@ -namespace BattleBitAPI.Common +namespace BattleBitAPI.Common; + +public enum WeaponType { - public enum WeaponType : int - { - Rifle, - DMR, - SniperRifle, - LightSupportGun_LSG, - LightMachineGun_LMG, - SubmachineGun_SMG, - Pistol, - AutoPistol, - HeavyPistol, - Carbine, - PersonalDefenseWeapon_PDW, - } -} + Rifle, + DMR, + SniperRifle, + LightSupportGun_LSG, + LightMachineGun_LMG, + SubmachineGun_SMG, + Pistol, + AutoPistol, + HeavyPistol, + Carbine, + PersonalDefenseWeapon_PDW +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Extentions/Extentions.cs b/BattleBitAPI/Common/Extentions/Extentions.cs index 3ef94dd..c0db5ea 100644 --- a/BattleBitAPI/Common/Extentions/Extentions.cs +++ b/BattleBitAPI/Common/Extentions/Extentions.cs @@ -1,39 +1,79 @@ using System.Net; using System.Net.Sockets; +using Stream = BattleBitAPI.Common.Serialization.Stream; -namespace BattleBitAPI.Common.Extentions +namespace BattleBitAPI.Common.Extentions; + +public static class Extentions { - public static class Extentions + public static long TickCount { - public static long TickCount + get { - get - { #if NETCOREAPP - return System.Environment.TickCount64; + return Environment.TickCount64; #else return (long)Environment.TickCount; #endif - } } - public unsafe static uint ToUInt(this IPAddress address) - { + } + + public static uint ToUInt(this IPAddress address) + { #if NETCOREAPP - return BitConverter.ToUInt32(address.GetAddressBytes()); + return BitConverter.ToUInt32(address.GetAddressBytes()); #else return BitConverter.ToUInt32(address.GetAddressBytes(), 0); #endif + } + + public static void SafeClose(this TcpClient client) + { + try + { + client.Close(); + } + catch + { } - public static void SafeClose(this TcpClient client) + try { - try { client.Close(); } catch { } - try { client.Dispose(); } catch { } + client.Dispose(); } - public static async Task Read(this NetworkStream networkStream, Serialization.Stream outputStream, int size, CancellationToken token = default) + catch { - int read = 0; - int readUntil = outputStream.WritePosition + size; + } + } + + public static async Task Read(this NetworkStream networkStream, Stream outputStream, int size, CancellationToken token = default) + { + var read = 0; + var readUntil = outputStream.WritePosition + size; + + //Ensure we have space. + outputStream.EnsureWriteBufferSize(size); + + //Continue reading until we have the package. + while (outputStream.WritePosition < readUntil) + { + var sizeToRead = readUntil - outputStream.WritePosition; + var received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); + if (received <= 0) + throw new Exception("NetworkStream was closed."); + + read += received; + outputStream.WritePosition += received; + } + + return read; + } + + public static async Task TryRead(this NetworkStream networkStream, Stream outputStream, int size, CancellationToken token = default) + { + try + { + var readUntil = outputStream.WritePosition + size; //Ensure we have space. outputStream.EnsureWriteBufferSize(size); @@ -41,42 +81,18 @@ namespace BattleBitAPI.Common.Extentions //Continue reading until we have the package. while (outputStream.WritePosition < readUntil) { - int sizeToRead = readUntil - outputStream.WritePosition; - int received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); + var sizeToRead = readUntil - outputStream.WritePosition; + var received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); if (received <= 0) throw new Exception("NetworkStream was closed."); - - read += received; outputStream.WritePosition += received; } - return read; + return true; } - public static async Task TryRead(this NetworkStream networkStream, Serialization.Stream outputStream, int size, CancellationToken token = default) + catch { - try - { - int readUntil = outputStream.WritePosition + size; - - //Ensure we have space. - outputStream.EnsureWriteBufferSize(size); - - //Continue reading until we have the package. - while (outputStream.WritePosition < readUntil) - { - int sizeToRead = readUntil - outputStream.WritePosition; - int received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); - if (received <= 0) - throw new Exception("NetworkStream was closed."); - outputStream.WritePosition += received; - } - - return true; - } - catch - { - return false; - } + return false; } } -} +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Serialization/IStreamSerializble.cs b/BattleBitAPI/Common/Serialization/IStreamSerializble.cs index 61fcb6c..d561f07 100644 --- a/BattleBitAPI/Common/Serialization/IStreamSerializble.cs +++ b/BattleBitAPI/Common/Serialization/IStreamSerializble.cs @@ -1,8 +1,7 @@ -namespace BattleBitAPI.Common.Serialization +namespace BattleBitAPI.Common.Serialization; + +public interface IStreamSerializable { - public interface IStreamSerializable - { - void Read(Stream ser); - void Write(Stream ser); - } -} + void Read(Stream ser); + void Write(Stream ser); +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Serialization/Stream.cs b/BattleBitAPI/Common/Serialization/Stream.cs index c683c54..9f5a948 100644 --- a/BattleBitAPI/Common/Serialization/Stream.cs +++ b/BattleBitAPI/Common/Serialization/Stream.cs @@ -1,675 +1,770 @@ -using BattleBitAPI.Common.Extentions; using System.Net; +using System.Text; +using BattleBitAPI.Common.Extentions; -namespace BattleBitAPI.Common.Serialization +namespace BattleBitAPI.Common.Serialization; + +public class Stream : IDisposable { - public class Stream : IDisposable - { - public const int DefaultBufferSize = 1024 * 512; + public const int DefaultBufferSize = 1024 * 512; #if BIGENDIAN public static readonly bool IsLittleEndian = false; #else - public static readonly bool IsLittleEndian = true; + public static readonly bool IsLittleEndian = true; #endif - public byte[] Buffer; - public int WritePosition; - public int ReadPosition; - public bool InPool; + public byte[] Buffer; + public int WritePosition; + public int ReadPosition; + public bool InPool; - public bool CanRead(int size) - { - int readableLenght = WritePosition - ReadPosition; - return (readableLenght >= size); - } - public void EnsureWriteBufferSize(int requiredSize) - { - int bufferLenght = Buffer.Length; + public bool CanRead(int size) + { + var readableLenght = WritePosition - ReadPosition; + return readableLenght >= size; + } - int leftSpace = bufferLenght - WritePosition; - if (leftSpace < requiredSize) - { - int newSize = bufferLenght + Math.Max(requiredSize, 1024); - System.Array.Resize(ref Buffer, newSize); - } - } + public void EnsureWriteBufferSize(int requiredSize) + { + var bufferLenght = Buffer.Length; - // -------- Write ------ - public void Write(byte value) + var leftSpace = bufferLenght - WritePosition; + if (leftSpace < requiredSize) { - EnsureWriteBufferSize(1); - Buffer[WritePosition] = value; - WritePosition += 1; - } - public void Write(bool value) - { - EnsureWriteBufferSize(1); - Buffer[WritePosition] = value ? (byte)1 : (byte)0; - WritePosition += 1; - } - public unsafe void Write(short value) - { - EnsureWriteBufferSize(2); - fixed (byte* ptr = &Buffer[WritePosition]) - *((short*)ptr) = value; - WritePosition += 2; - } - public unsafe void Write(ushort value) - { - EnsureWriteBufferSize(2); - fixed (byte* ptr = &Buffer[WritePosition]) - *((ushort*)ptr) = value; - WritePosition += 2; - } - public unsafe void Write(int value) - { - EnsureWriteBufferSize(4); - fixed (byte* ptr = &Buffer[WritePosition]) - *((int*)ptr) = value; - WritePosition += 4; - } - public unsafe void Write(uint value) - { - EnsureWriteBufferSize(4); - fixed (byte* ptr = &Buffer[WritePosition]) - *((uint*)ptr) = value; - WritePosition += 4; - } - public unsafe void Write(long value) - { - EnsureWriteBufferSize(8); - fixed (byte* ptr = &Buffer[WritePosition]) - *((long*)ptr) = value; - WritePosition += 8; - } - public unsafe void Write(ulong value) - { - EnsureWriteBufferSize(8); - fixed (byte* ptr = &Buffer[WritePosition]) - *((ulong*)ptr) = value; - WritePosition += 8; - } - public unsafe void Write(decimal value) - { - EnsureWriteBufferSize(16); - fixed (byte* ptr = &Buffer[WritePosition]) - *((decimal*)ptr) = value; - WritePosition += 16; - } - public unsafe void Write(double value) - { - EnsureWriteBufferSize(8); - fixed (byte* ptr = &Buffer[WritePosition]) - *((double*)ptr) = value; - WritePosition += 8; - } - public unsafe void Write(float value) - { - int intValue = *((int*)&value); - EnsureWriteBufferSize(4); - fixed (byte* ptr = &Buffer[WritePosition]) - *((int*)ptr) = intValue; - WritePosition += 4; - } - public unsafe void Write(string value) - { - int charCount = value.Length; - fixed (char* strPtr = value) - { - int size = System.Text.Encoding.UTF8.GetByteCount(strPtr, charCount); - EnsureWriteBufferSize(size + 2); - - - fixed (byte* buffPtr = &Buffer[WritePosition]) - { - *((ushort*)buffPtr) = (ushort)size; - System.Text.Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr + 2, size); - } - WritePosition += size + 2; - } - } - public unsafe void Write(DateTime value) - { - var utc = value.ToUniversalTime(); - - EnsureWriteBufferSize(8); - fixed (byte* ptr = &Buffer[WritePosition]) - *((long*)ptr) = utc.Ticks; - WritePosition += 8; - } - public unsafe void Write(IPAddress value) - { - uint ip = value.ToUInt(); - Write(ip); - } - public unsafe void Write(IPEndPoint value) - { - uint ip = value.Address.ToUInt(); - - Write(ip); - Write((ushort)value.Port); - } - public unsafe void WriteRaw(string value) - { - int charCount = value.Length; - fixed (char* strPtr = value) - { - int size = System.Text.Encoding.UTF8.GetByteCount(strPtr, charCount); - EnsureWriteBufferSize(size); - - fixed (byte* buffPtr = &Buffer[WritePosition]) - System.Text.Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr, size); - WritePosition += size; - } - } - public unsafe void Write(T value) where T : IStreamSerializable - { - value.Write(this); - } - public void Write(byte[] source, int sourceIndex, int length) - { - if (length == 0) - return; - - EnsureWriteBufferSize(length); - System.Array.Copy(source, sourceIndex, this.Buffer, this.WritePosition, length); - this.WritePosition += length; - } - public void Write(Stream source) - { - EnsureWriteBufferSize(source.WritePosition); - System.Array.Copy(source.Buffer, 0, this.Buffer, this.WritePosition, source.WritePosition); - this.WritePosition += source.WritePosition; - } - public void WriteStringItem(string value) - { - if (value == null) - this.Write("none"); - else - this.Write(value); - } - - public unsafe void WriteAt(byte value, int position) - { - Buffer[position] = value; - } - public unsafe void WriteAt(short value, int position) - { - fixed (byte* ptr = &Buffer[position]) - *((short*)ptr) = value; - } - public unsafe void WriteAt(ushort value, int position) - { - fixed (byte* ptr = &Buffer[position]) - *((ushort*)ptr) = value; - } - public unsafe void WriteAt(int value, int position) - { - fixed (byte* ptr = &Buffer[position]) - *((int*)ptr) = value; - } - public unsafe void WriteAt(uint value, int position) - { - fixed (byte* ptr = &Buffer[position]) - *((uint*)ptr) = value; - } - public unsafe void WriteAt(long value, int position) - { - fixed (byte* ptr = &Buffer[position]) - *((long*)ptr) = value; - } - public unsafe void WriteAt(ulong value, int position) - { - fixed (byte* ptr = &Buffer[position]) - *((ulong*)ptr) = value; - } - - // -------- Read ------ - public byte ReadInt8() - { - - var value = Buffer[ReadPosition]; - ReadPosition++; - - return value; - } - public bool ReadBool() - { - - - var value = Buffer[ReadPosition]; - ReadPosition++; - - return value == 1; - } - public unsafe short ReadInt16() - { - short value = 0; - - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 2 == 0) - { - value = *((short*)pbyte); - } - else - { - if (IsLittleEndian) - { - value = (short)((*pbyte) | (*(pbyte + 1) << 8)); - } - else - { - value = (short)((*pbyte << 8) | (*(pbyte + 1))); - } - } - } - - ReadPosition += 2; - return value; - } - public unsafe ushort ReadUInt16() - { - ushort value = 0; - - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 2 == 0) - { - value = *((ushort*)pbyte); - } - else - { - if (IsLittleEndian) - { - value = (ushort)((*pbyte) | (*(pbyte + 1) << 8)); - } - else - { - value = (ushort)((*pbyte << 8) | (*(pbyte + 1))); - } - } - } - - ReadPosition += 2; - return value; - } - public unsafe int ReadInt32() - { - int value = 0; - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 4 == 0) - { - value = *((int*)pbyte); - } - else - { - if (IsLittleEndian) - { - value = (int)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); - } - else - { - value = (int)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); - } - } - } - ReadPosition += 4; - - return value; - } - public unsafe uint ReadUInt32() - { - uint value = 0; - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 4 == 0) - { - value = *((uint*)pbyte); - } - else - { - if (IsLittleEndian) - { - value = (uint)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); - } - else - { - value = (uint)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); - } - } - } - ReadPosition += 4; - - return value; - } - public unsafe long ReadInt64() - { - long value = 0; - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 8 == 0) - { - value = *((long*)pbyte); - } - else - { - if (IsLittleEndian) - { - int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); - int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); - value = (uint)i1 | ((long)i2 << 32); - } - else - { - int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); - int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); - value = (uint)i2 | ((long)i1 << 32); - } - } - } - ReadPosition += 8; - - return value; - } - public unsafe ulong ReadUInt64() - { - ulong value = 0; - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 8 == 0) - { - value = *((ulong*)pbyte); - } - else - { - if (IsLittleEndian) - { - int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); - int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); - value = (uint)i1 | ((ulong)i2 << 32); - } - else - { - int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); - int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); - value = (uint)i2 | ((ulong)i1 << 32); - } - } - } - ReadPosition += 8; - - return value; - } - public unsafe decimal ReadInt128() - { - - - decimal value = 0; - fixed (byte* ptr = &Buffer[ReadPosition]) - { - value = *((decimal*)ptr); - } - ReadPosition += 16; - - return value; - } - public unsafe double ReadDouble() - { - double value = 0; - fixed (byte* ptr = &Buffer[ReadPosition]) - { - value = *((double*)ptr); - } - ReadPosition += 8; - - return value; - } - public unsafe float ReadFloat() - { - int value = 0; - fixed (byte* pbyte = &Buffer[ReadPosition]) - { - if (ReadPosition % 4 == 0) - { - value = *((int*)pbyte); - } - else - { - if (IsLittleEndian) - { - value = (int)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); - } - else - { - value = (int)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); - } - } - } - ReadPosition += 4; - - return *(float*)&value; - } - public DateTime ReadDateTime() - { - long value = ReadInt64(); - try - { - return new DateTime(value, DateTimeKind.Utc); - } - catch - { - return DateTime.MinValue; - } - } - public bool TryReadDateTime(out DateTime time) - { - long value = ReadInt64(); - try - { - time = new DateTime(value, DateTimeKind.Utc); - return true; - } - catch { } - - time = default; - return false; - } - public unsafe IPAddress ReadIPAddress() - { - uint ip = ReadUInt32(); - return new IPAddress(ip); - } - public unsafe IPEndPoint ReadIPEndPoint() - { - uint ip = ReadUInt32(); - ushort port = ReadUInt16(); - - return new IPEndPoint(ip, port); - } - public T Read() where T : IStreamSerializable - { - T value = default; - value.Read(this); - return value; - } - - public byte[] ReadByteArray(int lenght) - { - if (lenght == 0) - return new byte[0]; - - byte[] newBuffer = new byte[lenght]; - System.Array.Copy(this.Buffer, this.ReadPosition, newBuffer, 0, lenght); - this.ReadPosition += lenght; - return newBuffer; - } - public void ReadTo(byte[] buffer, int offset, int size) - { - System.Array.Copy(this.Buffer, this.ReadPosition, buffer, offset, size); - this.ReadPosition += size; - } - public unsafe string ReadString(int size) - { - string str; - -#if NETCOREAPP - fixed (byte* ptr = &Buffer[ReadPosition]) - str = System.Text.Encoding.UTF8.GetString(ptr, size); -#else - str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); -#endif - ReadPosition += size; - - return str; - } - public unsafe bool TryReadString(out string str) - { - if (!CanRead(2)) - { - str = null; - return false; - } - - - int size = 0; - fixed (byte* ptr = &Buffer[ReadPosition]) - size = *((ushort*)ptr); - ReadPosition += 2; - - if (!CanRead(size)) - { - str = null; - return false; - } - -#if NETCOREAPP - fixed (byte* ptr = &Buffer[ReadPosition]) - str = System.Text.Encoding.UTF8.GetString(ptr, size); -#else - str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); -#endif - - ReadPosition += size; - - return true; - } - public unsafe bool TryReadString(out string str, int maximumSize = ushort.MaxValue) - { - if (!CanRead(2)) - { - str = null; - return false; - } - - - int size = 0; - fixed (byte* ptr = &Buffer[ReadPosition]) - size = *((ushort*)ptr); - ReadPosition += 2; - - if (size > maximumSize) - { - str = null; - return false; - } - - if (!CanRead(size)) - { - str = null; - return false; - } - -#if NETCOREAPP - fixed (byte* ptr = &Buffer[ReadPosition]) - str = System.Text.Encoding.UTF8.GetString(ptr, size); -#else - str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); -#endif - - ReadPosition += size; - - return true; - } - public unsafe bool TrySkipString() - { - if (!CanRead(2)) - return false; - - int size = 0; - fixed (byte* ptr = &Buffer[ReadPosition]) - size = *((ushort*)ptr); - ReadPosition += 2; - - if (!CanRead(size)) - return false; - - ReadPosition += size; - return true; - } - - public int NumberOfBytesReadable - { - get => WritePosition - ReadPosition; - } - public void SkipWriting(int size) - { - EnsureWriteBufferSize(size); - WritePosition += size; - } - public void SkipReading(int size) - { - ReadPosition += size; - } - - // -------- Finalizing ------ - public byte[] AsByteArrayData() - { - var data = new byte[this.WritePosition]; - System.Array.Copy(this.Buffer, 0, data, 0, this.WritePosition); - return data; - } - public void Reset() - { - this.ReadPosition = 0; - this.WritePosition = 0; - } - public void Dispose() - { - if (InPool) - return; - InPool = true; - - lock (mPool) - mPool.Enqueue(this); - } - - // ------- Pool ----- - private static Queue mPool = new Queue(1024 * 256); - public static Stream Get() - { - lock (mPool) - { - if (mPool.Count > 0) - { - var item = mPool.Dequeue(); - item.WritePosition = 0; - item.ReadPosition = 0; - item.InPool = false; - - return item; - } - } - - return new Stream() - { - Buffer = new byte[DefaultBufferSize], - InPool = false, - ReadPosition = 0, - WritePosition = 0, - }; + var newSize = bufferLenght + Math.Max(requiredSize, 1024); + Array.Resize(ref Buffer, newSize); } } + + // -------- Write ------ + public void Write(byte value) + { + EnsureWriteBufferSize(1); + Buffer[WritePosition] = value; + WritePosition += 1; + } + + public void Write(bool value) + { + EnsureWriteBufferSize(1); + Buffer[WritePosition] = value ? (byte)1 : (byte)0; + WritePosition += 1; + } + + public unsafe void Write(short value) + { + EnsureWriteBufferSize(2); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(short*)ptr = value; + } + + WritePosition += 2; + } + + public unsafe void Write(ushort value) + { + EnsureWriteBufferSize(2); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(ushort*)ptr = value; + } + + WritePosition += 2; + } + + public unsafe void Write(int value) + { + EnsureWriteBufferSize(4); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(int*)ptr = value; + } + + WritePosition += 4; + } + + public unsafe void Write(uint value) + { + EnsureWriteBufferSize(4); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(uint*)ptr = value; + } + + WritePosition += 4; + } + + public unsafe void Write(long value) + { + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(long*)ptr = value; + } + + WritePosition += 8; + } + + public unsafe void Write(ulong value) + { + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(ulong*)ptr = value; + } + + WritePosition += 8; + } + + public unsafe void Write(decimal value) + { + EnsureWriteBufferSize(16); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(decimal*)ptr = value; + } + + WritePosition += 16; + } + + public unsafe void Write(double value) + { + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(double*)ptr = value; + } + + WritePosition += 8; + } + + public unsafe void Write(float value) + { + var intValue = *(int*)&value; + EnsureWriteBufferSize(4); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(int*)ptr = intValue; + } + + WritePosition += 4; + } + + public unsafe void Write(string value) + { + var charCount = value.Length; + fixed (char* strPtr = value) + { + var size = Encoding.UTF8.GetByteCount(strPtr, charCount); + EnsureWriteBufferSize(size + 2); + + + fixed (byte* buffPtr = &Buffer[WritePosition]) + { + *(ushort*)buffPtr = (ushort)size; + Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr + 2, size); + } + + WritePosition += size + 2; + } + } + + public unsafe void Write(DateTime value) + { + var utc = value.ToUniversalTime(); + + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + { + *(long*)ptr = utc.Ticks; + } + + WritePosition += 8; + } + + public void Write(IPAddress value) + { + var ip = value.ToUInt(); + Write(ip); + } + + public void Write(IPEndPoint value) + { + var ip = value.Address.ToUInt(); + + Write(ip); + Write((ushort)value.Port); + } + + public unsafe void WriteRaw(string value) + { + var charCount = value.Length; + fixed (char* strPtr = value) + { + var size = Encoding.UTF8.GetByteCount(strPtr, charCount); + EnsureWriteBufferSize(size); + + fixed (byte* buffPtr = &Buffer[WritePosition]) + { + Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr, size); + } + + WritePosition += size; + } + } + + public void Write(T value) where T : IStreamSerializable + { + value.Write(this); + } + + public void Write(byte[] source, int sourceIndex, int length) + { + if (length == 0) + return; + + EnsureWriteBufferSize(length); + Array.Copy(source, sourceIndex, Buffer, WritePosition, length); + WritePosition += length; + } + + public void Write(Stream source) + { + EnsureWriteBufferSize(source.WritePosition); + Array.Copy(source.Buffer, 0, Buffer, WritePosition, source.WritePosition); + WritePosition += source.WritePosition; + } + + public void WriteStringItem(string value) + { + if (value == null) + Write("none"); + else + Write(value); + } + + public void WriteAt(byte value, int position) + { + Buffer[position] = value; + } + + public unsafe void WriteAt(short value, int position) + { + fixed (byte* ptr = &Buffer[position]) + { + *(short*)ptr = value; + } + } + + public unsafe void WriteAt(ushort value, int position) + { + fixed (byte* ptr = &Buffer[position]) + { + *(ushort*)ptr = value; + } + } + + public unsafe void WriteAt(int value, int position) + { + fixed (byte* ptr = &Buffer[position]) + { + *(int*)ptr = value; + } + } + + public unsafe void WriteAt(uint value, int position) + { + fixed (byte* ptr = &Buffer[position]) + { + *(uint*)ptr = value; + } + } + + public unsafe void WriteAt(long value, int position) + { + fixed (byte* ptr = &Buffer[position]) + { + *(long*)ptr = value; + } + } + + public unsafe void WriteAt(ulong value, int position) + { + fixed (byte* ptr = &Buffer[position]) + { + *(ulong*)ptr = value; + } + } + + // -------- Read ------ + public byte ReadInt8() + { + var value = Buffer[ReadPosition]; + ReadPosition++; + + return value; + } + + public bool ReadBool() + { + var value = Buffer[ReadPosition]; + ReadPosition++; + + return value == 1; + } + + public unsafe short ReadInt16() + { + short value = 0; + + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 2 == 0) + { + value = *(short*)pbyte; + } + else + { + if (IsLittleEndian) + value = (short)(*pbyte | (*(pbyte + 1) << 8)); + else + value = (short)((*pbyte << 8) | *(pbyte + 1)); + } + } + + ReadPosition += 2; + return value; + } + + public unsafe ushort ReadUInt16() + { + ushort value = 0; + + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 2 == 0) + { + value = *(ushort*)pbyte; + } + else + { + if (IsLittleEndian) + value = (ushort)(*pbyte | (*(pbyte + 1) << 8)); + else + value = (ushort)((*pbyte << 8) | *(pbyte + 1)); + } + } + + ReadPosition += 2; + return value; + } + + public unsafe int ReadInt32() + { + var value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 4 == 0) + { + value = *(int*)pbyte; + } + else + { + if (IsLittleEndian) + value = *pbyte | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); + else + value = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | *(pbyte + 3); + } + } + + ReadPosition += 4; + + return value; + } + + public unsafe uint ReadUInt32() + { + uint value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 4 == 0) + { + value = *(uint*)pbyte; + } + else + { + if (IsLittleEndian) + value = (uint)(*pbyte | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); + else + value = (uint)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | *(pbyte + 3)); + } + } + + ReadPosition += 4; + + return value; + } + + public unsafe long ReadInt64() + { + long value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 8 == 0) + { + value = *(long*)pbyte; + } + else + { + if (IsLittleEndian) + { + var i1 = *pbyte | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); + var i2 = *(pbyte + 4) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); + value = (uint)i1 | ((long)i2 << 32); + } + else + { + var i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | *(pbyte + 3); + var i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | *(pbyte + 7); + value = (uint)i2 | ((long)i1 << 32); + } + } + } + + ReadPosition += 8; + + return value; + } + + public unsafe ulong ReadUInt64() + { + ulong value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 8 == 0) + { + value = *(ulong*)pbyte; + } + else + { + if (IsLittleEndian) + { + var i1 = *pbyte | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); + var i2 = *(pbyte + 4) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); + value = (uint)i1 | ((ulong)i2 << 32); + } + else + { + var i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | *(pbyte + 3); + var i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | *(pbyte + 7); + value = (uint)i2 | ((ulong)i1 << 32); + } + } + } + + ReadPosition += 8; + + return value; + } + + public unsafe decimal ReadInt128() + { + decimal value = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + value = *(decimal*)ptr; + } + + ReadPosition += 16; + + return value; + } + + public unsafe double ReadDouble() + { + double value = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + value = *(double*)ptr; + } + + ReadPosition += 8; + + return value; + } + + public unsafe float ReadFloat() + { + var value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 4 == 0) + { + value = *(int*)pbyte; + } + else + { + if (IsLittleEndian) + value = *pbyte | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); + else + value = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | *(pbyte + 3); + } + } + + ReadPosition += 4; + + return *(float*)&value; + } + + public DateTime ReadDateTime() + { + var value = ReadInt64(); + try + { + return new DateTime(value, DateTimeKind.Utc); + } + catch + { + return DateTime.MinValue; + } + } + + public bool TryReadDateTime(out DateTime time) + { + var value = ReadInt64(); + try + { + time = new DateTime(value, DateTimeKind.Utc); + return true; + } + catch + { + } + + time = default; + return false; + } + + public IPAddress ReadIPAddress() + { + var ip = ReadUInt32(); + return new IPAddress(ip); + } + + public IPEndPoint ReadIPEndPoint() + { + var ip = ReadUInt32(); + var port = ReadUInt16(); + + return new IPEndPoint(ip, port); + } + + public T Read() where T : IStreamSerializable + { + T value = default; + value.Read(this); + return value; + } + + public byte[] ReadByteArray(int lenght) + { + if (lenght == 0) + return new byte[0]; + + var newBuffer = new byte[lenght]; + Array.Copy(Buffer, ReadPosition, newBuffer, 0, lenght); + ReadPosition += lenght; + return newBuffer; + } + + public void ReadTo(byte[] buffer, int offset, int size) + { + Array.Copy(Buffer, ReadPosition, buffer, offset, size); + ReadPosition += size; + } + + public unsafe string ReadString(int size) + { + string str; + +#if NETCOREAPP + fixed (byte* ptr = &Buffer[ReadPosition]) + { + str = Encoding.UTF8.GetString(ptr, size); + } +#else + str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); +#endif + ReadPosition += size; + + return str; + } + + public unsafe bool TryReadString(out string str) + { + if (!CanRead(2)) + { + str = null; + return false; + } + + + var size = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + size = *(ushort*)ptr; + } + + ReadPosition += 2; + + if (!CanRead(size)) + { + str = null; + return false; + } + +#if NETCOREAPP + fixed (byte* ptr = &Buffer[ReadPosition]) + { + str = Encoding.UTF8.GetString(ptr, size); + } +#else + str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); +#endif + + ReadPosition += size; + + return true; + } + + public unsafe bool TryReadString(out string str, int maximumSize = ushort.MaxValue) + { + if (!CanRead(2)) + { + str = null; + return false; + } + + + var size = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + size = *(ushort*)ptr; + } + + ReadPosition += 2; + + if (size > maximumSize) + { + str = null; + return false; + } + + if (!CanRead(size)) + { + str = null; + return false; + } + +#if NETCOREAPP + fixed (byte* ptr = &Buffer[ReadPosition]) + { + str = Encoding.UTF8.GetString(ptr, size); + } +#else + str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); +#endif + + ReadPosition += size; + + return true; + } + + public unsafe bool TrySkipString() + { + if (!CanRead(2)) + return false; + + var size = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + size = *(ushort*)ptr; + } + + ReadPosition += 2; + + if (!CanRead(size)) + return false; + + ReadPosition += size; + return true; + } + + public int NumberOfBytesReadable => WritePosition - ReadPosition; + + public void SkipWriting(int size) + { + EnsureWriteBufferSize(size); + WritePosition += size; + } + + public void SkipReading(int size) + { + ReadPosition += size; + } + + // -------- Finalizing ------ + public byte[] AsByteArrayData() + { + var data = new byte[WritePosition]; + Array.Copy(Buffer, 0, data, 0, WritePosition); + return data; + } + + public void Reset() + { + ReadPosition = 0; + WritePosition = 0; + } + + public void Dispose() + { + if (InPool) + return; + InPool = true; + + lock (mPool) + { + mPool.Enqueue(this); + } + } + + // ------- Pool ----- + private static readonly Queue mPool = new(1024 * 256); + + public static Stream Get() + { + lock (mPool) + { + if (mPool.Count > 0) + { + var item = mPool.Dequeue(); + item.WritePosition = 0; + item.ReadPosition = 0; + item.InPool = false; + + return item; + } + } + + return new Stream + { + Buffer = new byte[DefaultBufferSize], + InPool = false, + ReadPosition = 0, + WritePosition = 0 + }; + } } \ No newline at end of file diff --git a/BattleBitAPI/Common/Threading/ThreadSafe.cs b/BattleBitAPI/Common/Threading/ThreadSafe.cs index 23f7431..542ada9 100644 --- a/BattleBitAPI/Common/Threading/ThreadSafe.cs +++ b/BattleBitAPI/Common/Threading/ThreadSafe.cs @@ -1,70 +1,79 @@ -using System; -using System.Collections.Generic; +namespace BattleBitAPI.Common.Threading; -namespace BattleBitAPI.Common.Threading +public class ThreadSafe { - public class ThreadSafe + private readonly ReaderWriterLockSlim mLock; + public T Value; + + public ThreadSafe(T value) { - private System.Threading.ReaderWriterLockSlim mLock; - public T Value; + Value = value; + mLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + } - public ThreadSafe(T value) + public SafeWriteHandle GetWriteHandle() + { + return new SafeWriteHandle(mLock); + } + + public SafeReadHandle GetReadHandle() + { + return new SafeReadHandle(mLock); + } + + /// + /// Swaps current value with new value and returns old one. + /// + /// + /// Old value + public T SwapValue(T newValue) + { + using (new SafeWriteHandle(mLock)) { - this.Value = value; - this.mLock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.SupportsRecursion); - } - - public SafeWriteHandle GetWriteHandle() => new SafeWriteHandle(this.mLock); - public SafeReadHandle GetReadHandle() => new SafeReadHandle(this.mLock); - - /// - /// Swaps current value with new value and returns old one. - /// - /// - /// Old value - public T SwapValue(T newValue) - { - using (new SafeWriteHandle(this.mLock)) - { - var oldValue = this.Value; - this.Value = newValue; - return oldValue; - } + var oldValue = Value; + Value = newValue; + return oldValue; } } - public class SafeWriteHandle : System.IDisposable - { - private System.Threading.ReaderWriterLockSlim mLock; - private bool mDisposed; - public SafeWriteHandle(System.Threading.ReaderWriterLockSlim mLock) - { - this.mLock = mLock; - mLock.EnterWriteLock(); - } - public void Dispose() - { - if (mDisposed) - return; - mDisposed = true; - mLock.ExitWriteLock(); - } - } - public class SafeReadHandle : System.IDisposable - { - private System.Threading.ReaderWriterLockSlim mLock; - private bool mDisposed; - public SafeReadHandle(System.Threading.ReaderWriterLockSlim mLock) - { - this.mLock = mLock; - mLock.EnterReadLock(); - } - public void Dispose() - { - if (mDisposed) - return; - mDisposed = true; +} - mLock.ExitReadLock(); - } +public class SafeWriteHandle : IDisposable +{ + private bool mDisposed; + private readonly ReaderWriterLockSlim mLock; + + public SafeWriteHandle(ReaderWriterLockSlim mLock) + { + this.mLock = mLock; + mLock.EnterWriteLock(); + } + + public void Dispose() + { + if (mDisposed) + return; + mDisposed = true; + mLock.ExitWriteLock(); + } +} + +public class SafeReadHandle : IDisposable +{ + private bool mDisposed; + private readonly ReaderWriterLockSlim mLock; + + public SafeReadHandle(ReaderWriterLockSlim mLock) + { + this.mLock = mLock; + mLock.EnterReadLock(); + } + + public void Dispose() + { + if (mDisposed) + return; + mDisposed = true; + + mLock.ExitReadLock(); } } \ No newline at end of file diff --git a/BattleBitAPI/Networking/NetworkCommuncation.cs b/BattleBitAPI/Networking/NetworkCommuncation.cs deleted file mode 100644 index 428f1a9..0000000 --- a/BattleBitAPI/Networking/NetworkCommuncation.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace BattleBitAPI.Networking -{ - public enum NetworkCommuncation : byte - { - None = 0, - Hail = 1, - Accepted = 2, - Denied = 3, - - ExecuteCommand = 10, - SendPlayerStats = 11, - SpawnPlayer = 12, - SetNewRoomSettings = 13, - RespondPlayerMessage = 14, - SetNewRoundState = 15, - SetPlayerWeapon = 16, - SetPlayerGadget = 17, - - PlayerConnected = 50, - PlayerDisconnected = 51, - OnPlayerTypedMessage = 52, - OnAPlayerDownedAnotherPlayer = 53, - OnPlayerJoining = 54, - SavePlayerStats = 55, - OnPlayerAskingToChangeRole = 56, - OnPlayerChangedRole = 57, - OnPlayerJoinedASquad = 58, - OnPlayerLeftSquad = 59, - OnPlayerChangedTeam = 60, - OnPlayerRequestingToSpawn = 61, - OnPlayerReport = 62, - OnPlayerSpawn = 63, - OnPlayerDie = 64, - NotifyNewMapRotation = 65, - NotifyNewGamemodeRotation = 66, - NotifyNewRoundState = 67, - OnPlayerAskingToChangeTeam = 68, - GameTick = 69, - OnPlayerGivenUp = 70, - OnPlayerRevivedAnother = 71, - } -} diff --git a/BattleBitAPI/Networking/NetworkCommunication.cs b/BattleBitAPI/Networking/NetworkCommunication.cs new file mode 100644 index 0000000..580077e --- /dev/null +++ b/BattleBitAPI/Networking/NetworkCommunication.cs @@ -0,0 +1,41 @@ +namespace BattleBitAPI.Networking; + +public enum NetworkCommunication : byte +{ + None = 0, + Hail = 1, + Accepted = 2, + Denied = 3, + + ExecuteCommand = 10, + SendPlayerStats = 11, + SpawnPlayer = 12, + SetNewRoomSettings = 13, + RespondPlayerMessage = 14, + SetNewRoundState = 15, + SetPlayerWeapon = 16, + SetPlayerGadget = 17, + + PlayerConnected = 50, + PlayerDisconnected = 51, + OnPlayerTypedMessage = 52, + OnAPlayerDownedAnotherPlayer = 53, + OnPlayerJoining = 54, + SavePlayerStats = 55, + OnPlayerAskingToChangeRole = 56, + OnPlayerChangedRole = 57, + OnPlayerJoinedASquad = 58, + OnPlayerLeftSquad = 59, + OnPlayerChangedTeam = 60, + OnPlayerRequestingToSpawn = 61, + OnPlayerReport = 62, + OnPlayerSpawn = 63, + OnPlayerDie = 64, + NotifyNewMapRotation = 65, + NotifyNewGamemodeRotation = 66, + NotifyNewRoundState = 67, + OnPlayerAskingToChangeTeam = 68, + GameTick = 69, + OnPlayerGivenUp = 70, + OnPlayerRevivedAnother = 71 +} \ No newline at end of file diff --git a/BattleBitAPI/Server/GameServer.cs b/BattleBitAPI/Server/GameServer.cs index c3c0169..7bbe71f 100644 --- a/BattleBitAPI/Server/GameServer.cs +++ b/BattleBitAPI/Server/GameServer.cs @@ -1,5 +1,4 @@ -using System.Diagnostics; -using System.Net; +using System.Net; using System.Net.Sockets; using System.Numerics; using System.Text; @@ -7,1014 +6,1102 @@ using BattleBitAPI.Common; using BattleBitAPI.Common.Extentions; using BattleBitAPI.Networking; using CommunityServerAPI.BattleBitAPI; +using Stream = BattleBitAPI.Common.Serialization.Stream; -namespace BattleBitAPI.Server +namespace BattleBitAPI.Server; + +public class GameServer : IDisposable where TPlayer : Player { - public class GameServer : System.IDisposable where TPlayer : Player - { - // ---- Public Variables ---- - public ulong ServerHash => mInternal.ServerHash; - public bool IsConnected => mInternal.IsConnected; - public IPAddress GameIP => mInternal.GameIP; - public int GamePort => mInternal.GamePort; + // ---- Private Variables ---- + private Internal mInternal; - public TcpClient Socket => mInternal.Socket; - public bool IsPasswordProtected => mInternal.IsPasswordProtected; - public string ServerName => mInternal.ServerName; - public string Gamemode => mInternal.Gamemode; - public string Map => mInternal.Map; - public MapSize MapSize => mInternal.MapSize; - public MapDayNight DayNight => mInternal.DayNight; - public int CurrentPlayerCount => mInternal.CurrentPlayerCount; - public int InQueuePlayerCount => mInternal.InQueuePlayerCount; - public int MaxPlayerCount => mInternal.MaxPlayerCount; - public string LoadingScreenText => mInternal.LoadingScreenText; - public string ServerRulesText => mInternal.ServerRulesText; - public ServerSettings ServerSettings => mInternal.ServerSettings; - public MapRotation MapRotation => mInternal.MapRotation; - public GamemodeRotation GamemodeRotation => mInternal.GamemodeRotation; - public RoundSettings RoundSettings => mInternal.RoundSettings; - public string TerminationReason => mInternal.TerminationReason; - public bool ReconnectFlag => mInternal.ReconnectFlag; + // ---- Public Variables ---- + public ulong ServerHash => mInternal.ServerHash; + public bool IsConnected => mInternal.IsConnected; + 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; + public string Map => mInternal.Map; + public MapSize MapSize => mInternal.MapSize; + public MapDayNight DayNight => mInternal.DayNight; + public int CurrentPlayerCount => mInternal.CurrentPlayerCount; + public int InQueuePlayerCount => mInternal.InQueuePlayerCount; + public int MaxPlayerCount => mInternal.MaxPlayerCount; + public string LoadingScreenText => mInternal.LoadingScreenText; + public string ServerRulesText => mInternal.ServerRulesText; + public ServerSettings ServerSettings => mInternal.ServerSettings; + public MapRotation MapRotation => mInternal.MapRotation; + public GamemodeRotation GamemodeRotation => mInternal.GamemodeRotation; + public RoundSettings RoundSettings => mInternal.RoundSettings; + public string TerminationReason => mInternal.TerminationReason; + public bool ReconnectFlag => mInternal.ReconnectFlag; + + // ---- Team ---- + public IEnumerable AllPlayers + { + get + { + var list = new List(mInternal.Players.Values.Count); + lock (mInternal.Players) + { + foreach (var item in mInternal.Players.Values) + list.Add((TPlayer)item); + } + + return list; + } + } + + // ---- Disposing ---- + public void Dispose() + { + if (mInternal.Socket != null) + { + mInternal.Socket.SafeClose(); + mInternal.Socket = null; + } + } + + // ---- Tick ---- + public async Task Tick() + { + if (!IsConnected) + return; + + if (mInternal.IsDirtyRoomSettings) + { + mInternal.IsDirtyRoomSettings = false; + + //Send new settings + using (var pck = Stream.Get()) + { + pck.Write((byte)NetworkCommunication.SetNewRoomSettings); + mInternal._RoomSettings.Write(pck); + WriteToSocket(pck); + } + } + + if (mInternal.IsDirtyMapRotation) + { + mInternal.IsDirtyMapRotation = false; + mInternal.mBuilder.Clear(); + + mInternal.mBuilder.Append("setmaprotation "); + lock (mInternal._MapRotation) + { + foreach (var map in mInternal._MapRotation) + { + mInternal.mBuilder.Append(map); + mInternal.mBuilder.Append(','); + } + } + + ExecuteCommand(mInternal.mBuilder.ToString()); + } + + if (mInternal.IsDirtyGamemodeRotation) + { + mInternal.IsDirtyGamemodeRotation = false; + mInternal.mBuilder.Clear(); + + mInternal.mBuilder.Append("setgamemoderotation "); + lock (mInternal._GamemodeRotation) + { + foreach (var gamemode in mInternal._GamemodeRotation) + { + mInternal.mBuilder.Append(gamemode); + mInternal.mBuilder.Append(','); + } + } + + ExecuteCommand(mInternal.mBuilder.ToString()); + } + + if (mInternal.IsDirtyRoundSettings) + { + mInternal.IsDirtyRoundSettings = false; + + //Send new round settings + using (var pck = Stream.Get()) + { + pck.Write((byte)NetworkCommunication.SetNewRoundState); + mInternal._RoundSettings.Write(pck); + WriteToSocket(pck); + } + } + + try + { + //Are we still connected on socket level? + if (!Socket.Connected) + { + mClose("Connection was terminated."); + return; + } + + //Did user requested to close connection? + if (mInternal.mWantsToCloseConnection) + { + mClose(TerminationReason); + return; + } + + var networkStream = Socket.GetStream(); + + //Read network packages. + while (Socket.Available > 0) + { + mInternal.mLastPackageReceived = Extentions.TickCount; + + //Do we know the package size? + if (mInternal.mReadPackageSize == 0) + { + const int sizeToRead = 4; + var leftSizeToRead = sizeToRead - mInternal.mReadStream.WritePosition; + + var read = await networkStream.ReadAsync(mInternal.mReadStream.Buffer, mInternal.mReadStream.WritePosition, leftSizeToRead); + if (read <= 0) + throw new Exception("Connection was terminated."); + + mInternal.mReadStream.WritePosition += read; + + //Did we receive the package? + if (mInternal.mReadStream.WritePosition >= 4) + { + //Read the package size + mInternal.mReadPackageSize = mInternal.mReadStream.ReadUInt32(); + + if (mInternal.mReadPackageSize > Const.MaxNetworkPackageSize) + throw new Exception("Incoming package was larger than 'Conts.MaxNetworkPackageSize'"); + + mInternal.mReadStream.Reset(); + } + } + else + { + var sizeToRead = (int)mInternal.mReadPackageSize; + var leftSizeToRead = sizeToRead - mInternal.mReadStream.WritePosition; + + var read = await networkStream.ReadAsync(mInternal.mReadStream.Buffer, mInternal.mReadStream.WritePosition, leftSizeToRead); + if (read <= 0) + throw new Exception("Connection was terminated."); + + mInternal.mReadStream.WritePosition += read; + + //Do we have the package? + if (mInternal.mReadStream.WritePosition >= mInternal.mReadPackageSize) + { + mInternal.mReadPackageSize = 0; + + await mInternal.mExecutionFunc(this, mInternal, mInternal.mReadStream); + + //Reset + mInternal.mReadStream.Reset(); + } + } + } + + //Send the network packages. + if (mInternal.mWriteStream.WritePosition > 0) + lock (mInternal.mWriteStream) + { + if (mInternal.mWriteStream.WritePosition > 0) + { + networkStream.WriteAsync(mInternal.mWriteStream.Buffer, 0, mInternal.mWriteStream.WritePosition); + mInternal.mWriteStream.WritePosition = 0; + + mInternal.mLastPackageSent = Extentions.TickCount; + } + } + + //Are we timed out? + if (Extentions.TickCount - mInternal.mLastPackageReceived > Const.NetworkTimeout) + throw new Exception("Timedout."); + + //Send keep alive if needed + if (Extentions.TickCount - mInternal.mLastPackageSent > Const.NetworkKeepAlive) + { + //Send keep alive. + await networkStream.WriteAsync(mInternal.mKeepAliveBuffer, 0, 4); + await networkStream.FlushAsync(); + mInternal.mLastPackageSent = Extentions.TickCount; + } + } + catch (Exception e) + { + mClose(e.Message); + } + } + + public bool TryGetPlayer(ulong steamID, out TPlayer player) + { + lock (mInternal.Players) + { + if (mInternal.Players.TryGetValue(steamID, out var _player)) + { + player = (TPlayer)_player; + return true; + } + } + + player = default; + return false; + } + + // ---- Virtual ---- + public virtual async Task OnConnected() + { + } + + public virtual async Task OnTick() + { + } + + public virtual async Task OnReconnected() + { + } + + public virtual async Task OnDisconnected() + { + } + + public virtual async Task OnPlayerConnected(TPlayer player) + { + } + + public virtual async Task OnPlayerDisconnected(TPlayer player) + { + } + + public virtual async Task OnPlayerTypedMessage(TPlayer player, ChatChannel channel, string msg) + { + return true; + } + + public virtual async Task OnPlayerJoiningToServer(ulong steamID, PlayerJoiningArguments args) + { + } + + public virtual async Task OnSavePlayerStats(ulong steamID, PlayerStats stats) + { + } + + public virtual async Task OnPlayerRequestingToChangeRole(TPlayer player, GameRole requestedRole) + { + return true; + } + + public virtual async Task OnPlayerRequestingToChangeTeam(TPlayer player, Team requestedTeam) + { + return true; + } + + public virtual async Task OnPlayerChangedRole(TPlayer player, GameRole role) + { + } + + public virtual async Task OnPlayerJoinedSquad(TPlayer player, Squads squad) + { + } + + public virtual async Task OnPlayerLeftSquad(TPlayer player, Squads squad) + { + } + + public virtual async Task OnPlayerChangeTeam(TPlayer player, Team team) + { + } + + public virtual async Task OnPlayerSpawning(TPlayer player, OnPlayerSpawnArguments request) + { + return request; + } + + public virtual async Task OnPlayerSpawned(TPlayer player) + { + } + + public virtual async Task OnPlayerDied(TPlayer player) + { + } + + public virtual async Task OnPlayerGivenUp(TPlayer player) + { + } + + public virtual async Task OnAPlayerDownedAnotherPlayer(OnPlayerKillArguments args) + { + } + + public virtual async Task OnAPlayerRevivedAnotherPlayer(TPlayer from, TPlayer to) + { + } + + public virtual async Task OnPlayerReported(TPlayer from, TPlayer to, ReportReason reason, string additional) + { + } + + public virtual async Task OnGameStateChanged(GameState oldState, GameState newState) + { + } + + public virtual async Task OnRoundStarted() + { + } + + public virtual async Task OnRoundEnded() + { + } + + // ---- Functions ---- + public void WriteToSocket(Stream pck) + { + lock (mInternal.mWriteStream) + { + mInternal.mWriteStream.Write((uint)pck.WritePosition); + mInternal.mWriteStream.Write(pck.Buffer, 0, pck.WritePosition); + } + } + + public void ExecuteCommand(string cmd) + { + if (string.IsNullOrWhiteSpace(cmd)) + return; + + var bytesLong = Encoding.UTF8.GetByteCount(cmd); + lock (mInternal.mWriteStream) + { + mInternal.mWriteStream.Write((uint)(1 + 2 + bytesLong)); + mInternal.mWriteStream.Write((byte)NetworkCommunication.ExecuteCommand); + mInternal.mWriteStream.Write(cmd); + } + } + + public void SetNewPassword(string newPassword) + { + ExecuteCommand("setpass " + newPassword); + } + + public void SetPingLimit(int newPing) + { + ExecuteCommand("setmaxping " + newPing); + } + + public void AnnounceShort(string msg) + { + ExecuteCommand("an " + msg); + } + + public void AnnounceLong(string msg) + { + ExecuteCommand("ann " + msg); + } + + public void UILogOnServer(string msg, float messageLifetime) + { + ExecuteCommand("serverlog " + msg + " " + messageLifetime); + } + + public void ForceStartGame() + { + ExecuteCommand("forcestart"); + } + + public void ForceEndGame() + { + ExecuteCommand("endgame"); + } + + public void SayToChat(string msg) + { + ExecuteCommand("say " + msg); + } + + public void StopServer() + { + ExecuteCommand("stop"); + } + + public void CloseServer() + { + ExecuteCommand("notifyend"); + } + + public void KickAllPlayers() + { + ExecuteCommand("kick all"); + } + + public void Kick(ulong steamID, string reason) + { + ExecuteCommand("kick " + steamID + " " + reason); + } + + public void Kick(Player player, string reason) + { + Kick(player.SteamID, reason); + } + + public void Kill(ulong steamID) + { + ExecuteCommand("kill " + steamID); + } + + public void Kill(Player player) + { + Kill(player.SteamID); + } + + public void ChangeTeam(ulong steamID) + { + ExecuteCommand("changeteam " + steamID); + } + + public void ChangeTeam(Player player) + { + ChangeTeam(player.SteamID); + } + + public void ChangeTeam(ulong steamID, Team team) + { + if (team == Team.TeamA) + ExecuteCommand("changeteam " + steamID + " a"); + else if (team == Team.TeamB) + ExecuteCommand("changeteam " + steamID + " b"); + } + + public void ChangeTeam(Player player, Team team) + { + ChangeTeam(player.SteamID, team); + } + + public void KickFromSquad(ulong steamID) + { + ExecuteCommand("squadkick " + steamID); + } + + public void KickFromSquad(Player player) + { + KickFromSquad(player.SteamID); + } + + public void JoinSquad(ulong steamID, Squads targetSquad) + { + ExecuteCommand("setsquad " + steamID + " " + (int)targetSquad); + } + + public void JoinSquad(Player player, Squads targetSquad) + { + JoinSquad(player.SteamID, targetSquad); + } + + public void DisbandPlayerSquad(ulong steamID) + { + ExecuteCommand("squaddisband " + steamID); + } + + public void DisbandPlayerCurrentSquad(Player player) + { + DisbandPlayerSquad(player.SteamID); + } + + public void PromoteSquadLeader(ulong steamID) + { + ExecuteCommand("squadpromote " + steamID); + } + + public void PromoteSquadLeader(Player player) + { + PromoteSquadLeader(player.SteamID); + } + + public void WarnPlayer(ulong steamID, string msg) + { + ExecuteCommand("warn " + steamID + " " + msg); + } + + public void WarnPlayer(Player player, string msg) + { + WarnPlayer(player.SteamID, msg); + } + + public void MessageToPlayer(ulong steamID, string msg) + { + ExecuteCommand("msg " + steamID + " " + msg); + } + + public void MessageToPlayer(Player player, string msg) + { + MessageToPlayer(player.SteamID, msg); + } + + public void MessageToPlayer(ulong steamID, string msg, float fadeOutTime) + { + ExecuteCommand("msgf " + steamID + " " + fadeOutTime + " " + msg); + } + + public void MessageToPlayer(Player player, string msg, float fadeOutTime) + { + MessageToPlayer(player.SteamID, msg, fadeOutTime); + } + + public void SetRoleTo(ulong steamID, GameRole role) + { + ExecuteCommand("setrole " + steamID + " " + role); + } + + public void SetRoleTo(Player player, GameRole role) + { + SetRoleTo(player.SteamID, role); + } + + public void SpawnPlayer(ulong steamID, PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) + { + var request = new OnPlayerSpawnArguments + { + Loadout = loadout, + Wearings = wearings, + RequestedPoint = PlayerSpawningPosition.Null, + SpawnPosition = position, + LookDirection = lookDirection, + SpawnStand = stand, + SpawnProtection = spawnProtection + }; + + //Respond back. + using (var response = Stream.Get()) + { + response.Write((byte)NetworkCommunication.SpawnPlayer); + response.Write(steamID); + request.Write(response); + response.Write((ushort)0); + + WriteToSocket(response); + } + } + + public void SpawnPlayer(Player player, PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) + { + SpawnPlayer(player.SteamID, loadout, wearings, position, lookDirection, stand, spawnProtection); + } + + public void SetHP(ulong steamID, float newHP) + { + ExecuteCommand("sethp " + steamID + " " + newHP); + } + + public void SetHP(Player player, float newHP) + { + SetHP(player.SteamID, newHP); + } + + public void GiveDamage(ulong steamID, float damage) + { + ExecuteCommand("givedamage " + steamID + " " + damage); + } + + public void GiveDamage(Player player, float damage) + { + GiveDamage(player.SteamID, damage); + } + + public void Heal(ulong steamID, float heal) + { + ExecuteCommand("heal " + steamID + " " + heal); + } + + public void Heal(Player player, float heal) + { + 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) + { + using (var packet = Stream.Get()) + { + packet.Write((byte)NetworkCommunication.SetPlayerWeapon); + packet.Write(steamID); + packet.Write((byte)0); //Primary + item.Write(packet); + packet.Write((byte)extraMagazines); + packet.Write(clear); + + WriteToSocket(packet); + } + } + + public void SetPrimaryWeapon(Player player, WeaponItem item, int extraMagazines, bool clear = false) + { + SetPrimaryWeapon(player.SteamID, item, extraMagazines, clear); + } + + public void SetSecondaryWeapon(ulong steamID, WeaponItem item, int extraMagazines, bool clear = false) + { + using (var packet = Stream.Get()) + { + packet.Write((byte)NetworkCommunication.SetPlayerWeapon); + packet.Write(steamID); + packet.Write((byte)1); //Secondary + item.Write(packet); + packet.Write((byte)extraMagazines); + packet.Write(clear); + + WriteToSocket(packet); + } + } + + public void SetSecondaryWeapon(Player player, WeaponItem item, int extraMagazines, bool clear = false) + { + SetSecondaryWeapon(player.SteamID, item, extraMagazines, clear); + } + + public void SetFirstAid(ulong steamID, string tool, int extra, bool clear = false) + { + using (var packet = Stream.Get()) + { + packet.Write((byte)NetworkCommunication.SetPlayerGadget); + packet.Write(steamID); + packet.Write((byte)2); //first aid + packet.Write(tool); + packet.Write((byte)extra); + packet.Write(clear); + + WriteToSocket(packet); + } + } + + public void SetFirstAid(Player player, string tool, int extra, bool clear = false) + { + SetFirstAid(player.SteamID, tool, extra, clear); + } + + public void SetLightGadget(ulong steamID, string tool, int extra, bool clear = false) + { + using (var packet = Stream.Get()) + { + packet.Write((byte)NetworkCommunication.SetPlayerGadget); + packet.Write(steamID); + packet.Write((byte)3); //Tool A + packet.Write(tool); + packet.Write((byte)extra); + packet.Write(clear); + + WriteToSocket(packet); + } + } + + public void SetLightGadget(Player player, string tool, int extra, bool clear = false) + { + SetLightGadget(player.SteamID, tool, extra, clear); + } + + public void SetHeavyGadget(ulong steamID, string tool, int extra, bool clear = false) + { + using (var packet = Stream.Get()) + { + packet.Write((byte)NetworkCommunication.SetPlayerGadget); + packet.Write(steamID); + packet.Write((byte)4); //Tool A + packet.Write(tool); + packet.Write((byte)extra); + packet.Write(clear); + + WriteToSocket(packet); + } + } + + public void SetHeavyGadget(Player player, string tool, int extra, bool clear = false) + { + SetHeavyGadget(player.SteamID, tool, extra, clear); + } + + public void SetThrowable(ulong steamID, string tool, int extra, bool clear = false) + { + using (var packet = Stream.Get()) + { + packet.Write((byte)NetworkCommunication.SetPlayerGadget); + packet.Write(steamID); + packet.Write((byte)5); //Tool A + packet.Write(tool); + packet.Write((byte)extra); + packet.Write(clear); + + WriteToSocket(packet); + } + } + + public void SetThrowable(Player player, string tool, int extra, bool clear = false) + { + SetThrowable(player.SteamID, tool, extra, clear); + } + + // ---- Closing ---- + public void CloseConnection(string additionInfo = "") + { + if (string.IsNullOrWhiteSpace(additionInfo)) + mInternal.TerminationReason = additionInfo; + else + mInternal.TerminationReason = "User requested to terminate the connection"; + mInternal.mWantsToCloseConnection = true; + } + + private void mClose(string reason) + { + if (IsConnected) + { + mInternal.TerminationReason = reason; + mInternal.IsConnected = false; + } + } + + // ---- Overrides ---- + public override string ToString() + { + return + GameIP + ":" + GamePort + " - " + + ServerName; + } + + // ---- Static ---- + public static TGameServer CreateInstance(Internal @internal) where TGameServer : GameServer + { + var gameServer = (TGameServer)Activator.CreateInstance(typeof(TGameServer)); + gameServer.mInternal = @internal; + return gameServer; + } + + // ---- Internal ---- + public class Internal + { + // ---- Gamemode Rotation ---- + public HashSet _GamemodeRotation = new(8); + + // ---- Map Rotation ---- + public HashSet _MapRotation = new(8); + + // ---- Room Settings ---- + public mRoomSettings _RoomSettings = new(); + + // ---- Round Settings ---- + public mRoundSettings _RoundSettings = new(); + public int CurrentPlayerCount; + public MapDayNight DayNight; + public IPAddress GameIP; + public string Gamemode; + public GamemodeRotation GamemodeRotation; + public int GamePort; + public int InQueuePlayerCount; + public bool IsConnected; + public bool IsDirtyGamemodeRotation; + public bool IsDirtyMapRotation; + public bool IsDirtyRoomSettings; + public bool IsDirtyRoundSettings; + public bool IsPasswordProtected; + public string LoadingScreenText; + public string Map; + public MapRotation MapRotation; + public MapSize MapSize; + public int MaxPlayerCount; + public StringBuilder mBuilder; + public Func, Internal, Stream, Task> mExecutionFunc; // ---- Private Variables ---- - private Internal mInternal; + public byte[] mKeepAliveBuffer; + public long mLastPackageReceived; + public long mLastPackageSent; + public uint mReadPackageSize; + public Stream mReadStream; + public bool mWantsToCloseConnection; + public Stream mWriteStream; - // ---- Tick ---- - public async Task Tick() + // ---- Players In Room ---- + public Dictionary> Players = new(254); + public bool ReconnectFlag; + + public RoundSettings RoundSettings; + + // ---- Variables ---- + public ulong ServerHash; + public string ServerName; + public string ServerRulesText; + public ServerSettings ServerSettings; + public TcpClient Socket; + public string TerminationReason; + + public Internal() { - if (!this.IsConnected) - return; - - if (this.mInternal.IsDirtyRoomSettings) + TerminationReason = string.Empty; + mWriteStream = new Stream { - this.mInternal.IsDirtyRoomSettings = false; - - //Send new settings - using (var pck = Common.Serialization.Stream.Get()) - { - pck.Write((byte)NetworkCommuncation.SetNewRoomSettings); - this.mInternal._RoomSettings.Write(pck); - WriteToSocket(pck); - } - } - if (this.mInternal.IsDirtyMapRotation) - { - this.mInternal.IsDirtyMapRotation = false; - this.mInternal.mBuilder.Clear(); - - this.mInternal.mBuilder.Append("setmaprotation "); - lock (this.mInternal._MapRotation) - foreach (var map in this.mInternal._MapRotation) - { - this.mInternal.mBuilder.Append(map); - this.mInternal.mBuilder.Append(','); - } - this.ExecuteCommand(this.mInternal.mBuilder.ToString()); - } - if (this.mInternal.IsDirtyGamemodeRotation) - { - this.mInternal.IsDirtyGamemodeRotation = false; - this.mInternal.mBuilder.Clear(); - - this.mInternal.mBuilder.Append("setgamemoderotation "); - lock (this.mInternal._GamemodeRotation) - { - foreach (var gamemode in this.mInternal._GamemodeRotation) - { - this.mInternal.mBuilder.Append(gamemode); - this.mInternal.mBuilder.Append(','); - } - } - this.ExecuteCommand(this.mInternal.mBuilder.ToString()); - } - if (this.mInternal.IsDirtyRoundSettings) - { - this.mInternal.IsDirtyRoundSettings = false; - - //Send new round settings - using (var pck = Common.Serialization.Stream.Get()) - { - pck.Write((byte)NetworkCommuncation.SetNewRoundState); - this.mInternal._RoundSettings.Write(pck); - WriteToSocket(pck); - } - } - - try - { - //Are we still connected on socket level? - if (!Socket.Connected) - { - mClose("Connection was terminated."); - return; - } - - //Did user requested to close connection? - if (this.mInternal.mWantsToCloseConnection) - { - mClose(this.TerminationReason); - return; - } - - var networkStream = Socket.GetStream(); - - //Read network packages. - while (Socket.Available > 0) - { - this.mInternal.mLastPackageReceived = Extentions.TickCount; - - //Do we know the package size? - if (this.mInternal.mReadPackageSize == 0) - { - const int sizeToRead = 4; - int leftSizeToRead = sizeToRead - this.mInternal.mReadStream.WritePosition; - - int read = await networkStream.ReadAsync(this.mInternal.mReadStream.Buffer, this.mInternal.mReadStream.WritePosition, leftSizeToRead); - if (read <= 0) - throw new Exception("Connection was terminated."); - - this.mInternal.mReadStream.WritePosition += read; - - //Did we receive the package? - if (this.mInternal.mReadStream.WritePosition >= 4) - { - //Read the package size - this.mInternal.mReadPackageSize = this.mInternal.mReadStream.ReadUInt32(); - - if (this.mInternal.mReadPackageSize > Const.MaxNetworkPackageSize) - throw new Exception("Incoming package was larger than 'Conts.MaxNetworkPackageSize'"); - - this.mInternal.mReadStream.Reset(); - } - } - else - { - int sizeToRead = (int)this.mInternal.mReadPackageSize; - int leftSizeToRead = sizeToRead - this.mInternal.mReadStream.WritePosition; - - int read = await networkStream.ReadAsync(this.mInternal.mReadStream.Buffer, this.mInternal.mReadStream.WritePosition, leftSizeToRead); - if (read <= 0) - throw new Exception("Connection was terminated."); - - this.mInternal.mReadStream.WritePosition += read; - - //Do we have the package? - if (this.mInternal.mReadStream.WritePosition >= this.mInternal.mReadPackageSize) - { - this.mInternal.mReadPackageSize = 0; - - await this.mInternal.mExecutionFunc(this, this.mInternal, this.mInternal.mReadStream); - - //Reset - this.mInternal.mReadStream.Reset(); - } - } - } - - //Send the network packages. - if (this.mInternal.mWriteStream.WritePosition > 0) - { - lock (this.mInternal.mWriteStream) - { - if (this.mInternal.mWriteStream.WritePosition > 0) - { - networkStream.WriteAsync(this.mInternal.mWriteStream.Buffer, 0, this.mInternal.mWriteStream.WritePosition); - this.mInternal.mWriteStream.WritePosition = 0; - - this.mInternal.mLastPackageSent = Extentions.TickCount; - } - } - } - - //Are we timed out? - if ((Extentions.TickCount - this.mInternal.mLastPackageReceived) > Const.NetworkTimeout) - throw new Exception("Timedout."); - - //Send keep alive if needed - if ((Extentions.TickCount - this.mInternal.mLastPackageSent) > Const.NetworkKeepAlive) - { - //Send keep alive. - await networkStream.WriteAsync(this.mInternal.mKeepAliveBuffer, 0, 4); - await networkStream.FlushAsync(); - this.mInternal.mLastPackageSent = Extentions.TickCount; - } - } - catch (Exception e) - { - mClose(e.Message); - } - } - - // ---- Team ---- - public IEnumerable AllPlayers - { - get - { - var list = new List(this.mInternal.Players.Values.Count); - lock (this.mInternal.Players) - { - foreach (var item in this.mInternal.Players.Values) - list.Add((TPlayer)item); - } - return list; - } - } - public bool TryGetPlayer(ulong steamID, out TPlayer player) - { - lock (this.mInternal.Players) - { - if (this.mInternal.Players.TryGetValue(steamID, out var _player)) - { - player = (TPlayer)_player; - return true; - } - } - - player = default; - return false; - } - - // ---- Virtual ---- - public virtual async Task OnConnected() - { - - } - public virtual async Task OnTick() - { - - } - public virtual async Task OnReconnected() - { - - } - public virtual async Task OnDisconnected() - { - - } - public virtual async Task OnPlayerConnected(TPlayer player) - { - - } - public virtual async Task OnPlayerDisconnected(TPlayer player) - { - - } - public virtual async Task OnPlayerTypedMessage(TPlayer player, ChatChannel channel, string msg) - { - return true; - } - public virtual async Task OnPlayerJoiningToServer(ulong steamID, PlayerJoiningArguments args) - { - } - public virtual async Task OnSavePlayerStats(ulong steamID, PlayerStats stats) - { - - } - public virtual async Task OnPlayerRequestingToChangeRole(TPlayer player, GameRole requestedRole) - { - return true; - } - public virtual async Task OnPlayerRequestingToChangeTeam(TPlayer player, Team requestedTeam) - { - return true; - } - public virtual async Task OnPlayerChangedRole(TPlayer player, GameRole role) - { - - } - public virtual async Task OnPlayerJoinedSquad(TPlayer player, Squads squad) - { - - } - public virtual async Task OnPlayerLeftSquad(TPlayer player, Squads squad) - { - - } - public virtual async Task OnPlayerChangeTeam(TPlayer player, Team team) - { - - } - public virtual async Task OnPlayerSpawning(TPlayer player, OnPlayerSpawnArguments request) - { - return request; - } - public virtual async Task OnPlayerSpawned(TPlayer player) - { - - } - public virtual async Task OnPlayerDied(TPlayer player) - { - - } - public virtual async Task OnPlayerGivenUp(TPlayer player) - { - - } - public virtual async Task OnAPlayerDownedAnotherPlayer(OnPlayerKillArguments args) - { - - } - public virtual async Task OnAPlayerRevivedAnotherPlayer(TPlayer from,TPlayer to) - { - - } - public virtual async Task OnPlayerReported(TPlayer from, TPlayer to, ReportReason reason, string additional) - { - - } - public virtual async Task OnGameStateChanged(GameState oldState, GameState newState) - { - - } - public virtual async Task OnRoundStarted() - { - - } - public virtual async Task OnRoundEnded() - { - - } - - // ---- Functions ---- - public void WriteToSocket(Common.Serialization.Stream pck) - { - lock (this.mInternal.mWriteStream) - { - this.mInternal.mWriteStream.Write((uint)pck.WritePosition); - this.mInternal.mWriteStream.Write(pck.Buffer, 0, pck.WritePosition); - } - } - public void ExecuteCommand(string cmd) - { - if (string.IsNullOrWhiteSpace(cmd)) - return; - - int bytesLong = System.Text.Encoding.UTF8.GetByteCount(cmd); - lock (this.mInternal.mWriteStream) - { - this.mInternal.mWriteStream.Write((uint)(1 + 2 + bytesLong)); - this.mInternal.mWriteStream.Write((byte)NetworkCommuncation.ExecuteCommand); - this.mInternal.mWriteStream.Write(cmd); - } - } - - public void SetNewPassword(string newPassword) - { - ExecuteCommand("setpass " + newPassword); - } - public void SetPingLimit(int newPing) - { - ExecuteCommand("setmaxping " + newPing); - } - public void AnnounceShort(string msg) - { - ExecuteCommand("an " + msg); - } - public void AnnounceLong(string msg) - { - ExecuteCommand("ann " + msg); - } - public void UILogOnServer(string msg, float messageLifetime) - { - ExecuteCommand("serverlog " + msg + " " + messageLifetime); - } - public void ForceStartGame() - { - ExecuteCommand("forcestart"); - } - public void ForceEndGame() - { - ExecuteCommand("endgame"); - } - public void SayToChat(string msg) - { - ExecuteCommand("say " + msg); - } - - public void StopServer() - { - ExecuteCommand("stop"); - } - public void CloseServer() - { - ExecuteCommand("notifyend"); - } - public void KickAllPlayers() - { - ExecuteCommand("kick all"); - } - public void Kick(ulong steamID, string reason) - { - ExecuteCommand("kick " + steamID + " " + reason); - } - public void Kick(Player player, string reason) - { - Kick(player.SteamID, reason); - } - public void Kill(ulong steamID) - { - ExecuteCommand("kill " + steamID); - } - public void Kill(Player player) - { - Kill(player.SteamID); - } - public void ChangeTeam(ulong steamID) - { - ExecuteCommand("changeteam " + steamID); - } - public void ChangeTeam(Player player) - { - ChangeTeam(player.SteamID); - } - public void ChangeTeam(ulong steamID, Team team) - { - if (team == Team.TeamA) - ExecuteCommand("changeteam " + steamID + " a"); - else if (team == Team.TeamB) - ExecuteCommand("changeteam " + steamID + " b"); - } - public void ChangeTeam(Player player, Team team) - { - ChangeTeam(player.SteamID, team); - } - public void KickFromSquad(ulong steamID) - { - ExecuteCommand("squadkick " + steamID); - } - public void KickFromSquad(Player player) - { - KickFromSquad(player.SteamID); - } - public void JoinSquad(ulong steamID, Squads targetSquad) - { - ExecuteCommand("setsquad " + steamID + " " + ((int)targetSquad)); - } - public void JoinSquad(Player player, Squads targetSquad) - { - JoinSquad(player.SteamID, targetSquad); - } - public void DisbandPlayerSquad(ulong steamID) - { - ExecuteCommand("squaddisband " + steamID); - } - public void DisbandPlayerCurrentSquad(Player player) - { - DisbandPlayerSquad(player.SteamID); - } - public void PromoteSquadLeader(ulong steamID) - { - ExecuteCommand("squadpromote " + steamID); - } - public void PromoteSquadLeader(Player player) - { - PromoteSquadLeader(player.SteamID); - } - public void WarnPlayer(ulong steamID, string msg) - { - ExecuteCommand("warn " + steamID + " " + msg); - } - public void WarnPlayer(Player player, string msg) - { - WarnPlayer(player.SteamID, msg); - } - public void MessageToPlayer(ulong steamID, string msg) - { - ExecuteCommand("msg " + steamID + " " + msg); - } - public void MessageToPlayer(Player player, string msg) - { - MessageToPlayer(player.SteamID, msg); - } - public void MessageToPlayer(ulong steamID, string msg, float fadeOutTime) - { - ExecuteCommand("msgf " + steamID + " " + fadeOutTime + " " + msg); - } - public void MessageToPlayer(Player player, string msg, float fadeOutTime) - { - MessageToPlayer(player.SteamID, msg, fadeOutTime); - } - public void SetRoleTo(ulong steamID, GameRole role) - { - ExecuteCommand("setrole " + steamID + " " + role); - } - public void SetRoleTo(Player player, GameRole role) - { - SetRoleTo(player.SteamID, role); - } - public void SpawnPlayer(ulong steamID, PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) - { - var request = new OnPlayerSpawnArguments() - { - Loadout = loadout, - Wearings = wearings, - RequestedPoint = PlayerSpawningPosition.Null, - SpawnPosition = position, - LookDirection = lookDirection, - SpawnStand = stand, - SpawnProtection = spawnProtection + Buffer = new byte[Const.MaxNetworkPackageSize], + InPool = false, + ReadPosition = 0, + WritePosition = 0 }; - - //Respond back. - using (var response = Common.Serialization.Stream.Get()) + mReadStream = new Stream { - response.Write((byte)NetworkCommuncation.SpawnPlayer); - response.Write(steamID); - request.Write(response); - response.Write((ushort)0); - - WriteToSocket(response); - } - } - public void SpawnPlayer(Player player, PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) - { - SpawnPlayer(player.SteamID, loadout, wearings, position, lookDirection, stand, spawnProtection); - } - public void SetHP(ulong steamID, float newHP) - { - ExecuteCommand("sethp " + steamID + " " + newHP); - } - public void SetHP(Player player, float newHP) - { - SetHP(player.SteamID, newHP); - } - public void GiveDamage(ulong steamID, float damage) - { - ExecuteCommand("givedamage " + steamID + " " + damage); - } - public void GiveDamage(Player player, float damage) - { - GiveDamage(player.SteamID, damage); - } - public void Heal(ulong steamID, float heal) - { - ExecuteCommand("heal " + steamID + " " + heal); - } - public void Heal(Player player, float heal) - { - 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) - { - using (var packet = Common.Serialization.Stream.Get()) + Buffer = new byte[Const.MaxNetworkPackageSize], + InPool = false, + ReadPosition = 0, + WritePosition = 0 + }; + mKeepAliveBuffer = new byte[4] { - packet.Write((byte)NetworkCommuncation.SetPlayerWeapon); - packet.Write(steamID); - packet.Write((byte)0);//Primary - item.Write(packet); - packet.Write((byte)extraMagazines); - packet.Write(clear); + 0, 0, 0, 0 + }; + mLastPackageReceived = Extentions.TickCount; + mLastPackageSent = Extentions.TickCount; + mBuilder = new StringBuilder(4096); - WriteToSocket(packet); - } + ServerSettings = new ServerSettings(this); + MapRotation = new MapRotation(this); + GamemodeRotation = new GamemodeRotation(this); + RoundSettings = new RoundSettings(this); } - public void SetPrimaryWeapon(Player player, WeaponItem item, int extraMagazines, bool clear = false) + + // ---- Public Functions ---- + public void Set(Func, Internal, 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) { - SetPrimaryWeapon(player.SteamID, item, extraMagazines, clear); + ServerHash = ((ulong)port << 32) | iP.ToUInt(); + IsConnected = true; + GameIP = iP; + GamePort = port; + Socket = socket; + mExecutionFunc = func; + IsPasswordProtected = isPasswordProtected; + ServerName = serverName; + Gamemode = gamemode; + Map = map; + MapSize = mapSize; + DayNight = dayNight; + CurrentPlayerCount = currentPlayers; + InQueuePlayerCount = inQueuePlayers; + MaxPlayerCount = maxPlayers; + LoadingScreenText = loadingScreenText; + ServerRulesText = serverRulesText; + + ServerSettings.Reset(); + _RoomSettings.Reset(); + IsDirtyRoomSettings = false; + + MapRotation.Reset(); + _MapRotation.Clear(); + IsDirtyMapRotation = false; + + GamemodeRotation.Reset(); + _GamemodeRotation.Clear(); + IsDirtyGamemodeRotation = false; + + RoundSettings.Reset(); + _RoundSettings.Reset(); + IsDirtyRoundSettings = false; + + TerminationReason = string.Empty; + ReconnectFlag = false; + + mWriteStream.Reset(); + mReadStream.Reset(); + mReadPackageSize = 0; + mLastPackageReceived = Extentions.TickCount; + mLastPackageSent = Extentions.TickCount; + mWantsToCloseConnection = false; + mBuilder.Clear(); } - public void SetSecondaryWeapon(ulong steamID, WeaponItem item, int extraMagazines, bool clear = false) + + public void AddPlayer(Player player) { - using (var packet = Common.Serialization.Stream.Get()) + lock (Players) { - packet.Write((byte)NetworkCommuncation.SetPlayerWeapon); - packet.Write(steamID); - packet.Write((byte)1);//Secondary - item.Write(packet); - packet.Write((byte)extraMagazines); - packet.Write(clear); - - WriteToSocket(packet); - } - } - public void SetSecondaryWeapon(Player player, WeaponItem item, int extraMagazines, bool clear = false) - { - SetSecondaryWeapon(player.SteamID, item, extraMagazines, clear); - } - public void SetFirstAid(ulong steamID, string tool, int extra, bool clear = false) - { - using (var packet = Common.Serialization.Stream.Get()) - { - packet.Write((byte)NetworkCommuncation.SetPlayerGadget); - packet.Write(steamID); - packet.Write((byte)2);//first aid - packet.Write(tool); - packet.Write((byte)extra); - packet.Write(clear); - - WriteToSocket(packet); - } - } - public void SetFirstAid(Player player, string tool, int extra, bool clear = false) - { - SetFirstAid(player.SteamID, tool, extra, clear); - } - public void SetLightGadget(ulong steamID, string tool, int extra, bool clear = false) - { - using (var packet = Common.Serialization.Stream.Get()) - { - packet.Write((byte)NetworkCommuncation.SetPlayerGadget); - packet.Write(steamID); - packet.Write((byte)3);//Tool A - packet.Write(tool); - packet.Write((byte)extra); - packet.Write(clear); - - WriteToSocket(packet); - } - } - public void SetLightGadget(Player player, string tool, int extra, bool clear = false) - { - SetLightGadget(player.SteamID, tool, extra, clear); - } - public void SetHeavyGadget(ulong steamID, string tool, int extra, bool clear = false) - { - using (var packet = Common.Serialization.Stream.Get()) - { - packet.Write((byte)NetworkCommuncation.SetPlayerGadget); - packet.Write(steamID); - packet.Write((byte)4);//Tool A - packet.Write(tool); - packet.Write((byte)extra); - packet.Write(clear); - - WriteToSocket(packet); - } - } - public void SetHeavyGadget(Player player, string tool, int extra, bool clear = false) - { - SetHeavyGadget(player.SteamID, tool, extra, clear); - } - public void SetThrowable(ulong steamID, string tool, int extra, bool clear = false) - { - using (var packet = Common.Serialization.Stream.Get()) - { - packet.Write((byte)NetworkCommuncation.SetPlayerGadget); - packet.Write(steamID); - packet.Write((byte)5);//Tool A - packet.Write(tool); - packet.Write((byte)extra); - packet.Write(clear); - - WriteToSocket(packet); - } - } - public void SetThrowable(Player player, string tool, int extra, bool clear = false) - { - SetThrowable(player.SteamID, tool, extra, clear); - } - - // ---- Closing ---- - public void CloseConnection(string additionInfo = "") - { - if (string.IsNullOrWhiteSpace(additionInfo)) - this.mInternal.TerminationReason = additionInfo; - else - this.mInternal.TerminationReason = "User requested to terminate the connection"; - this.mInternal.mWantsToCloseConnection = true; - } - private void mClose(string reason) - { - if (this.IsConnected) - { - this.mInternal.TerminationReason = reason; - this.mInternal.IsConnected = false; + Players.Remove(player.SteamID); + Players.Add(player.SteamID, player); } } - // ---- Disposing ---- - public void Dispose() + public void RemovePlayer(TPlayer player) where TPlayer : Player { - if (this.mInternal.Socket != null) + lock (Players) { - this.mInternal.Socket.SafeClose(); - this.mInternal.Socket = null; + Players.Remove(player.SteamID); } } - // ---- Overrides ---- - public override string ToString() + public bool TryGetPlayer(ulong steamID, out Player result) { - return - this.GameIP + ":" + this.GamePort + " - " + - this.ServerName; - } - - // ---- Static ---- - public static TGameServer CreateInstance(Internal @internal) where TGameServer : GameServer - { - TGameServer gameServer = (TGameServer)Activator.CreateInstance(typeof(TGameServer)); - gameServer.mInternal = @internal; - return gameServer; - } - - // ---- Internal ---- - public class Internal - { - // ---- Variables ---- - public ulong ServerHash; - public bool IsConnected; - public IPAddress GameIP; - public int GamePort; - public TcpClient Socket; - public Func, Internal, Common.Serialization.Stream, Task> mExecutionFunc; - public bool IsPasswordProtected; - public string ServerName; - public string Gamemode; - public string Map; - public MapSize MapSize; - public MapDayNight DayNight; - public int CurrentPlayerCount; - public int InQueuePlayerCount; - public int MaxPlayerCount; - public string LoadingScreenText; - public string ServerRulesText; - public ServerSettings ServerSettings; - public MapRotation MapRotation; - public GamemodeRotation GamemodeRotation; - public RoundSettings RoundSettings; - public string TerminationReason; - public bool ReconnectFlag; - - // ---- Private Variables ---- - public byte[] mKeepAliveBuffer; - public Common.Serialization.Stream mWriteStream; - public Common.Serialization.Stream mReadStream; - public uint mReadPackageSize; - public long mLastPackageReceived; - public long mLastPackageSent; - public bool mWantsToCloseConnection; - public StringBuilder mBuilder; - - public Internal() + lock (Players) { - this.TerminationReason = string.Empty; - this.mWriteStream = new Common.Serialization.Stream() - { - Buffer = new byte[Const.MaxNetworkPackageSize], - InPool = false, - ReadPosition = 0, - WritePosition = 0, - }; - this.mReadStream = new Common.Serialization.Stream() - { - Buffer = new byte[Const.MaxNetworkPackageSize], - InPool = false, - ReadPosition = 0, - WritePosition = 0, - }; - this.mKeepAliveBuffer = new byte[4] - { - 0,0,0,0, - }; - this.mLastPackageReceived = Extentions.TickCount; - this.mLastPackageSent = Extentions.TickCount; - this.mBuilder = new StringBuilder(4096); - - this.ServerSettings = new ServerSettings(this); - this.MapRotation = new MapRotation(this); - this.GamemodeRotation = new GamemodeRotation(this); - this.RoundSettings = new RoundSettings(this); - } - - // ---- Players In Room ---- - public Dictionary> Players = new Dictionary>(254); - - // ---- Room Settings ---- - public mRoomSettings _RoomSettings = new mRoomSettings(); - public bool IsDirtyRoomSettings; - - // ---- Round Settings ---- - public mRoundSettings _RoundSettings = new mRoundSettings(); - public bool IsDirtyRoundSettings; - - // ---- Map Rotation ---- - public HashSet _MapRotation = new HashSet(8); - public bool IsDirtyMapRotation = false; - - // ---- Gamemode Rotation ---- - public HashSet _GamemodeRotation = new HashSet(8); - 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) - { - this.ServerHash = ((ulong)port << 32) | (ulong)iP.ToUInt(); - this.IsConnected = true; - this.GameIP = iP; - this.GamePort = port; - this.Socket = socket; - this.mExecutionFunc = func; - this.IsPasswordProtected = isPasswordProtected; - this.ServerName = serverName; - this.Gamemode = gamemode; - this.Map = map; - this.MapSize = mapSize; - this.DayNight = dayNight; - this.CurrentPlayerCount = currentPlayers; - this.InQueuePlayerCount = inQueuePlayers; - this.MaxPlayerCount = maxPlayers; - this.LoadingScreenText = loadingScreenText; - this.ServerRulesText = serverRulesText; - - this.ServerSettings.Reset(); - this._RoomSettings.Reset(); - this.IsDirtyRoomSettings = false; - - this.MapRotation.Reset(); - this._MapRotation.Clear(); - this.IsDirtyMapRotation = false; - - this.GamemodeRotation.Reset(); - this._GamemodeRotation.Clear(); - this.IsDirtyGamemodeRotation = false; - - this.RoundSettings.Reset(); - this._RoundSettings.Reset(); - this.IsDirtyRoundSettings = false; - - this.TerminationReason = string.Empty; - this.ReconnectFlag = false; - - this.mWriteStream.Reset(); - this.mReadStream.Reset(); - this.mReadPackageSize = 0; - this.mLastPackageReceived = Extentions.TickCount; - this.mLastPackageSent = Extentions.TickCount; - this.mWantsToCloseConnection = false; - this.mBuilder.Clear(); - } - public void AddPlayer(Player player) - { - lock (Players) - { - Players.Remove(player.SteamID); - Players.Add(player.SteamID, player); - } - } - public void RemovePlayer(TPlayer player) where TPlayer : Player - { - lock (Players) - Players.Remove(player.SteamID); - } - public bool TryGetPlayer(ulong steamID, out Player result) - { - lock (Players) - 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; + return Players.TryGetValue(steamID, out result); } } } -} + + public class mRoomSettings + { + public bool BleedingEnabled = true; + public float CaptureFlagSpeedMultiplier = 1f; + public float DamageMultiplier = 1.0f; + public byte EngineerLimitPerSquad = 8; + public bool FriendlyFireEnabled; + public bool HideMapVotes = true; + public bool HitMarkersEnabled = true; + + public byte MedicLimitPerSquad = 8; + public bool OnlyWinnerTeamCanVote; + public bool PointLogEnabled = true; + public byte ReconLimitPerSquad = 8; + public bool SpectatorEnabled = true; + public bool StaminaEnabled; + public byte SupportLimitPerSquad = 8; + + public void Write(Stream ser) + { + ser.Write(DamageMultiplier); + ser.Write(BleedingEnabled); + ser.Write(StaminaEnabled); + ser.Write(FriendlyFireEnabled); + ser.Write(HideMapVotes); + ser.Write(OnlyWinnerTeamCanVote); + ser.Write(HitMarkersEnabled); + ser.Write(PointLogEnabled); + ser.Write(SpectatorEnabled); + ser.Write(CaptureFlagSpeedMultiplier); + + ser.Write(MedicLimitPerSquad); + ser.Write(EngineerLimitPerSquad); + ser.Write(SupportLimitPerSquad); + ser.Write(ReconLimitPerSquad); + } + + public void Read(Stream ser) + { + DamageMultiplier = ser.ReadFloat(); + BleedingEnabled = ser.ReadBool(); + StaminaEnabled = ser.ReadBool(); + FriendlyFireEnabled = ser.ReadBool(); + HideMapVotes = ser.ReadBool(); + OnlyWinnerTeamCanVote = ser.ReadBool(); + HitMarkersEnabled = ser.ReadBool(); + PointLogEnabled = ser.ReadBool(); + SpectatorEnabled = ser.ReadBool(); + CaptureFlagSpeedMultiplier = ser.ReadFloat(); + + MedicLimitPerSquad = ser.ReadInt8(); + EngineerLimitPerSquad = ser.ReadInt8(); + SupportLimitPerSquad = ser.ReadInt8(); + ReconLimitPerSquad = ser.ReadInt8(); + } + + public void Reset() + { + DamageMultiplier = 1.0f; + BleedingEnabled = true; + StaminaEnabled = false; + FriendlyFireEnabled = false; + HideMapVotes = true; + OnlyWinnerTeamCanVote = false; + HitMarkersEnabled = true; + PointLogEnabled = true; + SpectatorEnabled = true; + + MedicLimitPerSquad = 8; + EngineerLimitPerSquad = 8; + SupportLimitPerSquad = 8; + ReconLimitPerSquad = 8; + } + } + + public class mRoundSettings + { + public const int Size = 1 + 8 + 8 + 8 + 4 + 4; + public double MaxTickets = 1; + public int PlayersToStart = 16; + public int SecondsLeft = 60; + + public GameState State = GameState.WaitingForPlayers; + public double TeamATickets; + public double TeamBTickets; + + public void Write(Stream ser) + { + ser.Write((byte)State); + ser.Write(TeamATickets); + ser.Write(TeamBTickets); + ser.Write(MaxTickets); + ser.Write(PlayersToStart); + ser.Write(SecondsLeft); + } + + public void Read(Stream ser) + { + State = (GameState)ser.ReadInt8(); + TeamATickets = ser.ReadDouble(); + TeamBTickets = ser.ReadDouble(); + MaxTickets = ser.ReadDouble(); + PlayersToStart = ser.ReadInt32(); + SecondsLeft = ser.ReadInt32(); + } + + public void Reset() + { + State = GameState.WaitingForPlayers; + TeamATickets = 0; + TeamBTickets = 0; + MaxTickets = 1; + PlayersToStart = 16; + SecondsLeft = 60; + } + } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/Internal/GamemodeRotation.cs b/BattleBitAPI/Server/Internal/GamemodeRotation.cs index 7c5ee4d..c49813f 100644 --- a/BattleBitAPI/Server/Internal/GamemodeRotation.cs +++ b/BattleBitAPI/Server/Internal/GamemodeRotation.cs @@ -1,66 +1,80 @@ -using BattleBitAPI.Common; -using CommunityServerAPI.BattleBitAPI.Server; +namespace BattleBitAPI.Server; -namespace BattleBitAPI.Server +public class GamemodeRotation where TPlayer : Player { - public class GamemodeRotation where TPlayer : Player + private readonly GameServer.Internal mResources; + + public GamemodeRotation(GameServer.Internal resources) { - private GameServer.Internal mResources; - public GamemodeRotation(GameServer.Internal resources) - { - mResources = resources; - } + mResources = resources; + } - public IEnumerable GetGamemodeRotation() - { - lock (mResources._GamemodeRotation) - return new List(mResources._GamemodeRotation); - } - public bool InRotation(string gamemode) - { - lock (mResources._GamemodeRotation) - return mResources._GamemodeRotation.Contains(gamemode); - } - public bool RemoveFromRotation(string gamemode) - { - lock (mResources._GamemodeRotation) - if (!mResources._GamemodeRotation.Remove(gamemode)) - return false; - mResources.IsDirtyGamemodeRotation = true; - return true; - } - public bool AddToRotation(string gamemode) - { - lock (mResources._GamemodeRotation) - if (!mResources._GamemodeRotation.Add(gamemode)) - return false; - mResources.IsDirtyGamemodeRotation = true; - return true; - } - public void SetRotation(params string[] gamemodes) - { - lock (mResources._GamemodeRotation) - { - mResources._GamemodeRotation.Clear(); - foreach (var item in gamemodes) - mResources._GamemodeRotation.Add(item); - } - mResources.IsDirtyGamemodeRotation = true; - } - public void ClearRotation() - { - lock (mResources._GamemodeRotation) - { - if (mResources._GamemodeRotation.Count == 0) - return; - - mResources._GamemodeRotation.Clear(); - } - mResources.IsDirtyGamemodeRotation = true; - } - - public void Reset() + public IEnumerable GetGamemodeRotation() + { + lock (mResources._GamemodeRotation) { + return new List(mResources._GamemodeRotation); } } -} + + public bool InRotation(string gamemode) + { + lock (mResources._GamemodeRotation) + { + return mResources._GamemodeRotation.Contains(gamemode); + } + } + + public bool RemoveFromRotation(string gamemode) + { + lock (mResources._GamemodeRotation) + { + if (!mResources._GamemodeRotation.Remove(gamemode)) + return false; + } + + mResources.IsDirtyGamemodeRotation = true; + return true; + } + + public bool AddToRotation(string gamemode) + { + lock (mResources._GamemodeRotation) + { + if (!mResources._GamemodeRotation.Add(gamemode)) + return false; + } + + mResources.IsDirtyGamemodeRotation = true; + return true; + } + + public void SetRotation(params string[] gamemodes) + { + lock (mResources._GamemodeRotation) + { + mResources._GamemodeRotation.Clear(); + foreach (var item in gamemodes) + mResources._GamemodeRotation.Add(item); + } + + mResources.IsDirtyGamemodeRotation = true; + } + + public void ClearRotation() + { + lock (mResources._GamemodeRotation) + { + if (mResources._GamemodeRotation.Count == 0) + return; + + mResources._GamemodeRotation.Clear(); + } + + mResources.IsDirtyGamemodeRotation = true; + } + + public void Reset() + { + } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/Internal/MapRotation.cs b/BattleBitAPI/Server/Internal/MapRotation.cs index c718005..71dafaf 100644 --- a/BattleBitAPI/Server/Internal/MapRotation.cs +++ b/BattleBitAPI/Server/Internal/MapRotation.cs @@ -1,71 +1,86 @@ -using CommunityServerAPI.BattleBitAPI.Server; +namespace BattleBitAPI.Server; -namespace BattleBitAPI.Server +public class MapRotation where TPlayer : Player { - public class MapRotation where TPlayer : Player + private readonly GameServer.Internal mResources; + + public MapRotation(GameServer.Internal resources) { - private GameServer.Internal mResources; - public MapRotation(GameServer.Internal resources) - { - mResources = resources; - } + mResources = resources; + } - public IEnumerable GetMapRotation() - { - lock (mResources._MapRotation) - return new List(mResources._MapRotation); - } - public bool InRotation(string map) - { - map = map.ToUpperInvariant(); - - lock (mResources._MapRotation) - return mResources._MapRotation.Contains(map); - } - public bool RemoveFromRotation(string map) - { - map = map.ToUpperInvariant(); - - lock (mResources._MapRotation) - if (!mResources._MapRotation.Remove(map)) - return false; - mResources.IsDirtyMapRotation = true; - return true; - } - public bool AddToRotation(string map) - { - map = map.ToUpperInvariant(); - - lock (mResources._MapRotation) - if (!mResources._MapRotation.Add(map)) - return false; - mResources.IsDirtyMapRotation = true; - return true; - } - public void SetRotation(params string[] maps) - { - lock (mResources._MapRotation) - { - mResources._MapRotation.Clear(); - foreach (var item in maps) - mResources._MapRotation.Add(item); - } - mResources.IsDirtyMapRotation = true; - } - public void ClearRotation() - { - lock (mResources._MapRotation) - { - if (mResources._MapRotation.Count == 0) - return; - - mResources._MapRotation.Clear(); - } - mResources.IsDirtyMapRotation = true; - } - - public void Reset() + public IEnumerable GetMapRotation() + { + lock (mResources._MapRotation) { + return new List(mResources._MapRotation); } } -} + + public bool InRotation(string map) + { + map = map.ToUpperInvariant(); + + lock (mResources._MapRotation) + { + return mResources._MapRotation.Contains(map); + } + } + + public bool RemoveFromRotation(string map) + { + map = map.ToUpperInvariant(); + + lock (mResources._MapRotation) + { + if (!mResources._MapRotation.Remove(map)) + return false; + } + + mResources.IsDirtyMapRotation = true; + return true; + } + + public bool AddToRotation(string map) + { + map = map.ToUpperInvariant(); + + lock (mResources._MapRotation) + { + if (!mResources._MapRotation.Add(map)) + return false; + } + + mResources.IsDirtyMapRotation = true; + return true; + } + + public void SetRotation(params string[] maps) + { + lock (mResources._MapRotation) + { + mResources._MapRotation.Clear(); + foreach (var item in maps) + mResources._MapRotation.Add(item); + } + + mResources.IsDirtyMapRotation = true; + } + + public void ClearRotation() + { + lock (mResources._MapRotation) + { + if (mResources._MapRotation.Count == 0) + return; + + mResources._MapRotation.Clear(); + } + + mResources.IsDirtyMapRotation = true; + } + + public void Reset() + { + } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/Internal/PlayerModifications.cs b/BattleBitAPI/Server/Internal/PlayerModifications.cs index 4f9c77e..75ecd96 100644 --- a/BattleBitAPI/Server/Internal/PlayerModifications.cs +++ b/BattleBitAPI/Server/Internal/PlayerModifications.cs @@ -1,28 +1,28 @@ -namespace BattleBitAPI.Server -{ - public class PlayerModifications where TPlayer : Player - { - private Player.Internal @internal; - public PlayerModifications(Player.Internal @internal) - { - this.@internal = @internal; - } +namespace BattleBitAPI.Server; - 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; } +public class PlayerModifications where TPlayer : Player +{ + 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; } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/Internal/RoundSettings.cs b/BattleBitAPI/Server/Internal/RoundSettings.cs index a25a203..0f1ab65 100644 --- a/BattleBitAPI/Server/Internal/RoundSettings.cs +++ b/BattleBitAPI/Server/Internal/RoundSettings.cs @@ -1,69 +1,69 @@ using BattleBitAPI.Common; -using CommunityServerAPI.BattleBitAPI.Server; -namespace BattleBitAPI.Server +namespace BattleBitAPI.Server; + +public class RoundSettings where TPlayer : Player { - public class RoundSettings where TPlayer : Player + private readonly GameServer.Internal mResources; + + public RoundSettings(GameServer.Internal resources) { - private GameServer.Internal mResources; - public RoundSettings(GameServer.Internal resources) - { - mResources = resources; - } + mResources = resources; + } - public GameState State - { - get => this.mResources._RoundSettings.State; - } - public double TeamATickets - { - get => this.mResources._RoundSettings.TeamATickets; - set - { - this.mResources._RoundSettings.TeamATickets = value; - this.mResources.IsDirtyRoundSettings = true; - } - } - public double TeamBTickets - { - get => this.mResources._RoundSettings.TeamBTickets; - set - { - this.mResources._RoundSettings.TeamBTickets = value; - this.mResources.IsDirtyRoundSettings = true; - } - } - public double MaxTickets - { - get => this.mResources._RoundSettings.MaxTickets; - set - { - this.mResources._RoundSettings.MaxTickets = value; - this.mResources.IsDirtyRoundSettings = true; - } - } - public int PlayersToStart - { - get => this.mResources._RoundSettings.PlayersToStart; - set - { - this.mResources._RoundSettings.PlayersToStart = value; - this.mResources.IsDirtyRoundSettings = true; - } - } - public int SecondsLeft - { - get => this.mResources._RoundSettings.SecondsLeft; - set - { - this.mResources._RoundSettings.SecondsLeft = value; - this.mResources.IsDirtyRoundSettings = true; - } - } + public GameState State => mResources._RoundSettings.State; - public void Reset() + public double TeamATickets + { + get => mResources._RoundSettings.TeamATickets; + set { - + mResources._RoundSettings.TeamATickets = value; + mResources.IsDirtyRoundSettings = true; } } -} + + public double TeamBTickets + { + get => mResources._RoundSettings.TeamBTickets; + set + { + mResources._RoundSettings.TeamBTickets = value; + mResources.IsDirtyRoundSettings = true; + } + } + + public double MaxTickets + { + get => mResources._RoundSettings.MaxTickets; + set + { + mResources._RoundSettings.MaxTickets = value; + mResources.IsDirtyRoundSettings = true; + } + } + + public int PlayersToStart + { + get => mResources._RoundSettings.PlayersToStart; + set + { + mResources._RoundSettings.PlayersToStart = value; + mResources.IsDirtyRoundSettings = true; + } + } + + public int SecondsLeft + { + get => mResources._RoundSettings.SecondsLeft; + set + { + mResources._RoundSettings.SecondsLeft = value; + mResources.IsDirtyRoundSettings = true; + } + } + + public void Reset() + { + } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/Internal/ServerSettings.cs b/BattleBitAPI/Server/Internal/ServerSettings.cs index b84bdf8..7ceae40 100644 --- a/BattleBitAPI/Server/Internal/ServerSettings.cs +++ b/BattleBitAPI/Server/Internal/ServerSettings.cs @@ -1,91 +1,95 @@ -using CommunityServerAPI.BattleBitAPI.Server; +namespace BattleBitAPI.Server; -namespace BattleBitAPI.Server +public class ServerSettings where TPlayer : Player { - public class ServerSettings where TPlayer : Player + private readonly GameServer.Internal mResources; + + public ServerSettings(GameServer.Internal resources) { - private GameServer.Internal mResources; - public ServerSettings(GameServer.Internal resources) - { - mResources = resources; - } + mResources = resources; + } - public float DamageMultiplier + public float DamageMultiplier + { + get => mResources._RoomSettings.DamageMultiplier; + set { - get => mResources._RoomSettings.DamageMultiplier; - set - { - 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 - { - mResources._RoomSettings.FriendlyFireEnabled = value; - mResources.IsDirtyRoomSettings = true; - } - } - public bool OnlyWinnerTeamCanVote - { - get => mResources._RoomSettings.OnlyWinnerTeamCanVote; - set - { - mResources._RoomSettings.OnlyWinnerTeamCanVote = value; - mResources.IsDirtyRoomSettings = true; - } - } - public bool HitMarkersEnabled - { - get => mResources._RoomSettings.HitMarkersEnabled; - 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; - mResources.IsDirtyRoomSettings = true; - } - } - - public void Reset() - { - + 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 + { + mResources._RoomSettings.FriendlyFireEnabled = value; + mResources.IsDirtyRoomSettings = true; + } + } + + public bool OnlyWinnerTeamCanVote + { + get => mResources._RoomSettings.OnlyWinnerTeamCanVote; + set + { + mResources._RoomSettings.OnlyWinnerTeamCanVote = value; + mResources.IsDirtyRoomSettings = true; + } + } + + public bool HitMarkersEnabled + { + get => mResources._RoomSettings.HitMarkersEnabled; + 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; + mResources.IsDirtyRoomSettings = true; + } + } + + public void Reset() + { + } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/Player.cs b/BattleBitAPI/Server/Player.cs index c05f783..cf36df3 100644 --- a/BattleBitAPI/Server/Player.cs +++ b/BattleBitAPI/Server/Player.cs @@ -1,364 +1,395 @@ -using BattleBitAPI.Common; -using BattleBitAPI.Server; -using System.Net; +using System.Net; using System.Numerics; +using BattleBitAPI.Common; +using BattleBitAPI.Server; +using Stream = BattleBitAPI.Common.Serialization.Stream; -namespace BattleBitAPI +namespace BattleBitAPI; + +public class Player where TPlayer : Player { - public class Player where TPlayer : Player + private Internal mInternal; + + // ---- Variables ---- + public ulong SteamID => mInternal.SteamID; + public string Name => mInternal.Name; + public IPAddress IP => mInternal.IP; + public GameServer GameServer => mInternal.GameServer; + + public GameRole Role { - private Internal mInternal; - - // ---- Variables ---- - public ulong SteamID => mInternal.SteamID; - public string Name => mInternal.Name; - public IPAddress IP => mInternal.IP; - public GameServer GameServer => mInternal.GameServer; - public GameRole Role + get => mInternal.Role; + set { - get => mInternal.Role; - set - { - if (value == mInternal.Role) - return; - SetNewRole(value); - } - } - public Team Team - { - get => mInternal.Team; - set - { - if (mInternal.Team != value) - ChangeTeam(value); - } - } - public Squads Squad - { - get => mInternal.Squad; - set - { - if (value == mInternal.Squad) - return; - if (value == Squads.NoSquad) - KickFromSquad(); - else - JoinSquad(value); - } - } - public bool InSquad => mInternal.Squad != Squads.NoSquad; - public int PingMs => mInternal.PingMs; - - public float HP => mInternal.HP; - public bool IsAlive => mInternal.HP >= 0f; - public bool IsUp => mInternal.HP > 0f; - public bool IsDown => mInternal.HP == 0f; - public bool IsDead => mInternal.HP == -1f; - - public Vector3 Position - { - get => mInternal.Position; - set => Teleport(value); - } - public PlayerStand StandingState => mInternal.Standing; - public LeaningSide LeaningState => mInternal.Leaning; - public LoadoutIndex CurrentLoadoutIndex => mInternal.CurrentLoadoutIndex; - public bool InVehicle => mInternal.InVehicle; - public bool IsBleeding => mInternal.IsBleeding; - public PlayerLoadout CurrentLoadout => mInternal.CurrentLoadout; - public PlayerWearings CurrentWearings => mInternal.CurrentWearings; - public PlayerModifications Modifications => mInternal.Modifications; - - // ---- Events ---- - public virtual void OnCreated() - { - - } - - public virtual async Task OnConnected() - { - - } - public virtual async Task OnSpawned() - { - - } - public virtual async Task OnDowned() - { - - } - public virtual async Task OnGivenUp() - { - - } - public virtual async Task OnRevivedByAnotherPlayer() - { - - } - public virtual async Task OnRevivedAnotherPlayer() - { - - } - public virtual async Task OnDied() - { - - } - public virtual async Task OnChangedTeam() - { - - } - public virtual async Task OnChangedRole(GameRole newRole) - { - - } - public virtual async Task OnJoinedSquad(Squads newSquad) - { - - } - public virtual async Task OnLeftSquad(Squads oldSquad) - { - - } - public virtual async Task OnDisconnected() - { - - } - - // ---- Functions ---- - public void Kick(string reason = "") - { - GameServer.Kick(this, reason); - } - public void Kill() - { - GameServer.Kill(this); - } - public void ChangeTeam() - { - GameServer.ChangeTeam(this); - } - public void ChangeTeam(Team team) - { - GameServer.ChangeTeam(this, team); - } - public void KickFromSquad() - { - GameServer.KickFromSquad(this); - } - public void JoinSquad(Squads targetSquad) - { - GameServer.JoinSquad(this, targetSquad); - } - public void DisbandTheSquad() - { - GameServer.DisbandPlayerCurrentSquad(this); - } - public void PromoteToSquadLeader() - { - GameServer.PromoteSquadLeader(this); - } - public void WarnPlayer(string msg) - { - GameServer.WarnPlayer(this, msg); - } - public void Message(string msg) - { - GameServer.MessageToPlayer(this, msg); - } - public void Message(string msg, float fadeoutTime) - { - GameServer.MessageToPlayer(this, msg, fadeoutTime); - } - public void SetNewRole(GameRole role) - { - GameServer.SetRoleTo(this, role); - } - public void Teleport(Vector3 target) - { - - } - public void SpawnPlayer(PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) - { - GameServer.SpawnPlayer(this, loadout, wearings, position, lookDirection, stand, spawnProtection); - } - public void SetHP(float newHP) - { - GameServer.SetHP(this, newHP); - } - public void GiveDamage(float damage) - { - GameServer.GiveDamage(this, damage); - } - public void Heal(float hp) - { - 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); - } - public void SetSecondaryWeapon(WeaponItem item, int extraMagazines, bool clear = false) - { - GameServer.SetSecondaryWeapon(this, item, extraMagazines, clear); - } - public void SetFirstAidGadget(string item, int extra, bool clear = false) - { - GameServer.SetFirstAid(this, item, extra, clear); - } - public void SetLightGadget(string item, int extra, bool clear = false) - { - GameServer.SetLightGadget(this, item, extra, clear); - } - public void SetHeavyGadget(string item, int extra, bool clear = false) - { - GameServer.SetHeavyGadget(this, item, extra, clear); - } - public void SetThrowable(string item, int extra, bool clear = false) - { - GameServer.SetThrowable(this, item, extra, clear); - } - - // ---- Static ---- - public static TPlayer CreateInstance(Player.Internal @internal) where TPlayer : Player - { - TPlayer player = (TPlayer)Activator.CreateInstance(typeof(TPlayer)); - player.mInternal = @internal; - return player; - } - - // ---- Overrides ---- - public override string ToString() - { - return Name + " (" + SteamID + ")"; - } - - // ---- Internal ---- - public class Internal - { - public ulong SteamID; - public string Name; - public IPAddress IP; - public GameServer GameServer; - public GameRole Role; - public Team Team; - public Squads Squad; - public int PingMs = 999; - - public bool IsAlive; - public float HP; - public Vector3 Position; - public PlayerStand Standing; - public LeaningSide Leaning; - public LoadoutIndex CurrentLoadoutIndex; - public bool InVehicle; - public bool IsBleeding; - public PlayerLoadout CurrentLoadout; - public PlayerWearings CurrentWearings; - - public mPlayerModifications _Modifications; - public PlayerModifications Modifications; - - public Internal() - { - this.Modifications = new PlayerModifications(this); - this._Modifications = new mPlayerModifications(); - } - - public void OnDie() - { - IsAlive = false; - HP = -1f; - Position = default; - Standing = PlayerStand.Standing; - Leaning = LeaningSide.None; - CurrentLoadoutIndex = LoadoutIndex.Primary; - InVehicle = false; - IsBleeding = false; - CurrentLoadout = new PlayerLoadout(); - 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(); - } + if (value == mInternal.Role) + return; + SetNewRole(value); } } -} + + public Team Team + { + get => mInternal.Team; + set + { + if (mInternal.Team != value) + ChangeTeam(value); + } + } + + public Squads Squad + { + get => mInternal.Squad; + set + { + if (value == mInternal.Squad) + return; + if (value == Squads.NoSquad) + KickFromSquad(); + else + JoinSquad(value); + } + } + + public bool InSquad => mInternal.Squad != Squads.NoSquad; + public int PingMs => mInternal.PingMs; + + public float HP => mInternal.HP; + public bool IsAlive => mInternal.HP >= 0f; + public bool IsUp => mInternal.HP > 0f; + public bool IsDown => mInternal.HP == 0f; + public bool IsDead => mInternal.HP == -1f; + + public Vector3 Position + { + get => mInternal.Position; + set => Teleport(value); + } + + public PlayerStand StandingState => mInternal.Standing; + public LeaningSide LeaningState => mInternal.Leaning; + public LoadoutIndex CurrentLoadoutIndex => mInternal.CurrentLoadoutIndex; + public bool InVehicle => mInternal.InVehicle; + public bool IsBleeding => mInternal.IsBleeding; + public PlayerLoadout CurrentLoadout => mInternal.CurrentLoadout; + public PlayerWearings CurrentWearings => mInternal.CurrentWearings; + public PlayerModifications Modifications => mInternal.Modifications; + + // ---- Events ---- + public virtual void OnCreated() + { + } + + public virtual async Task OnConnected() + { + } + + public virtual async Task OnSpawned() + { + } + + public virtual async Task OnDowned() + { + } + + public virtual async Task OnGivenUp() + { + } + + public virtual async Task OnRevivedByAnotherPlayer() + { + } + + public virtual async Task OnRevivedAnotherPlayer() + { + } + + public virtual async Task OnDied() + { + } + + public virtual async Task OnChangedTeam() + { + } + + public virtual async Task OnChangedRole(GameRole newRole) + { + } + + public virtual async Task OnJoinedSquad(Squads newSquad) + { + } + + public virtual async Task OnLeftSquad(Squads oldSquad) + { + } + + public virtual async Task OnDisconnected() + { + } + + // ---- Functions ---- + public void Kick(string reason = "") + { + GameServer.Kick(this, reason); + } + + public void Kill() + { + GameServer.Kill(this); + } + + public void ChangeTeam() + { + GameServer.ChangeTeam(this); + } + + public void ChangeTeam(Team team) + { + GameServer.ChangeTeam(this, team); + } + + public void KickFromSquad() + { + GameServer.KickFromSquad(this); + } + + public void JoinSquad(Squads targetSquad) + { + GameServer.JoinSquad(this, targetSquad); + } + + public void DisbandTheSquad() + { + GameServer.DisbandPlayerCurrentSquad(this); + } + + public void PromoteToSquadLeader() + { + GameServer.PromoteSquadLeader(this); + } + + public void WarnPlayer(string msg) + { + GameServer.WarnPlayer(this, msg); + } + + public void Message(string msg) + { + GameServer.MessageToPlayer(this, msg); + } + + public void Message(string msg, float fadeoutTime) + { + GameServer.MessageToPlayer(this, msg, fadeoutTime); + } + + public void SetNewRole(GameRole role) + { + GameServer.SetRoleTo(this, role); + } + + public void Teleport(Vector3 target) + { + } + + public void SpawnPlayer(PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) + { + GameServer.SpawnPlayer(this, loadout, wearings, position, lookDirection, stand, spawnProtection); + } + + public void SetHP(float newHP) + { + GameServer.SetHP(this, newHP); + } + + public void GiveDamage(float damage) + { + GameServer.GiveDamage(this, damage); + } + + public void Heal(float hp) + { + 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); + } + + public void SetSecondaryWeapon(WeaponItem item, int extraMagazines, bool clear = false) + { + GameServer.SetSecondaryWeapon(this, item, extraMagazines, clear); + } + + public void SetFirstAidGadget(string item, int extra, bool clear = false) + { + GameServer.SetFirstAid(this, item, extra, clear); + } + + public void SetLightGadget(string item, int extra, bool clear = false) + { + GameServer.SetLightGadget(this, item, extra, clear); + } + + public void SetHeavyGadget(string item, int extra, bool clear = false) + { + GameServer.SetHeavyGadget(this, item, extra, clear); + } + + public void SetThrowable(string item, int extra, bool clear = false) + { + GameServer.SetThrowable(this, item, extra, clear); + } + + // ---- Static ---- + public static TPlayer CreateInstance(Player.Internal @internal) where TPlayer : Player + { + var player = (TPlayer)Activator.CreateInstance(typeof(TPlayer)); + player.mInternal = @internal; + return player; + } + + // ---- Overrides ---- + public override string ToString() + { + return Name + " (" + SteamID + ")"; + } + + // ---- Internal ---- + public class Internal + { + public mPlayerModifications _Modifications; + public PlayerLoadout CurrentLoadout; + public LoadoutIndex CurrentLoadoutIndex; + public PlayerWearings CurrentWearings; + public GameServer GameServer; + public float HP; + public bool InVehicle; + public IPAddress IP; + + public bool IsAlive; + public bool IsBleeding; + public LeaningSide Leaning; + public PlayerModifications Modifications; + public string Name; + public int PingMs = 999; + public Vector3 Position; + public GameRole Role; + public Squads Squad; + public PlayerStand Standing; + public ulong SteamID; + public Team Team; + + public Internal() + { + Modifications = new PlayerModifications(this); + _Modifications = new mPlayerModifications(); + } + + public void OnDie() + { + IsAlive = false; + HP = -1f; + Position = default; + Standing = PlayerStand.Standing; + Leaning = LeaningSide.None; + CurrentLoadoutIndex = LoadoutIndex.Primary; + InVehicle = false; + IsBleeding = false; + CurrentLoadout = new PlayerLoadout(); + CurrentWearings = new PlayerWearings(); + } + } + + public class mPlayerModifications + { + public bool AirStrafe = true; + public bool CanRespawn = true; + public bool CanSpawn = true; + public bool CanSpectate = true; + public bool CanUseNightVision = true; + public float DownTimeGiveUpTime = 60f; + public float FallDamageMultiplier = 1f; + public float GiveDamageMultiplier = 1f; + public bool HasCollision; + + public bool IsDirtyFlag = false; + public bool IsTextChatMuted; + public bool IsVoiceChatMuted; + public float JumpHeightMultiplier = 1f; + public float ReceiveDamageMultiplier = 1f; + public float ReloadSpeedMultiplier = 1f; + public float RespawnTime = 10f; + public float RunningSpeedMultiplier = 1f; + + public void Write(Stream ser) + { + ser.Write(RunningSpeedMultiplier); + ser.Write(ReceiveDamageMultiplier); + ser.Write(GiveDamageMultiplier); + ser.Write(JumpHeightMultiplier); + ser.Write(FallDamageMultiplier); + ser.Write(ReloadSpeedMultiplier); + ser.Write(CanUseNightVision); + ser.Write(HasCollision); + ser.Write(DownTimeGiveUpTime); + ser.Write(AirStrafe); + ser.Write(CanSpawn); + ser.Write(CanSpectate); + ser.Write(IsTextChatMuted); + ser.Write(IsVoiceChatMuted); + ser.Write(RespawnTime); + ser.Write(CanRespawn); + } + + public void Read(Stream ser) + { + RunningSpeedMultiplier = ser.ReadFloat(); + if (RunningSpeedMultiplier <= 0f) + RunningSpeedMultiplier = 0.01f; + + ReceiveDamageMultiplier = ser.ReadFloat(); + GiveDamageMultiplier = ser.ReadFloat(); + JumpHeightMultiplier = ser.ReadFloat(); + FallDamageMultiplier = ser.ReadFloat(); + ReloadSpeedMultiplier = ser.ReadFloat(); + CanUseNightVision = ser.ReadBool(); + HasCollision = ser.ReadBool(); + DownTimeGiveUpTime = ser.ReadFloat(); + AirStrafe = ser.ReadBool(); + CanSpawn = ser.ReadBool(); + CanSpectate = ser.ReadBool(); + IsTextChatMuted = ser.ReadBool(); + IsVoiceChatMuted = ser.ReadBool(); + RespawnTime = ser.ReadFloat(); + CanRespawn = ser.ReadBool(); + } + } +} \ No newline at end of file diff --git a/BattleBitAPI/Server/ServerListener.cs b/BattleBitAPI/Server/ServerListener.cs index 5a4d261..604e00c 100644 --- a/BattleBitAPI/Server/ServerListener.cs +++ b/BattleBitAPI/Server/ServerListener.cs @@ -1,1289 +1,1303 @@ -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; +using Stream = BattleBitAPI.Common.Serialization.Stream; -namespace BattleBitAPI.Server +namespace BattleBitAPI.Server; + +public class ServerListener : IDisposable where TPlayer : Player where TGameServer : GameServer { - public class ServerListener : IDisposable where TPlayer : Player where TGameServer : GameServer + private readonly Dictionary.Internal resources)> mActiveConnections; + private readonly mInstances mInstanceDatabase; + + // --- Private --- + private TcpListener mSocket; + + // --- Construction --- + public ServerListener() { - // --- Public --- - public bool IsListening { get; private set; } - public bool IsDisposed { get; private set; } - public int ListeningPort { get; private set; } + mActiveConnections = new Dictionary.Internal)>(16); + mInstanceDatabase = new mInstances(); + } - // --- Events --- - /// - /// Fired when an attempt made to connect to the server.
- /// Default, any connection attempt will be accepted - ///
- /// - /// - /// IPAddress: IP of incoming connection
- ///
- /// - /// - /// Returns: true if allow connection, false if deny the connection. - /// - public Func> OnGameServerConnecting { get; set; } + // --- Public --- + public bool IsListening { get; private set; } + public bool IsDisposed { get; private set; } + public int ListeningPort { get; private set; } - /// - /// Fired when a game server connects. - /// - /// - /// - /// GameServer: Game server that is connecting.
- ///
- public Func, Task> OnGameServerConnected { get; set; } + // --- Events --- + /// + /// Fired when an attempt made to connect to the server.
+ /// Default, any connection attempt will be accepted + ///
+ /// + /// IPAddress: IP of incoming connection
+ ///
+ /// + /// Returns: true if allow connection, false if deny the connection. + /// + public Func> OnGameServerConnecting { get; set; } - /// - /// Fired when a game server reconnects. (When game server connects while a socket is already open) - /// - /// - /// - /// GameServer: Game server that is reconnecting.
- ///
- public Func, Task> OnGameServerReconnected { get; set; } + /// + /// Fired when a game server connects. + /// + /// + /// GameServer: Game server that is connecting.
+ ///
+ public Func, Task> OnGameServerConnected { get; set; } - /// - /// Fired when a game server disconnects. Check (GameServer.TerminationReason) to see the reason. - /// - /// - /// - /// GameServer: Game server that disconnected.
- ///
- public Func, Task> OnGameServerDisconnected { get; set; } + /// + /// Fired when a game server reconnects. (When game server connects while a socket is already open) + /// + /// + /// GameServer: Game server that is reconnecting.
+ ///
+ public Func, Task> OnGameServerReconnected { get; set; } - /// - /// Fired when a new instance of game server created. - /// - /// - /// - /// GameServer: Game server that has been just created.
- ///
- public Func, Task> OnCreatingGameServerInstance { get; set; } + /// + /// Fired when a game server disconnects. Check (GameServer.TerminationReason) to see the reason. + /// + /// + /// GameServer: Game server that disconnected.
+ ///
+ public Func, Task> OnGameServerDisconnected { get; set; } - /// - /// Fired when a new instance of player instance created. - /// - /// - /// - /// TPlayer: The player instance that was created
- ///
- public Func OnCreatingPlayerInstance { get; set; } + /// + /// Fired when a new instance of game server created. + /// + /// + /// GameServer: Game server that has been just created.
+ ///
+ public Func, Task> OnCreatingGameServerInstance { get; set; } - // --- Private --- - private TcpListener mSocket; - private Dictionary.Internal resources)> mActiveConnections; - private mInstances mInstanceDatabase; + /// + /// Fired when a new instance of player instance created. + /// + /// + /// TPlayer: The player instance that was created
+ ///
+ public Func OnCreatingPlayerInstance { get; set; } - // --- Construction --- - public ServerListener() + // --- Public --- + public IEnumerable ConnectedGameServers + { + get { - this.mActiveConnections = new Dictionary.Internal)>(16); - this.mInstanceDatabase = new mInstances(); - } - - // --- Starting --- - public void Start(IPAddress bindIP, int port) - { - if (this.IsDisposed) - throw new ObjectDisposedException(this.GetType().FullName); - if (bindIP == null) - throw new ArgumentNullException(nameof(bindIP)); - if (IsListening) - throw new Exception("Server is already listening."); - - this.mSocket = new TcpListener(bindIP, port); - this.mSocket.Start(); - - this.ListeningPort = port; - this.IsListening = true; - - mMainLoop(); - } - public void Start(int port) - { - Start(IPAddress.Any, port); - } - - // --- Stopping --- - public void Stop() - { - if (this.IsDisposed) - throw new ObjectDisposedException(this.GetType().FullName); - if (!IsListening) - throw new Exception("Already not running."); - - try + var list = new List(mActiveConnections.Count); + lock (mActiveConnections) { - mSocket.Stop(); - } - catch { } - - this.mSocket = null; - this.ListeningPort = 0; - this.IsListening = true; - } - - // --- Main Loop --- - private async Task mMainLoop() - { - while (IsListening) - { - var client = await mSocket.AcceptTcpClientAsync(); - mInternalOnClientConnecting(client); - } - } - private async Task mInternalOnClientConnecting(TcpClient client) - { - var ip = (client.Client.RemoteEndPoint as IPEndPoint).Address; - - bool allow = true; - if (OnGameServerConnecting != null) - allow = await OnGameServerConnecting(ip); - - if (!allow) - { - //Connection is not allowed from this IP. - client.SafeClose(); - return; + foreach (var item in mActiveConnections.Values) + list.Add(item.server); } - TGameServer server = null; - GameServer.Internal resources; - try + return list; + } + } + + // --- Disposing --- + public void Dispose() + { + //Already disposed? + if (IsDisposed) + return; + IsDisposed = true; + + if (IsListening) + Stop(); + } + + // --- Starting --- + public void Start(IPAddress bindIP, int port) + { + if (IsDisposed) + throw new ObjectDisposedException(GetType().FullName); + if (bindIP == null) + throw new ArgumentNullException(nameof(bindIP)); + if (IsListening) + throw new Exception("Server is already listening."); + + mSocket = new TcpListener(bindIP, port); + mSocket.Start(); + + ListeningPort = port; + IsListening = true; + + mMainLoop(); + } + + public void Start(int port) + { + Start(IPAddress.Any, port); + } + + // --- Stopping --- + public void Stop() + { + if (IsDisposed) + throw new ObjectDisposedException(GetType().FullName); + if (!IsListening) + throw new Exception("Already not running."); + + try + { + mSocket.Stop(); + } + catch + { + } + + mSocket = null; + ListeningPort = 0; + IsListening = true; + } + + // --- Main Loop --- + private async Task mMainLoop() + { + while (IsListening) + { + var client = await mSocket.AcceptTcpClientAsync(); + mInternalOnClientConnecting(client); + } + } + + private async Task mInternalOnClientConnecting(TcpClient client) + { + var ip = (client.Client.RemoteEndPoint as IPEndPoint).Address; + + var allow = true; + if (OnGameServerConnecting != null) + allow = await OnGameServerConnecting(ip); + + if (!allow) + { + //Connection is not allowed from this IP. + client.SafeClose(); + return; + } + + TGameServer server = null; + GameServer.Internal resources; + try + { + using (var source = new CancellationTokenSource(Const.HailConnectTimeout)) { - using (CancellationTokenSource source = new CancellationTokenSource(Const.HailConnectTimeout)) - { - using (var readStream = Common.Serialization.Stream.Get()) - { - var networkStream = client.GetStream(); - - //Read package type - { - 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 port - int gamePort; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the Port"); - gamePort = readStream.ReadUInt16(); - } - - //Read is server protected - bool isPasswordProtected; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the IsPasswordProtected"); - isPasswordProtected = readStream.ReadBool(); - } - - //Read the server name - string serverName; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the ServerName Size"); - - int stringSize = readStream.ReadUInt16(); - if (stringSize < Const.MinServerNameLength || stringSize > Const.MaxServerNameLength) - throw new Exception("Invalid server name size"); - - readStream.Reset(); - if (!await networkStream.TryRead(readStream, stringSize, source.Token)) - throw new Exception("Unable to read the ServerName"); - - serverName = readStream.ReadString(stringSize); - } - - //Read the gamemode - string gameMode; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the gamemode Size"); - - int stringSize = readStream.ReadUInt16(); - if (stringSize < Const.MinGamemodeNameLength || stringSize > Const.MaxGamemodeNameLength) - throw new Exception("Invalid gamemode size"); - - readStream.Reset(); - if (!await networkStream.TryRead(readStream, stringSize, source.Token)) - throw new Exception("Unable to read the gamemode"); - - gameMode = readStream.ReadString(stringSize); - } - - //Read the gamemap - string gamemap; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the map size"); - - int stringSize = readStream.ReadUInt16(); - if (stringSize < Const.MinMapNameLength || stringSize > Const.MaxMapNameLength) - throw new Exception("Invalid map size"); - - readStream.Reset(); - if (!await networkStream.TryRead(readStream, stringSize, source.Token)) - throw new Exception("Unable to read the map"); - - gamemap = readStream.ReadString(stringSize); - } - - //Read the mapSize - MapSize size; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the MapSize"); - size = (MapSize)readStream.ReadInt8(); - } - - //Read the day night - MapDayNight dayNight; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the MapDayNight"); - dayNight = (MapDayNight)readStream.ReadInt8(); - } - - //Current Players - int currentPlayers; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Current Players"); - currentPlayers = readStream.ReadInt8(); - } - - //Queue Players - int queuePlayers; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Queue Players"); - queuePlayers = readStream.ReadInt8(); - } - - //Max Players - int maxPlayers; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Max Players"); - maxPlayers = readStream.ReadInt8(); - } - - //Read Loading Screen Text - string loadingScreenText; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the Loading Screen Text Size"); - - int stringSize = readStream.ReadUInt16(); - if (stringSize < Const.MinLoadingScreenTextLength || stringSize > Const.MaxLoadingScreenTextLength) - throw new Exception("Invalid server Loading Screen Text Size"); - - if (stringSize > 0) - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, stringSize, source.Token)) - throw new Exception("Unable to read the Loading Screen Text"); - - loadingScreenText = readStream.ReadString(stringSize); - } - else - { - loadingScreenText = string.Empty; - } - } - - //Read Server Rules Text - string serverRulesText; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the Server Rules Text Size"); - - int stringSize = readStream.ReadUInt16(); - if (stringSize < Const.MinServerRulesTextLength || stringSize > Const.MaxServerRulesTextLength) - throw new Exception("Invalid server Server Rules Text Size"); - - if (stringSize > 0) - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, stringSize, source.Token)) - throw new Exception("Unable to read the Server Rules Text"); - - serverRulesText = readStream.ReadString(stringSize); - } - else - { - serverRulesText = string.Empty; - } - } - - var hash = ((ulong)gamePort << 32) | (ulong)ip.ToUInt(); - server = this.mInstanceDatabase.GetServerInstance(hash, out bool isNew, out resources); - resources.Set( - this.mExecutePackage, - client, - ip, - gamePort, - isPasswordProtected, - serverName, - gameMode, - gamemap, - size, - dayNight, - currentPlayers, - queuePlayers, - maxPlayers, - loadingScreenText, - serverRulesText - ); - - //Room settings - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 4, source.Token)) - throw new Exception("Unable to read the room size"); - int roomSize = (int)readStream.ReadUInt32(); - - readStream.Reset(); - if (!await networkStream.TryRead(readStream, roomSize, source.Token)) - throw new Exception("Unable to read the room"); - resources._RoomSettings.Read(readStream); - } - - //Map&gamemode rotation - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 4, source.Token)) - throw new Exception("Unable to read the map&gamemode rotation size"); - int rotationSize = (int)readStream.ReadUInt32(); - - readStream.Reset(); - if (!await networkStream.TryRead(readStream, rotationSize, source.Token)) - throw new Exception("Unable to read the map&gamemode"); - - uint count = readStream.ReadUInt32(); - while (count > 0) - { - count--; - if (readStream.TryReadString(out var item)) - resources._MapRotation.Add(item.ToUpperInvariant()); - } - - count = readStream.ReadUInt32(); - while (count > 0) - { - count--; - if (readStream.TryReadString(out var item)) - resources._GamemodeRotation.Add(item); - } - } - - //Round Settings - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, GameServer.mRoundSettings.Size, source.Token)) - throw new Exception("Unable to read the round settings"); - resources._RoundSettings.Read(readStream); - } - - //Client Count - int clientCount = 0; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Client Count Players"); - clientCount = readStream.ReadInt8(); - } - - //Get each client. - while (clientCount > 0) - { - clientCount--; - - ulong steamid = 0; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 8, source.Token)) - throw new Exception("Unable to read the SteamId"); - steamid = readStream.ReadUInt64(); - } - - string username; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 2, source.Token)) - throw new Exception("Unable to read the Username Size"); - - int stringSize = readStream.ReadUInt16(); - if (stringSize > 0) - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, stringSize, source.Token)) - throw new Exception("Unable to read the Username"); - - username = readStream.ReadString(stringSize); - } - else - { - username = string.Empty; - } - } - - uint ipHash = 0; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 4, source.Token)) - throw new Exception("Unable to read the ip"); - ipHash = readStream.ReadUInt32(); - } - - //Team - Team team; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Team"); - team = (Team)readStream.ReadInt8(); - } - - //Squad - Squads squad; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Squad"); - squad = (Squads)readStream.ReadInt8(); - } - - //Role - GameRole role; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the Role"); - role = (GameRole)readStream.ReadInt8(); - } - - var loadout = new PlayerLoadout(); - var wearings = new PlayerWearings(); - - //IsAlive - bool isAlive; - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 1, source.Token)) - throw new Exception("Unable to read the isAlive"); - isAlive = readStream.ReadBool(); - } - - //Loadout + Wearings - if (isAlive) - { - readStream.Reset(); - if (!await networkStream.TryRead(readStream, 4, source.Token)) - throw new Exception("Unable to read the LoadoutSize"); - int loadoutSize = (int)readStream.ReadUInt32(); - - readStream.Reset(); - if (!await networkStream.TryRead(readStream, loadoutSize, source.Token)) - throw new Exception("Unable to read the Loadout + Wearings"); - loadout.Read(readStream); - wearings.Read(readStream); - } - - TPlayer player = mInstanceDatabase.GetPlayerInstance(steamid, out bool isNewClient, out var playerInternal); - playerInternal.SteamID = steamid; - playerInternal.Name = username; - playerInternal.IP = new IPAddress(ipHash); - playerInternal.GameServer = (GameServer)server; - playerInternal.Team = team; - playerInternal.Squad = squad; - playerInternal.Role = role; - playerInternal.IsAlive = isAlive; - playerInternal.CurrentLoadout = loadout; - playerInternal.CurrentWearings = wearings; - - if (isNewClient) - { - if (this.OnCreatingPlayerInstance != null) - this.OnCreatingPlayerInstance(player); - } - - - resources.AddPlayer(player); - } - - //Send accepted notification. - networkStream.WriteByte((byte)NetworkCommuncation.Accepted); - - if (isNew) - { - if (this.OnCreatingGameServerInstance != null) - this.OnCreatingGameServerInstance(server); - } - - } - } - } - catch (Exception e) - { - try + using (var readStream = Stream.Get()) { var networkStream = client.GetStream(); - using (var pck = BattleBitAPI.Common.Serialization.Stream.Get()) + + //Read package type { - pck.Write((byte)NetworkCommuncation.Denied); - pck.Write(e.Message); - - //Send denied notification. - networkStream.Write(pck.Buffer, 0, pck.WritePosition); + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the package type"); + var type = (NetworkCommunication)readStream.ReadInt8(); + if (type != NetworkCommunication.Hail) + throw new Exception("Incoming package wasn't hail."); } - await networkStream.FlushAsync(); + + //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(); + } + + //Read is server protected + bool isPasswordProtected; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the IsPasswordProtected"); + isPasswordProtected = readStream.ReadBool(); + } + + //Read the server name + string serverName; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the ServerName Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinServerNameLength || stringSize > Const.MaxServerNameLength) + throw new Exception("Invalid server name size"); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the ServerName"); + + serverName = readStream.ReadString(stringSize); + } + + //Read the gamemode + string gameMode; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the gamemode Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinGamemodeNameLength || stringSize > Const.MaxGamemodeNameLength) + throw new Exception("Invalid gamemode size"); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the gamemode"); + + gameMode = readStream.ReadString(stringSize); + } + + //Read the gamemap + string gamemap; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the map size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinMapNameLength || stringSize > Const.MaxMapNameLength) + throw new Exception("Invalid map size"); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the map"); + + gamemap = readStream.ReadString(stringSize); + } + + //Read the mapSize + MapSize size; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the MapSize"); + size = (MapSize)readStream.ReadInt8(); + } + + //Read the day night + MapDayNight dayNight; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the MapDayNight"); + dayNight = (MapDayNight)readStream.ReadInt8(); + } + + //Current Players + int currentPlayers; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Current Players"); + currentPlayers = readStream.ReadInt8(); + } + + //Queue Players + int queuePlayers; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Queue Players"); + queuePlayers = readStream.ReadInt8(); + } + + //Max Players + int maxPlayers; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Max Players"); + maxPlayers = readStream.ReadInt8(); + } + + //Read Loading Screen Text + string loadingScreenText; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the Loading Screen Text Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinLoadingScreenTextLength || stringSize > Const.MaxLoadingScreenTextLength) + throw new Exception("Invalid server Loading Screen Text Size"); + + if (stringSize > 0) + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the Loading Screen Text"); + + loadingScreenText = readStream.ReadString(stringSize); + } + else + { + loadingScreenText = string.Empty; + } + } + + //Read Server Rules Text + string serverRulesText; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the Server Rules Text Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinServerRulesTextLength || stringSize > Const.MaxServerRulesTextLength) + throw new Exception("Invalid server Server Rules Text Size"); + + if (stringSize > 0) + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the Server Rules Text"); + + serverRulesText = readStream.ReadString(stringSize); + } + else + { + serverRulesText = string.Empty; + } + } + + var hash = ((ulong)gamePort << 32) | ip.ToUInt(); + server = mInstanceDatabase.GetServerInstance(hash, out var isNew, out resources); + resources.Set( + mExecutePackage, + client, + ip, + gamePort, + isPasswordProtected, + serverName, + gameMode, + gamemap, + size, + dayNight, + currentPlayers, + queuePlayers, + maxPlayers, + loadingScreenText, + serverRulesText + ); + + //Room settings + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 4, source.Token)) + throw new Exception("Unable to read the room size"); + var roomSize = (int)readStream.ReadUInt32(); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, roomSize, source.Token)) + throw new Exception("Unable to read the room"); + resources._RoomSettings.Read(readStream); + } + + //Map&gamemode rotation + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 4, source.Token)) + throw new Exception("Unable to read the map&gamemode rotation size"); + var rotationSize = (int)readStream.ReadUInt32(); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, rotationSize, source.Token)) + throw new Exception("Unable to read the map&gamemode"); + + var count = readStream.ReadUInt32(); + while (count > 0) + { + count--; + if (readStream.TryReadString(out var item)) + resources._MapRotation.Add(item.ToUpperInvariant()); + } + + count = readStream.ReadUInt32(); + while (count > 0) + { + count--; + if (readStream.TryReadString(out var item)) + resources._GamemodeRotation.Add(item); + } + } + + //Round Settings + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, GameServer.mRoundSettings.Size, source.Token)) + throw new Exception("Unable to read the round settings"); + resources._RoundSettings.Read(readStream); + } + + //Client Count + var clientCount = 0; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Client Count Players"); + clientCount = readStream.ReadInt8(); + } + + //Get each client. + while (clientCount > 0) + { + clientCount--; + + ulong steamid = 0; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 8, source.Token)) + throw new Exception("Unable to read the SteamId"); + steamid = readStream.ReadUInt64(); + } + + string username; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the Username Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize > 0) + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the Username"); + + username = readStream.ReadString(stringSize); + } + else + { + username = string.Empty; + } + } + + uint ipHash = 0; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 4, source.Token)) + throw new Exception("Unable to read the ip"); + ipHash = readStream.ReadUInt32(); + } + + //Team + Team team; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Team"); + team = (Team)readStream.ReadInt8(); + } + + //Squad + Squads squad; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Squad"); + squad = (Squads)readStream.ReadInt8(); + } + + //Role + GameRole role; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Role"); + role = (GameRole)readStream.ReadInt8(); + } + + var loadout = new PlayerLoadout(); + var wearings = new PlayerWearings(); + + //IsAlive + bool isAlive; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the isAlive"); + isAlive = readStream.ReadBool(); + } + + //Loadout + Wearings + if (isAlive) + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 4, source.Token)) + throw new Exception("Unable to read the LoadoutSize"); + var loadoutSize = (int)readStream.ReadUInt32(); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, loadoutSize, source.Token)) + throw new Exception("Unable to read the Loadout + Wearings"); + loadout.Read(readStream); + wearings.Read(readStream); + } + + var player = mInstanceDatabase.GetPlayerInstance(steamid, out var isNewClient, out var playerInternal); + playerInternal.SteamID = steamid; + playerInternal.Name = username; + playerInternal.IP = new IPAddress(ipHash); + playerInternal.GameServer = server; + playerInternal.Team = team; + playerInternal.Squad = squad; + playerInternal.Role = role; + playerInternal.IsAlive = isAlive; + playerInternal.CurrentLoadout = loadout; + playerInternal.CurrentWearings = wearings; + + if (isNewClient) + if (OnCreatingPlayerInstance != null) + OnCreatingPlayerInstance(player); + + + resources.AddPlayer(player); + } + + //Send accepted notification. + networkStream.WriteByte((byte)NetworkCommunication.Accepted); + + if (isNew) + if (OnCreatingGameServerInstance != null) + OnCreatingGameServerInstance(server); } - catch { } - - 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; - - //Join to main server loop. - await mHandleGameServer(server, resources); } - private async Task mHandleGameServer(TGameServer server, GameServer.Internal @internal) + catch (Exception e) { - bool isTicking = false; - - using (server) + try { - async Task mTickAsync() + var networkStream = client.GetStream(); + using (var pck = Stream.Get()) { - isTicking = true; - await server.OnTick(); - isTicking = false; + pck.Write((byte)NetworkCommunication.Denied); + pck.Write(e.Message); + + //Send denied notification. + networkStream.Write(pck.Buffer, 0, pck.WritePosition); } - while (server.IsConnected) - { - if (!isTicking) - mTickAsync(); - - await server.Tick(); - await Task.Delay(10); - } - - if (!server.ReconnectFlag) - { - server.OnDisconnected(); - - if (this.OnGameServerDisconnected != null) - this.OnGameServerDisconnected(server); - } + await networkStream.FlushAsync(); + } + catch + { + } + + client.SafeClose(); + return; + } + + var connectionExist = false; + + //Track the connection + lock (mActiveConnections) + { + //An old connection exist with same IP + Port? + if (connectionExist = mActiveConnections.TryGetValue(server.ServerHash, out var oldServer)) + { + oldServer.resources.ReconnectFlag = true; + mActiveConnections.Remove(server.ServerHash); + } + + mActiveConnections.Add(server.ServerHash, (server, resources)); + } + + //Call the callback. + if (!connectionExist) + { + //New connection! + server.OnConnected(); + if (OnGameServerConnected != null) + OnGameServerConnected(server); + } + else + { + //Reconnection + server.OnReconnected(); + if (OnGameServerReconnected != null) + OnGameServerReconnected(server); + } + + //Set the buffer sizes. + client.ReceiveBufferSize = Const.MaxNetworkPackageSize; + client.SendBufferSize = Const.MaxNetworkPackageSize; + + //Join to main server loop. + await mHandleGameServer(server, resources); + } + + private async Task mHandleGameServer(TGameServer server, GameServer.Internal @internal) + { + var isTicking = false; + + using (server) + { + async Task mTickAsync() + { + isTicking = true; + await server.OnTick(); + isTicking = false; + } + + while (server.IsConnected) + { + if (!isTicking) + mTickAsync(); + + await server.Tick(); + await Task.Delay(10); } - //Remove from list. if (!server.ReconnectFlag) - lock (this.mActiveConnections) - this.mActiveConnections.Remove(server.ServerHash); + { + server.OnDisconnected(); + + if (OnGameServerDisconnected != null) + OnGameServerDisconnected(server); + } } - // --- Logic Executing --- - private async Task mExecutePackage(GameServer server, GameServer.Internal resources, Common.Serialization.Stream stream) - { - var communcation = (NetworkCommuncation)stream.ReadInt8(); - switch (communcation) + //Remove from list. + if (!server.ReconnectFlag) + lock (mActiveConnections) { - case NetworkCommuncation.PlayerConnected: + mActiveConnections.Remove(server.ServerHash); + } + } + + // --- Logic Executing --- + private async Task mExecutePackage(GameServer server, GameServer.Internal resources, Stream stream) + { + var communcation = (NetworkCommunication)stream.ReadInt8(); + switch (communcation) + { + case NetworkCommunication.PlayerConnected: + { + if (stream.CanRead(8 + 2 + 4 + 1 + 1 + 1)) + { + var steamID = stream.ReadUInt64(); + if (stream.TryReadString(out var username)) { - if (stream.CanRead(8 + 2 + 4 + (1 + 1 + 1))) - { - ulong steamID = stream.ReadUInt64(); - if (stream.TryReadString(out var username)) - { - uint ip = stream.ReadUInt32(); - Team team = (Team)stream.ReadInt8(); - Squads squad = (Squads)stream.ReadInt8(); - GameRole role = (GameRole)stream.ReadInt8(); + var ip = stream.ReadUInt32(); + var team = (Team)stream.ReadInt8(); + var squad = (Squads)stream.ReadInt8(); + var role = (GameRole)stream.ReadInt8(); - TPlayer player = mInstanceDatabase.GetPlayerInstance(steamID, out bool isNewClient, out var playerInternal); - playerInternal.SteamID = steamID; - playerInternal.Name = username; - playerInternal.IP = new IPAddress(ip); - playerInternal.GameServer = (GameServer)server; + var player = mInstanceDatabase.GetPlayerInstance(steamID, out var isNewClient, out var playerInternal); + playerInternal.SteamID = steamID; + playerInternal.Name = username; + playerInternal.IP = new IPAddress(ip); + playerInternal.GameServer = server; - playerInternal.Team = team; - playerInternal.Squad = squad; - playerInternal.Role = role; + playerInternal.Team = team; + playerInternal.Squad = squad; + playerInternal.Role = role; - if (isNewClient) - { - if (this.OnCreatingPlayerInstance != null) - this.OnCreatingPlayerInstance(player); - } + if (isNewClient) + if (OnCreatingPlayerInstance != null) + OnCreatingPlayerInstance(player); - resources.AddPlayer(player); - player.OnConnected(); - server.OnPlayerConnected(player); - } - } - break; + resources.AddPlayer(player); + player.OnConnected(); + server.OnPlayerConnected(player); } - case NetworkCommuncation.PlayerDisconnected: + } + + break; + } + case NetworkCommunication.PlayerDisconnected: + { + if (stream.CanRead(8)) + { + var steamID = stream.ReadUInt64(); + bool exist; + Player player; + lock (resources.Players) { - if (stream.CanRead(8)) - { - ulong steamID = stream.ReadUInt64(); - bool exist; - Player player; - lock (resources.Players) - exist = resources.Players.Remove(steamID, out player); - - if (exist) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - if (@internal.HP > -1f) - { - @internal.OnDie(); - - player.OnDied(); - server.OnPlayerDied((TPlayer)player); - } - - player.OnDisconnected(); - server.OnPlayerDisconnected((TPlayer)player); - } - } - break; + exist = resources.Players.Remove(steamID, out player); } - case NetworkCommuncation.OnPlayerTypedMessage: + + if (exist) { - if (stream.CanRead(2 + 8 + 1 + 2)) + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + if (@internal.HP > -1f) { - ushort messageID = stream.ReadUInt16(); - ulong steamID = stream.ReadUInt64(); + @internal.OnDie(); - if (resources.TryGetPlayer(steamID, out var player)) - { - ChatChannel chat = (ChatChannel)stream.ReadInt8(); - if (stream.TryReadString(out var msg)) - { - async Task Handle() - { - var pass = await server.OnPlayerTypedMessage((TPlayer)player, chat, msg); - - //Respond back. - using (var response = Common.Serialization.Stream.Get()) - { - response.Write((byte)NetworkCommuncation.RespondPlayerMessage); - response.Write(messageID); - response.Write(pass); - server.WriteToSocket(response); - } - } - - Handle(); - - } - } - } - break; - } - case NetworkCommuncation.OnAPlayerDownedAnotherPlayer: - { - if (stream.CanRead(8 + 12 + 8 + 12 + 2 + 1 + 1)) - { - ulong killer = stream.ReadUInt64(); - Vector3 killerPos = new Vector3(stream.ReadFloat(), stream.ReadFloat(), stream.ReadFloat()); - - ulong victim = stream.ReadUInt64(); - Vector3 victimPos = new Vector3(stream.ReadFloat(), stream.ReadFloat(), stream.ReadFloat()); - - if (stream.TryReadString(out var tool)) - { - PlayerBody body = (PlayerBody)stream.ReadInt8(); - ReasonOfDamage source = (ReasonOfDamage)stream.ReadInt8(); - - if (resources.TryGetPlayer(killer, out var killerClient)) - { - if (resources.TryGetPlayer(victim, out var victimClient)) - { - var args = new OnPlayerKillArguments() - { - Killer = (TPlayer)killerClient, - KillerPosition = killerPos, - Victim = (TPlayer)victimClient, - VictimPosition = victimPos, - BodyPart = body, - SourceOfDamage = source, - KillerTool = tool, - }; - - victimClient.OnDowned(); - server.OnAPlayerDownedAnotherPlayer(args); - } - } - } + player.OnDied(); + server.OnPlayerDied((TPlayer)player); } - break; + player.OnDisconnected(); + server.OnPlayerDisconnected((TPlayer)player); } - case NetworkCommuncation.OnPlayerJoining: + } + + break; + } + case NetworkCommunication.OnPlayerTypedMessage: + { + if (stream.CanRead(2 + 8 + 1 + 2)) + { + var messageID = stream.ReadUInt16(); + var steamID = stream.ReadUInt64(); + + if (resources.TryGetPlayer(steamID, out var player)) { - if (stream.CanRead(8 + 2)) + var chat = (ChatChannel)stream.ReadInt8(); + if (stream.TryReadString(out var msg)) { - ulong steamID = stream.ReadUInt64(); - var stats = new PlayerStats(); - stats.Read(stream); - - - async Task mHandle() + async Task Handle() { - var args = new PlayerJoiningArguments() - { - Stats = stats, - Squad = Squads.NoSquad, - Team = Team.None - }; + var pass = await server.OnPlayerTypedMessage((TPlayer)player, chat, msg); - await server.OnPlayerJoiningToServer(steamID, args); - using (var response = Common.Serialization.Stream.Get()) + //Respond back. + using (var response = Stream.Get()) { - response.Write((byte)NetworkCommuncation.SendPlayerStats); - response.Write(steamID); - args.Write(response); + response.Write((byte)NetworkCommunication.RespondPlayerMessage); + response.Write(messageID); + response.Write(pass); server.WriteToSocket(response); } } - mHandle(); + Handle(); } - break; } - case NetworkCommuncation.SavePlayerStats: - { - if (stream.CanRead(8 + 4)) - { - ulong steamID = stream.ReadUInt64(); - PlayerStats stats = new PlayerStats(); - stats.Read(stream); - - server.OnSavePlayerStats(steamID, stats); - } - break; - } - case NetworkCommuncation.OnPlayerAskingToChangeRole: - { - if (stream.CanRead(8 + 1)) - { - ulong steamID = stream.ReadUInt64(); - GameRole role = (GameRole)stream.ReadInt8(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - async Task mHandle() - { - bool accepted = await server.OnPlayerRequestingToChangeRole((TPlayer)client, role); - if (accepted) - server.SetRoleTo(steamID, role); - } - - mHandle(); - } - } - break; - } - case NetworkCommuncation.OnPlayerChangedRole: - { - if (stream.CanRead(8 + 1)) - { - ulong steamID = stream.ReadUInt64(); - GameRole role = (GameRole)stream.ReadInt8(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - @internal.Role = role; - - client.OnChangedRole(role); - server.OnPlayerChangedRole((TPlayer)client, role); - } - } - break; - } - case NetworkCommuncation.OnPlayerJoinedASquad: - { - if (stream.CanRead(8 + 1)) - { - ulong steamID = stream.ReadUInt64(); - Squads squad = (Squads)stream.ReadInt8(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - @internal.Squad = squad; - - client.OnJoinedSquad(squad); - server.OnPlayerJoinedSquad((TPlayer)client, squad); - } - } - break; - } - case NetworkCommuncation.OnPlayerLeftSquad: - { - if (stream.CanRead(8)) - { - ulong steamID = stream.ReadUInt64(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - - var oldSquad = client.Squad; - var oldRole = client.Role; - @internal.Squad = Squads.NoSquad; - @internal.Role = GameRole.Assault; - - client.OnLeftSquad(oldSquad); - server.OnPlayerLeftSquad((TPlayer)client, oldSquad); - - if (oldRole != GameRole.Assault) - { - client.OnChangedRole(GameRole.Assault); - server.OnPlayerChangedRole((TPlayer)client, GameRole.Assault); - } - } - } - break; - } - case NetworkCommuncation.OnPlayerChangedTeam: - { - if (stream.CanRead(8 + 1)) - { - ulong steamID = stream.ReadUInt64(); - Team team = (Team)stream.ReadInt8(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - - @internal.Team = team; - - client.OnChangedTeam(); - server.OnPlayerChangeTeam((TPlayer)client, team); - } - } - break; - } - case NetworkCommuncation.OnPlayerRequestingToSpawn: - { - if (stream.CanRead(2)) - { - ulong steamID = stream.ReadUInt64(); - - var request = new OnPlayerSpawnArguments(); - request.Read(stream); - ushort vehicleID = stream.ReadUInt16(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - async Task mHandle() - { - request = await server.OnPlayerSpawning((TPlayer)client, request); - - //Respond back. - using (var response = Common.Serialization.Stream.Get()) - { - response.Write((byte)NetworkCommuncation.SpawnPlayer); - response.Write(steamID); - request.Write(response); - response.Write(vehicleID); - server.WriteToSocket(response); - } - } - - mHandle(); - } - } - break; - } - case NetworkCommuncation.OnPlayerReport: - { - if (stream.CanRead(8 + 8 + 1 + 2)) - { - ulong reporter = stream.ReadUInt64(); - ulong reported = stream.ReadUInt64(); - ReportReason reason = (ReportReason)stream.ReadInt8(); - stream.TryReadString(out var additionalInfo); - - if (resources.TryGetPlayer(reporter, out var reporterClient)) - { - if (resources.TryGetPlayer(reported, out var reportedClient)) - { - server.OnPlayerReported((TPlayer)reporterClient, (TPlayer)reportedClient, reason, additionalInfo); - } - } - } - break; - } - case NetworkCommuncation.OnPlayerSpawn: - { - if (stream.CanRead(8 + 2)) - { - ulong steamID = stream.ReadUInt64(); - if (resources.TryGetPlayer(steamID, out var client)) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - - var loadout = new PlayerLoadout(); - loadout.Read(stream); - @internal.CurrentLoadout = loadout; - - var wearings = new PlayerWearings(); - wearings.Read(stream); - @internal.CurrentWearings = wearings; - - @internal.IsAlive = true; - - client.OnSpawned(); - server.OnPlayerSpawned((TPlayer)client); - } - } - break; - } - case NetworkCommuncation.OnPlayerDie: - { - if (stream.CanRead(8)) - { - ulong steamid = stream.ReadUInt64(); - if (resources.TryGetPlayer(steamid, out var client)) - { - var @internal = mInstanceDatabase.GetPlayerInternals(steamid); - @internal.OnDie(); - - client.OnDied(); - server.OnPlayerDied((TPlayer)client); - } - } - break; - } - case NetworkCommuncation.NotifyNewMapRotation: - { - if (stream.CanRead(4)) - { - uint count = stream.ReadUInt32(); - lock (resources._MapRotation) - { - resources._MapRotation.Clear(); - while (count > 0) - { - count--; - if (stream.TryReadString(out var map)) - resources._MapRotation.Add(map.ToUpperInvariant()); - } - } - } - break; - } - case NetworkCommuncation.NotifyNewGamemodeRotation: - { - if (stream.CanRead(4)) - { - uint count = stream.ReadUInt32(); - lock (resources._GamemodeRotation) - { - resources._GamemodeRotation.Clear(); - while (count > 0) - { - count--; - if (stream.TryReadString(out var map)) - resources._GamemodeRotation.Add(map); - } - } - } - break; - } - case NetworkCommuncation.NotifyNewRoundState: - { - if (stream.CanRead(GameServer.mRoundSettings.Size)) - { - var oldState = resources._RoundSettings.State; - resources._RoundSettings.Read(stream); - var newState = resources._RoundSettings.State; - - if (newState != oldState) - { - server.OnGameStateChanged(oldState, newState); - - if (newState == GameState.Playing) - server.OnRoundStarted(); - else if (newState == GameState.EndingGame) - server.OnRoundEnded(); - } - } - break; - } - case NetworkCommuncation.OnPlayerAskingToChangeTeam: - { - if (stream.CanRead(8 + 1)) - { - ulong steamID = stream.ReadUInt64(); - Team team = (Team)stream.ReadInt8(); - - if (resources.TryGetPlayer(steamID, out var client)) - { - async Task mHandle() - { - bool accepted = await server.OnPlayerRequestingToChangeTeam((TPlayer)client, team); - if (accepted) - server.ChangeTeam(steamID, team); - } - - mHandle(); - } - } - break; - } - case NetworkCommuncation.GameTick: - { - if (stream.CanRead(4 + 4 + 4)) - { - float decompressX = stream.ReadFloat(); - float decompressY = stream.ReadFloat(); - float decompressZ = stream.ReadFloat(); - - int playerCount = stream.ReadInt8(); - while (playerCount > 0) - { - playerCount--; - ulong steamID = stream.ReadUInt64(); - - //TODO, can compressed further later. - ushort com_posX = stream.ReadUInt16(); - ushort com_posY = stream.ReadUInt16(); - ushort com_posZ = stream.ReadUInt16(); - byte com_healt = stream.ReadInt8(); - PlayerStand standing = (PlayerStand)stream.ReadInt8(); - LeaningSide side = (LeaningSide)stream.ReadInt8(); - LoadoutIndex loadoutIndex = (LoadoutIndex)stream.ReadInt8(); - bool inSeat = stream.ReadBool(); - bool isBleeding = stream.ReadBool(); - ushort ping = stream.ReadUInt16(); - - var @internal = mInstanceDatabase.GetPlayerInternals(steamID); - if (@internal.IsAlive) - { - @internal.Position = new Vector3() - { - X = com_posX * decompressX, - Y = com_posY * decompressY, - Z = com_posZ * decompressZ, - }; - @internal.HP = (com_healt * 0.5f) - 1f; - @internal.Standing = standing; - @internal.Leaning = side; - @internal.CurrentLoadoutIndex = loadoutIndex; - @internal.InVehicle = inSeat; - @internal.IsBleeding = isBleeding; - @internal.PingMs = ping; - } - } - } - break; - } - case NetworkCommuncation.OnPlayerGivenUp: - { - if (stream.CanRead(8)) - { - ulong steamID = stream.ReadUInt64(); - if (resources.TryGetPlayer(steamID, out var client)) - { - client.OnGivenUp(); - server.OnPlayerGivenUp((TPlayer)client); - } - } - break; - } - case NetworkCommuncation.OnPlayerRevivedAnother: - { - if (stream.CanRead(8 + 8)) - { - ulong from = stream.ReadUInt64(); - ulong to = stream.ReadUInt64(); - if (resources.TryGetPlayer(to, out var toClient)) - { - toClient.OnRevivedByAnotherPlayer(); - - if (resources.TryGetPlayer(from, out var fromClient)) - { - fromClient.OnRevivedAnotherPlayer(); - server.OnAPlayerRevivedAnotherPlayer((TPlayer)fromClient, (TPlayer)toClient); - } - } - } - break; - } - } - } - - // --- Public --- - public IEnumerable ConnectedGameServers - { - get - { - var list = new List(mActiveConnections.Count); - lock (mActiveConnections) - { - foreach (var item in mActiveConnections.Values) - list.Add(item.server); } - return list; + + break; } - } - public bool TryGetGameServer(IPAddress ip, ushort port, out TGameServer server) - { - var hash = ((ulong)port << 32) | (ulong)ip.ToUInt(); - lock (mActiveConnections) + case NetworkCommunication.OnAPlayerDownedAnotherPlayer: { - if (mActiveConnections.TryGetValue(hash, out var _server)) + if (stream.CanRead(8 + 12 + 8 + 12 + 2 + 1 + 1)) { - server = (TGameServer)_server.server; - return true; - } - } + var killer = stream.ReadUInt64(); + var killerPos = new Vector3(stream.ReadFloat(), stream.ReadFloat(), stream.ReadFloat()); - server = default; - return false; - } + var victim = stream.ReadUInt64(); + var victimPos = new Vector3(stream.ReadFloat(), stream.ReadFloat(), stream.ReadFloat()); - // --- Disposing --- - public void Dispose() - { - //Already disposed? - if (this.IsDisposed) - return; - this.IsDisposed = true; - - if (IsListening) - Stop(); - } - - // --- Classes --- - private class mInstances where TPlayer : Player where TGameServer : GameServer - { - private Dictionary.Internal)> mGameServerInstances; - private Dictionary.Internal)> mPlayerInstances; - - public mInstances() - { - this.mGameServerInstances = new Dictionary.Internal)>(64); - this.mPlayerInstances = new Dictionary.Internal)>(1024 * 16); - } - - public TGameServer GetServerInstance(ulong hash, out bool isNew, out GameServer.Internal @internal) - { - lock (mGameServerInstances) - { - if (mGameServerInstances.TryGetValue(hash, out var data)) + if (stream.TryReadString(out var tool)) { - @internal = data.Item2; - isNew = false; - return data.Item1; + var body = (PlayerBody)stream.ReadInt8(); + var source = (ReasonOfDamage)stream.ReadInt8(); + + if (resources.TryGetPlayer(killer, out var killerClient)) + if (resources.TryGetPlayer(victim, out var victimClient)) + { + var args = new OnPlayerKillArguments + { + Killer = (TPlayer)killerClient, + KillerPosition = killerPos, + Victim = (TPlayer)victimClient, + VictimPosition = victimPos, + BodyPart = body, + SourceOfDamage = source, + KillerTool = tool + }; + + victimClient.OnDowned(); + server.OnAPlayerDownedAnotherPlayer(args); + } + } + } + + break; + } + case NetworkCommunication.OnPlayerJoining: + { + if (stream.CanRead(8 + 2)) + { + var steamID = stream.ReadUInt64(); + var stats = new PlayerStats(); + stats.Read(stream); + + + async Task mHandle() + { + var args = new PlayerJoiningArguments + { + Stats = stats, + Squad = Squads.NoSquad, + Team = Team.None + }; + + await server.OnPlayerJoiningToServer(steamID, args); + using (var response = Stream.Get()) + { + response.Write((byte)NetworkCommunication.SendPlayerStats); + response.Write(steamID); + args.Write(response); + server.WriteToSocket(response); + } } - @internal = new GameServer.Internal(); - TGameServer gameServer = GameServer.CreateInstance(@internal); - - isNew = true; - mGameServerInstances.Add(hash, (gameServer, @internal)); - return gameServer; + mHandle(); } + + break; } - public TPlayer GetPlayerInstance(ulong steamID, out bool isNew, out Player.Internal @internal) + case NetworkCommunication.SavePlayerStats: { - lock (this.mPlayerInstances) + if (stream.CanRead(8 + 4)) { - if (this.mPlayerInstances.TryGetValue(steamID, out var player)) - { - isNew = false; - @internal = player.Item2; - return player.Item1; - } + var steamID = stream.ReadUInt64(); + var stats = new PlayerStats(); + stats.Read(stream); - @internal = new Player.Internal(); - var pplayer = Player.CreateInstance(@internal); - - isNew = true; - mPlayerInstances.Add(steamID, (pplayer, @internal)); - return pplayer; + server.OnSavePlayerStats(steamID, stats); } + + break; } - public Player.Internal GetPlayerInternals(ulong steamID) + case NetworkCommunication.OnPlayerAskingToChangeRole: { - lock (mPlayerInstances) - return mPlayerInstances[steamID].Item2; + if (stream.CanRead(8 + 1)) + { + var steamID = stream.ReadUInt64(); + var role = (GameRole)stream.ReadInt8(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + async Task mHandle() + { + var accepted = await server.OnPlayerRequestingToChangeRole((TPlayer)client, role); + if (accepted) + server.SetRoleTo(steamID, role); + } + + mHandle(); + } + } + + break; + } + case NetworkCommunication.OnPlayerChangedRole: + { + if (stream.CanRead(8 + 1)) + { + var steamID = stream.ReadUInt64(); + var role = (GameRole)stream.ReadInt8(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + @internal.Role = role; + + client.OnChangedRole(role); + server.OnPlayerChangedRole((TPlayer)client, role); + } + } + + break; + } + case NetworkCommunication.OnPlayerJoinedASquad: + { + if (stream.CanRead(8 + 1)) + { + var steamID = stream.ReadUInt64(); + var squad = (Squads)stream.ReadInt8(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + @internal.Squad = squad; + + client.OnJoinedSquad(squad); + server.OnPlayerJoinedSquad((TPlayer)client, squad); + } + } + + break; + } + case NetworkCommunication.OnPlayerLeftSquad: + { + if (stream.CanRead(8)) + { + var steamID = stream.ReadUInt64(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + + var oldSquad = client.Squad; + var oldRole = client.Role; + @internal.Squad = Squads.NoSquad; + @internal.Role = GameRole.Assault; + + client.OnLeftSquad(oldSquad); + server.OnPlayerLeftSquad((TPlayer)client, oldSquad); + + if (oldRole != GameRole.Assault) + { + client.OnChangedRole(GameRole.Assault); + server.OnPlayerChangedRole((TPlayer)client, GameRole.Assault); + } + } + } + + break; + } + case NetworkCommunication.OnPlayerChangedTeam: + { + if (stream.CanRead(8 + 1)) + { + var steamID = stream.ReadUInt64(); + var team = (Team)stream.ReadInt8(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + + @internal.Team = team; + + client.OnChangedTeam(); + server.OnPlayerChangeTeam((TPlayer)client, team); + } + } + + break; + } + case NetworkCommunication.OnPlayerRequestingToSpawn: + { + if (stream.CanRead(2)) + { + var steamID = stream.ReadUInt64(); + + var request = new OnPlayerSpawnArguments(); + request.Read(stream); + var vehicleID = stream.ReadUInt16(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + async Task mHandle() + { + request = await server.OnPlayerSpawning((TPlayer)client, request); + + //Respond back. + using (var response = Stream.Get()) + { + response.Write((byte)NetworkCommunication.SpawnPlayer); + response.Write(steamID); + request.Write(response); + response.Write(vehicleID); + server.WriteToSocket(response); + } + } + + mHandle(); + } + } + + break; + } + case NetworkCommunication.OnPlayerReport: + { + if (stream.CanRead(8 + 8 + 1 + 2)) + { + var reporter = stream.ReadUInt64(); + var reported = stream.ReadUInt64(); + var reason = (ReportReason)stream.ReadInt8(); + stream.TryReadString(out var additionalInfo); + + if (resources.TryGetPlayer(reporter, out var reporterClient)) + if (resources.TryGetPlayer(reported, out var reportedClient)) + server.OnPlayerReported((TPlayer)reporterClient, (TPlayer)reportedClient, reason, additionalInfo); + } + + break; + } + case NetworkCommunication.OnPlayerSpawn: + { + if (stream.CanRead(8 + 2)) + { + var steamID = stream.ReadUInt64(); + if (resources.TryGetPlayer(steamID, out var client)) + { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + + var loadout = new PlayerLoadout(); + loadout.Read(stream); + @internal.CurrentLoadout = loadout; + + var wearings = new PlayerWearings(); + wearings.Read(stream); + @internal.CurrentWearings = wearings; + + @internal.IsAlive = true; + + client.OnSpawned(); + server.OnPlayerSpawned((TPlayer)client); + } + } + + break; + } + case NetworkCommunication.OnPlayerDie: + { + if (stream.CanRead(8)) + { + var steamid = stream.ReadUInt64(); + if (resources.TryGetPlayer(steamid, out var client)) + { + var @internal = mInstanceDatabase.GetPlayerInternals(steamid); + @internal.OnDie(); + + client.OnDied(); + server.OnPlayerDied((TPlayer)client); + } + } + + break; + } + case NetworkCommunication.NotifyNewMapRotation: + { + if (stream.CanRead(4)) + { + var count = stream.ReadUInt32(); + lock (resources._MapRotation) + { + resources._MapRotation.Clear(); + while (count > 0) + { + count--; + if (stream.TryReadString(out var map)) + resources._MapRotation.Add(map.ToUpperInvariant()); + } + } + } + + break; + } + case NetworkCommunication.NotifyNewGamemodeRotation: + { + if (stream.CanRead(4)) + { + var count = stream.ReadUInt32(); + lock (resources._GamemodeRotation) + { + resources._GamemodeRotation.Clear(); + while (count > 0) + { + count--; + if (stream.TryReadString(out var map)) + resources._GamemodeRotation.Add(map); + } + } + } + + break; + } + case NetworkCommunication.NotifyNewRoundState: + { + if (stream.CanRead(GameServer.mRoundSettings.Size)) + { + var oldState = resources._RoundSettings.State; + resources._RoundSettings.Read(stream); + var newState = resources._RoundSettings.State; + + if (newState != oldState) + { + server.OnGameStateChanged(oldState, newState); + + if (newState == GameState.Playing) + server.OnRoundStarted(); + else if (newState == GameState.EndingGame) + server.OnRoundEnded(); + } + } + + break; + } + case NetworkCommunication.OnPlayerAskingToChangeTeam: + { + if (stream.CanRead(8 + 1)) + { + var steamID = stream.ReadUInt64(); + var team = (Team)stream.ReadInt8(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + async Task mHandle() + { + var accepted = await server.OnPlayerRequestingToChangeTeam((TPlayer)client, team); + if (accepted) + server.ChangeTeam(steamID, team); + } + + mHandle(); + } + } + + break; + } + case NetworkCommunication.GameTick: + { + if (stream.CanRead(4 + 4 + 4)) + { + var decompressX = stream.ReadFloat(); + var decompressY = stream.ReadFloat(); + var decompressZ = stream.ReadFloat(); + + int playerCount = stream.ReadInt8(); + while (playerCount > 0) + { + playerCount--; + var steamID = stream.ReadUInt64(); + + //TODO, can compressed further later. + var com_posX = stream.ReadUInt16(); + var com_posY = stream.ReadUInt16(); + var com_posZ = stream.ReadUInt16(); + var com_healt = stream.ReadInt8(); + var standing = (PlayerStand)stream.ReadInt8(); + var side = (LeaningSide)stream.ReadInt8(); + var loadoutIndex = (LoadoutIndex)stream.ReadInt8(); + var inSeat = stream.ReadBool(); + var isBleeding = stream.ReadBool(); + var ping = stream.ReadUInt16(); + + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + if (@internal.IsAlive) + { + @internal.Position = new Vector3 + { + X = com_posX * decompressX, + Y = com_posY * decompressY, + Z = com_posZ * decompressZ + }; + @internal.HP = com_healt * 0.5f - 1f; + @internal.Standing = standing; + @internal.Leaning = side; + @internal.CurrentLoadoutIndex = loadoutIndex; + @internal.InVehicle = inSeat; + @internal.IsBleeding = isBleeding; + @internal.PingMs = ping; + } + } + } + + break; + } + case NetworkCommunication.OnPlayerGivenUp: + { + if (stream.CanRead(8)) + { + var steamID = stream.ReadUInt64(); + if (resources.TryGetPlayer(steamID, out var client)) + { + client.OnGivenUp(); + server.OnPlayerGivenUp((TPlayer)client); + } + } + + break; + } + case NetworkCommunication.OnPlayerRevivedAnother: + { + if (stream.CanRead(8 + 8)) + { + var from = stream.ReadUInt64(); + var to = stream.ReadUInt64(); + if (resources.TryGetPlayer(to, out var toClient)) + { + toClient.OnRevivedByAnotherPlayer(); + + if (resources.TryGetPlayer(from, out var fromClient)) + { + fromClient.OnRevivedAnotherPlayer(); + server.OnAPlayerRevivedAnotherPlayer((TPlayer)fromClient, (TPlayer)toClient); + } + } + } + + break; } } } -} + + public bool TryGetGameServer(IPAddress ip, ushort port, out TGameServer server) + { + var hash = ((ulong)port << 32) | ip.ToUInt(); + lock (mActiveConnections) + { + if (mActiveConnections.TryGetValue(hash, out var _server)) + { + server = _server.server; + return true; + } + } + + server = default; + return false; + } + + // --- Classes --- + private class mInstances where TPlayer : Player where TGameServer : GameServer + { + private readonly Dictionary.Internal)> mGameServerInstances; + private readonly Dictionary.Internal)> mPlayerInstances; + + public mInstances() + { + mGameServerInstances = new Dictionary.Internal)>(64); + mPlayerInstances = new Dictionary.Internal)>(1024 * 16); + } + + public TGameServer GetServerInstance(ulong hash, out bool isNew, out GameServer.Internal @internal) + { + lock (mGameServerInstances) + { + if (mGameServerInstances.TryGetValue(hash, out var data)) + { + @internal = data.Item2; + isNew = false; + return data.Item1; + } + + @internal = new GameServer.Internal(); + var gameServer = GameServer.CreateInstance(@internal); + + isNew = true; + mGameServerInstances.Add(hash, (gameServer, @internal)); + return gameServer; + } + } + + public TPlayer GetPlayerInstance(ulong steamID, out bool isNew, out Player.Internal @internal) + { + lock (mPlayerInstances) + { + if (mPlayerInstances.TryGetValue(steamID, out var player)) + { + isNew = false; + @internal = player.Item2; + return player.Item1; + } + + @internal = new Player.Internal(); + var pplayer = Player.CreateInstance(@internal); + + isNew = true; + mPlayerInstances.Add(steamID, (pplayer, @internal)); + return pplayer; + } + } + + public Player.Internal GetPlayerInternals(ulong steamID) + { + lock (mPlayerInstances) + { + return mPlayerInstances[steamID].Item2; + } + } + } +} \ No newline at end of file diff --git a/BattleBitAPI/Storage/DiskStorage.cs b/BattleBitAPI/Storage/DiskStorage.cs index 512d3b4..2c349d1 100644 --- a/BattleBitAPI/Storage/DiskStorage.cs +++ b/BattleBitAPI/Storage/DiskStorage.cs @@ -1,41 +1,45 @@ using BattleBitAPI.Common; -namespace BattleBitAPI.Storage +namespace BattleBitAPI.Storage; + +public class DiskStorage : IPlayerStatsDatabase { - public class DiskStorage : IPlayerStatsDatabase + private readonly string mDirectory; + + public DiskStorage(string directory) { - private string mDirectory; - public DiskStorage(string directory) - { - var info = new DirectoryInfo(directory); - if (!info.Exists) - info.Create(); + var info = new DirectoryInfo(directory); + if (!info.Exists) + info.Create(); - this.mDirectory = info.FullName + Path.DirectorySeparatorChar; - } + mDirectory = info.FullName + Path.DirectorySeparatorChar; + } - public async Task GetPlayerStatsOf(ulong steamID) - { - var file = this.mDirectory + steamID + ".data"; - if (File.Exists(file)) - { - try - { - var data = await File.ReadAllBytesAsync(file); - return new PlayerStats(data); - } - catch { } - } - return null; - } - public async Task SavePlayerStatsOf(ulong steamID, PlayerStats stats) - { - var file = this.mDirectory + steamID + ".data"; + public async Task GetPlayerStatsOf(ulong steamID) + { + var file = mDirectory + steamID + ".data"; + if (File.Exists(file)) try { - await File.WriteAllBytesAsync(file, stats.SerializeToByteArray()); + var data = await File.ReadAllBytesAsync(file); + return new PlayerStats(data); } - catch { } + catch + { + } + + return null; + } + + public async Task SavePlayerStatsOf(ulong steamID, PlayerStats stats) + { + var file = mDirectory + steamID + ".data"; + try + { + await File.WriteAllBytesAsync(file, stats.SerializeToByteArray()); + } + catch + { } } -} +} \ No newline at end of file diff --git a/BattleBitAPI/Storage/IPlayerStatsDatabase.cs b/BattleBitAPI/Storage/IPlayerStatsDatabase.cs index 6689cfb..55ad0d5 100644 --- a/BattleBitAPI/Storage/IPlayerStatsDatabase.cs +++ b/BattleBitAPI/Storage/IPlayerStatsDatabase.cs @@ -1,10 +1,9 @@ using BattleBitAPI.Common; -namespace BattleBitAPI.Storage +namespace BattleBitAPI.Storage; + +public interface IPlayerStatsDatabase { - public interface IPlayerStatsDatabase - { - public Task GetPlayerStatsOf(ulong steamID); - public Task SavePlayerStatsOf(ulong steamID, PlayerStats stats); - } -} + public Task GetPlayerStatsOf(ulong steamID); + public Task SavePlayerStatsOf(ulong steamID, PlayerStats stats); +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index 022a2b9..cad05ba 100644 --- a/Program.cs +++ b/Program.cs @@ -1,28 +1,26 @@ using BattleBitAPI; using BattleBitAPI.Common; using BattleBitAPI.Server; -using System.Threading.Channels; -using System.Xml; -class Program +internal class Program { - static void Main(string[] args) + private static void Main(string[] args) { var listener = new ServerListener(); listener.Start(29294); Thread.Sleep(-1); } - - } -class MyPlayer : Player + +internal class MyPlayer : Player { public override async Task OnConnected() { } } -class MyGameServer : GameServer + +internal class MyGameServer : GameServer { public override async Task OnConnected() { @@ -36,28 +34,34 @@ class MyGameServer : GameServer { await Console.Out.WriteLineAsync("Connected: " + player); } + public override async Task OnPlayerSpawned(MyPlayer player) { await Console.Out.WriteLineAsync("Spawned: " + player); } + public override async Task OnAPlayerDownedAnotherPlayer(OnPlayerKillArguments args) { await Console.Out.WriteLineAsync("Downed: " + args.Victim); } + public override async Task OnPlayerGivenUp(MyPlayer player) { await Console.Out.WriteLineAsync("Giveup: " + player); } + public override async Task OnPlayerDied(MyPlayer player) { await Console.Out.WriteLineAsync("Died: " + player); } + public override async Task OnAPlayerRevivedAnotherPlayer(MyPlayer from, MyPlayer to) { await Console.Out.WriteLineAsync(from + " revived " + to); } + public override async Task OnPlayerDisconnected(MyPlayer player) { await Console.Out.WriteLineAsync("Disconnected: " + player); } -} +} \ No newline at end of file