├── .dockerignore ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── BattleBitAPI ├── Common │ ├── Arguments │ │ ├── OnPlayerKillArguments.cs │ │ ├── OnPlayerSpawnArguments.cs │ │ └── PlayerJoiningArgument.cs │ ├── Conts.cs │ ├── Data │ │ ├── Attachment.cs │ │ ├── EndGamePlayer.cs │ │ ├── EndGamePlayer1.cs │ │ ├── Gadget.cs │ │ ├── Gadgets.cs │ │ ├── Map.cs │ │ ├── PlayerLoadout.cs │ │ ├── PlayerStats.cs │ │ ├── PlayerWearings.cs │ │ ├── VoxelBlockData.cs │ │ └── Weapon.cs │ ├── Datasets │ │ ├── Attachments.cs │ │ └── Weapons.cs │ ├── Enums │ │ ├── AttachmentType.cs │ │ ├── ChatChannel.cs │ │ ├── DamageReason.cs │ │ ├── GameRole.cs │ │ ├── GameState.cs │ │ ├── LeaningSide.cs │ │ ├── LoadoutIndex.cs │ │ ├── LogLevel.cs │ │ ├── MapDayNight.cs │ │ ├── MapSize.cs │ │ ├── PlayerBody.cs │ │ ├── PlayerSpawningPoint.cs │ │ ├── PlayerStand.cs │ │ ├── ReportReason.cs │ │ ├── Roles.cs │ │ ├── SpawningRule.cs │ │ ├── Squads.cs │ │ ├── Team.cs │ │ ├── VehicleType.cs │ │ ├── VoxelTextures.cs │ │ └── WeaponType.cs │ ├── Extentions │ │ └── Extentions.cs │ ├── Serialization │ │ ├── IStreamSerializble.cs │ │ └── Stream.cs │ └── Threading │ │ └── ThreadSafe.cs ├── Networking │ └── NetworkCommuncation.cs ├── Pooling │ └── ItemPooling.cs ├── Server │ ├── GameServer.cs │ ├── Internal │ │ ├── GamemodeRotation.cs │ │ ├── MapRotation.cs │ │ ├── PlayerModifications.cs │ │ ├── RoundSettings.cs │ │ ├── ServerSettings.cs │ │ └── Squad.cs │ ├── Player.cs │ └── ServerListener.cs └── Storage │ ├── DiskStorage.cs │ └── IPlayerStatsDatabase.cs ├── CommunityServerAPI.csproj ├── CommunityServerAPI.sln ├── Dockerfile ├── LICENSE ├── README-esES.md ├── README-koKR.md ├── README-ptBR.md ├── README-ruRU.md ├── README-zhCN.md ├── README.md └── docker-compose.yml /.dockerignore: -------------------------------------------------------------------------------- 1 | # User-specific files 2 | *.suo 3 | *.user 4 | *.userosscache 5 | *.sln.docstates 6 | 7 | # Build results 8 | [Dd]ebug/ 9 | [Dd]ebugPublic/ 10 | [Rr]elease/ 11 | [Rr]eleases/ 12 | x64/ 13 | x86/ 14 | bld/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | [Ll]og/ 18 | 19 | # Visual Studio 2015 cache/options directory 20 | .vs/ 21 | # Uncomment if you have tasks that create the project's static files in wwwroot 22 | #wwwroot/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | # NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | *_i.c 33 | *_p.c 34 | *_i.h 35 | *.ilk 36 | *.meta 37 | *.obj 38 | *.pch 39 | *.pdb 40 | *.pgc 41 | *.pgd 42 | *.rsp 43 | *.sbr 44 | *.tlb 45 | *.tli 46 | *.tlh 47 | *.tmp 48 | *.tmp_proj 49 | *.log 50 | *.vspscc 51 | *.vssscc 52 | .builds 53 | *.pidb 54 | *.svclog 55 | *.scc 56 | 57 | # Chutzpah Test files 58 | _Chutzpah* 59 | 60 | # Visual C++ cache files 61 | ipch/ 62 | *.aps 63 | *.ncb 64 | *.opendb 65 | *.opensdf 66 | *.sdf 67 | *.cachefile 68 | *.VC.db 69 | *.VC.VC.opendb 70 | 71 | # Visual Studio profiler 72 | *.psess 73 | *.vsp 74 | *.vspx 75 | *.sap 76 | 77 | 78 | # ReSharper is a .NET coding add-in 79 | _ReSharper*/ 80 | *.[Rr]e[Ss]harper 81 | *.DotSettings.user 82 | 83 | # JustCode is a .NET coding add-in 84 | .JustCode 85 | 86 | # TeamCity is a build add-in 87 | _TeamCity* 88 | 89 | # DotCover is a Code Coverage Tool 90 | *.dotCover 91 | 92 | # Visual Studio code coverage results 93 | *.coverage 94 | *.coveragexml 95 | 96 | # Installshield output folder 97 | [Ee]xpress/ 98 | 99 | # DocProject is a documentation generator add-in 100 | DocProject/buildhelp/ 101 | DocProject/Help/*.HxT 102 | DocProject/Help/*.HxC 103 | DocProject/Help/*.hhc 104 | DocProject/Help/*.hhk 105 | DocProject/Help/*.hhp 106 | DocProject/Help/Html2 107 | DocProject/Help/html 108 | 109 | # Publish Web Output 110 | *.[Pp]ublish.xml 111 | *.azurePubxml 112 | *.pubxml 113 | *.publishproj 114 | 115 | # NuGet Packages 116 | *.nupkg 117 | **/packages/* 118 | !**/packages/build/ 119 | # NuGet v3's project.json files produces more ignoreable files 120 | *.nuget.props 121 | *.nuget.targets 122 | 123 | # Windows Store app package directories and files 124 | AppPackages/ 125 | BundleArtifacts/ 126 | Package.StoreAssociation.xml 127 | _pkginfo.txt 128 | 129 | # Visual Studio cache files 130 | # files ending in .cache can be ignored 131 | *.[Cc]ache 132 | # but keep track of directories ending in .cache 133 | !*.[Cc]ache/ 134 | 135 | # Others 136 | ClientBin/ 137 | ~$* 138 | *~ 139 | *.dbmdl 140 | *.dbproj.schemaview 141 | *.jfm 142 | *.pfx 143 | *.publishsettings 144 | 145 | # Visual Studio 6 build log 146 | *.plg 147 | 148 | # Paket dependency manager 149 | .paket/paket.exe 150 | paket-files/ 151 | 152 | # JetBrains Rider 153 | .idea/ 154 | *.sln.iml 155 | 156 | # CodeRush 157 | .cr/ 158 | 159 | # Python Tools for Visual Studio (PTVS) 160 | __pycache__/ 161 | *.pyc 162 | 163 | # Cake - Uncomment if you are using it 164 | tools/Cake.CoreCLR 165 | .vscode 166 | .dotnet 167 | Dockerfile 168 | 169 | # .env file contains default environment variables for docker 170 | .env 171 | .git -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[Bug]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature Request]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific files 2 | *.suo 3 | *.user 4 | *.userosscache 5 | *.sln.docstates 6 | 7 | # Build results 8 | [Dd]ebug/ 9 | [Dd]ebugPublic/ 10 | [Rr]elease/ 11 | [Rr]eleases/ 12 | x64/ 13 | x86/ 14 | bld/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | [Ll]og/ 18 | 19 | # Visual Studio 2015 cache/options directory 20 | .vs/ 21 | # Uncomment if you have tasks that create the project's static files in wwwroot 22 | #wwwroot/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | # NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | *_i.c 33 | *_p.c 34 | *_i.h 35 | *.ilk 36 | *.meta 37 | *.obj 38 | *.pch 39 | *.pdb 40 | *.pgc 41 | *.pgd 42 | *.rsp 43 | *.sbr 44 | *.tlb 45 | *.tli 46 | *.tlh 47 | *.tmp 48 | *.tmp_proj 49 | *.log 50 | *.vspscc 51 | *.vssscc 52 | .builds 53 | *.pidb 54 | *.svclog 55 | *.scc 56 | 57 | # Chutzpah Test files 58 | _Chutzpah* 59 | 60 | # Visual C++ cache files 61 | ipch/ 62 | *.aps 63 | *.ncb 64 | *.opendb 65 | *.opensdf 66 | *.sdf 67 | *.cachefile 68 | *.VC.db 69 | *.VC.VC.opendb 70 | 71 | # Visual Studio profiler 72 | *.psess 73 | *.vsp 74 | *.vspx 75 | *.sap 76 | 77 | 78 | # ReSharper is a .NET coding add-in 79 | _ReSharper*/ 80 | *.[Rr]e[Ss]harper 81 | *.DotSettings.user 82 | 83 | # JustCode is a .NET coding add-in 84 | .JustCode 85 | 86 | # TeamCity is a build add-in 87 | _TeamCity* 88 | 89 | # DotCover is a Code Coverage Tool 90 | *.dotCover 91 | 92 | # Visual Studio code coverage results 93 | *.coverage 94 | *.coveragexml 95 | 96 | # Installshield output folder 97 | [Ee]xpress/ 98 | 99 | # DocProject is a documentation generator add-in 100 | DocProject/buildhelp/ 101 | DocProject/Help/*.HxT 102 | DocProject/Help/*.HxC 103 | DocProject/Help/*.hhc 104 | DocProject/Help/*.hhk 105 | DocProject/Help/*.hhp 106 | DocProject/Help/Html2 107 | DocProject/Help/html 108 | 109 | # Publish Web Output 110 | *.[Pp]ublish.xml 111 | *.azurePubxml 112 | *.pubxml 113 | *.publishproj 114 | 115 | # NuGet Packages 116 | *.nupkg 117 | **/packages/* 118 | !**/packages/build/ 119 | # NuGet v3's project.json files produces more ignoreable files 120 | *.nuget.props 121 | *.nuget.targets 122 | 123 | # Windows Store app package directories and files 124 | AppPackages/ 125 | BundleArtifacts/ 126 | Package.StoreAssociation.xml 127 | _pkginfo.txt 128 | 129 | # Visual Studio cache files 130 | # files ending in .cache can be ignored 131 | *.[Cc]ache 132 | # but keep track of directories ending in .cache 133 | !*.[Cc]ache/ 134 | 135 | # Others 136 | ClientBin/ 137 | ~$* 138 | *~ 139 | *.dbmdl 140 | *.dbproj.schemaview 141 | *.jfm 142 | *.pfx 143 | *.publishsettings 144 | 145 | # Visual Studio 6 build log 146 | *.plg 147 | 148 | # Paket dependency manager 149 | .paket/paket.exe 150 | paket-files/ 151 | 152 | # JetBrains Rider 153 | .idea/ 154 | *.sln.iml 155 | 156 | # CodeRush 157 | .cr/ 158 | 159 | # Python Tools for Visual Studio (PTVS) 160 | __pycache__/ 161 | *.pyc 162 | 163 | # Cake - Uncomment if you are using it 164 | tools/Cake.CoreCLR 165 | .vscode 166 | .dotnet 167 | # Dockerfile 168 | 169 | # .env file contains default environment variables for docker 170 | .env 171 | .git/ -------------------------------------------------------------------------------- /BattleBitAPI/Common/Arguments/OnPlayerKillArguments.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | 3 | namespace BattleBitAPI.Common 4 | { 5 | public struct OnPlayerKillArguments where TPlayer : Player 6 | { 7 | public TPlayer Killer; 8 | public Vector3 KillerPosition; 9 | 10 | public TPlayer Victim; 11 | public Vector3 VictimPosition; 12 | 13 | public string KillerTool; 14 | public PlayerBody BodyPart; 15 | public ReasonOfDamage SourceOfDamage; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Arguments/OnPlayerSpawnArguments.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | 3 | namespace BattleBitAPI.Common 4 | { 5 | public struct OnPlayerSpawnArguments 6 | { 7 | public PlayerSpawningPosition RequestedPoint { get; private set; } 8 | public PlayerLoadout Loadout; 9 | public PlayerWearings Wearings; 10 | public Vector3 SpawnPosition; 11 | public Vector3 LookDirection; 12 | public PlayerStand SpawnStand; 13 | public float SpawnProtection; 14 | 15 | public void Write(Common.Serialization.Stream ser) 16 | { 17 | ser.Write((byte)RequestedPoint); 18 | Loadout.Write(ser); 19 | Wearings.Write(ser); 20 | ser.Write(SpawnPosition.X); 21 | ser.Write(SpawnPosition.Y); 22 | ser.Write(SpawnPosition.Z); 23 | ser.Write(LookDirection.X); 24 | ser.Write(LookDirection.Y); 25 | ser.Write(LookDirection.Z); 26 | ser.Write((byte)SpawnStand); 27 | ser.Write(SpawnProtection); 28 | } 29 | public void Read(Common.Serialization.Stream ser) 30 | { 31 | RequestedPoint = (PlayerSpawningPosition)ser.ReadInt8(); 32 | Loadout.Read(ser); 33 | Wearings.Read(ser); 34 | SpawnPosition = new Vector3() 35 | { 36 | X = ser.ReadFloat(), 37 | Y = ser.ReadFloat(), 38 | Z = ser.ReadFloat() 39 | }; 40 | LookDirection = new Vector3() 41 | { 42 | X = ser.ReadFloat(), 43 | Y = ser.ReadFloat(), 44 | Z = ser.ReadFloat() 45 | }; 46 | SpawnStand = (PlayerStand)ser.ReadInt8(); 47 | SpawnProtection = ser.ReadFloat(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BattleBitAPI.Common 4 | { 5 | public class PlayerJoiningArguments 6 | { 7 | public PlayerStats Stats; 8 | public Team Team; 9 | public Squads Squad; 10 | 11 | public void Write(BattleBitAPI.Common.Serialization.Stream ser) 12 | { 13 | this.Stats.Write(ser); 14 | ser.Write((byte)this.Team); 15 | ser.Write((byte)this.Squad); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Conts.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI 2 | { 3 | public static class Const 4 | { 5 | public static string Version = "1.0.8v"; 6 | 7 | // ---- Networking ---- 8 | /// 9 | /// Maximum data size for a single package. 4MB is default. 10 | /// 11 | public const int MaxNetworkPackageSize = 1024 * 1024 * 4;//4mb 12 | /// 13 | /// How long should server/client wait until connection is determined as timed out when no packages is being sent for long time. 14 | /// 15 | public const int NetworkTimeout = 60 * 1000;//60 seconds 16 | /// 17 | /// How frequently client/server will send keep alive to each other when no message is being sent to each other for a while. 18 | /// 19 | public const int NetworkKeepAlive = 5 * 1000;//15 seconds 20 | /// 21 | /// How long server/client will wait other side to send their hail/initial package. In miliseconds. 22 | /// 23 | #if DEBUG 24 | public const int HailConnectTimeout = 20 * 1000; 25 | #else 26 | public const int HailConnectTimeout = 2 * 1000; 27 | #endif 28 | 29 | // ---- Server Fields ---- 30 | public const int MinServerNameLength = 5; 31 | public const int MaxServerNameLength = 400; 32 | 33 | public const int MaxTokenSize = 512; 34 | 35 | public const int MinGamemodeNameLength = 2; 36 | public const int MaxGamemodeNameLength = 64; 37 | 38 | public const int MinMapNameLength = 2; 39 | public const int MaxMapNameLength = 64; 40 | 41 | public const int MinLoadingScreenTextLength = 0; 42 | public const int MaxLoadingScreenTextLength = 1024 * 8; 43 | 44 | public const int MinServerRulesTextLength = 0; 45 | public const int MaxServerRulesTextLength = 1024 * 8; 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/Attachment.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | using System; 3 | 4 | namespace BattleBitAPI.Common 5 | { 6 | public class Attachment : IEquatable, IEquatable 7 | { 8 | public string Name { get; private set; } 9 | public AttachmentType AttachmentType { get; private set; } 10 | public Attachment(string name, AttachmentType attachmentType) 11 | { 12 | Name = name; 13 | AttachmentType = attachmentType; 14 | } 15 | 16 | public override string ToString() 17 | { 18 | return this.Name; 19 | } 20 | public bool Equals(string other) 21 | { 22 | if (other == null) 23 | return false; 24 | return this.Name.Equals(other); 25 | } 26 | public bool Equals(Attachment other) 27 | { 28 | if (other == null) 29 | return false; 30 | return this.Name.Equals(other.Name); 31 | } 32 | 33 | public static bool operator ==(string left, Attachment right) 34 | { 35 | bool leftNull = object.ReferenceEquals(left, null); 36 | bool rightNull = object.ReferenceEquals(right, null); 37 | if (leftNull && rightNull) 38 | return true; 39 | if (leftNull || rightNull) 40 | return false; 41 | return right.Name.Equals(left); 42 | } 43 | public static bool operator !=(string left, Attachment right) 44 | { 45 | bool leftNull = object.ReferenceEquals(left, null); 46 | bool rightNull = object.ReferenceEquals(right, null); 47 | if (leftNull && rightNull) 48 | return true; 49 | if (leftNull || rightNull) 50 | return false; 51 | return right.Name.Equals(left); 52 | } 53 | public static bool operator ==(Attachment right, string left) 54 | { 55 | bool leftNull = object.ReferenceEquals(left, null); 56 | bool rightNull = object.ReferenceEquals(right, null); 57 | if (leftNull && rightNull) 58 | return true; 59 | if (leftNull || rightNull) 60 | return false; 61 | return right.Name.Equals(left); 62 | } 63 | public static bool operator !=(Attachment right, string left) 64 | { 65 | bool leftNull = object.ReferenceEquals(left, null); 66 | bool rightNull = object.ReferenceEquals(right, null); 67 | if (leftNull && rightNull) 68 | return true; 69 | if (leftNull || rightNull) 70 | return false; 71 | return right.Name.Equals(left); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/EndGamePlayer.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public struct EndGamePlayer : IComparable> where TPlayer : Player 4 | { 5 | public Player Player; 6 | public int Score; 7 | 8 | public EndGamePlayer(Player player, int score) 9 | { 10 | this.Player = player; 11 | this.Score = score; 12 | } 13 | public int CompareTo(EndGamePlayer other) 14 | { 15 | return other.Score.CompareTo(this.Score); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/EndGamePlayer1.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public class EndGamePlayer 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/Gadget.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public class Gadget : IEquatable, IEquatable 4 | { 5 | public string Name { get; private set; } 6 | public Gadget(string name) 7 | { 8 | Name = name; 9 | } 10 | 11 | public override string ToString() 12 | { 13 | return this.Name; 14 | } 15 | public bool Equals(string other) 16 | { 17 | if (other == null) 18 | return false; 19 | return this.Name.Equals(other); 20 | } 21 | public bool Equals(Gadget other) 22 | { 23 | if (other == null) 24 | return false; 25 | return this.Name.Equals(other.Name); 26 | } 27 | 28 | public static bool operator ==(string left, Gadget right) 29 | { 30 | bool leftNull = object.ReferenceEquals(left,null); 31 | bool rightNull = object.ReferenceEquals(right, null); 32 | if (leftNull && rightNull) 33 | return true; 34 | if (leftNull || rightNull) 35 | return false; 36 | return right.Name.Equals(left); 37 | } 38 | public static bool operator !=(string left, Gadget right) 39 | { 40 | bool leftNull = object.ReferenceEquals(left, null); 41 | bool rightNull = object.ReferenceEquals(right, null); 42 | if (leftNull && rightNull) 43 | return true; 44 | if (leftNull || rightNull) 45 | return false; 46 | return right.Name.Equals(left); 47 | } 48 | public static bool operator ==(Gadget right, string left) 49 | { 50 | bool leftNull = object.ReferenceEquals(left, null); 51 | bool rightNull = object.ReferenceEquals(right, null); 52 | if (leftNull && rightNull) 53 | return true; 54 | if (leftNull || rightNull) 55 | return false; 56 | return right.Name.Equals(left); 57 | } 58 | public static bool operator !=(Gadget right, string left) 59 | { 60 | bool leftNull = object.ReferenceEquals(left, null); 61 | bool rightNull = object.ReferenceEquals(right, null); 62 | if (leftNull && rightNull) 63 | return true; 64 | if (leftNull || rightNull) 65 | return false; 66 | return right.Name.Equals(left); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/Gadgets.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace BattleBitAPI.Common 4 | { 5 | public static class Gadgets 6 | { 7 | // ----- Private Variables ----- 8 | private static Dictionary mGadgets; 9 | 10 | // ----- Public Variables ----- 11 | public static readonly Gadget Bandage = new Gadget("Bandage"); 12 | public static readonly Gadget Binoculars = new Gadget("Binoculars"); 13 | public static readonly Gadget RangeFinder = new Gadget("Range Finder"); 14 | public static readonly Gadget RepairTool = new Gadget("Repair Tool"); 15 | public static readonly Gadget C4 = new Gadget("C4"); 16 | public static readonly Gadget Claymore = new Gadget("Claymore"); 17 | public static readonly Gadget M320SmokeGrenadeLauncher = new Gadget("M320 Smoke Grenade Launcher"); 18 | public static readonly Gadget SmallAmmoKit = new Gadget("Small Ammo Kit"); 19 | public static readonly Gadget AntiPersonnelMine = new Gadget("Anti Personnel Mine"); 20 | public static readonly Gadget AntiVehicleMine = new Gadget("Anti Vehicle Mine"); 21 | public static readonly Gadget MedicKit = new Gadget("Medic Kit"); 22 | public static readonly Gadget Rpg7HeatExplosive = new Gadget("Rpg7 Heat Explosive"); 23 | public static readonly Gadget RiotShield = new Gadget("Riot Shield"); 24 | public static readonly Gadget FragGrenade = new Gadget("Frag Grenade"); 25 | public static readonly Gadget ImpactGrenade = new Gadget("Impact Grenade"); 26 | public static readonly Gadget AntiVehicleGrenade = new Gadget("Anti Vehicle Grenade"); 27 | public static readonly Gadget SmokeGrenadeBlue = new Gadget("Smoke Grenade Blue"); 28 | public static readonly Gadget SmokeGrenadeGreen = new Gadget("Smoke Grenade Green"); 29 | public static readonly Gadget SmokeGrenadeRed = new Gadget("Smoke Grenade Red"); 30 | public static readonly Gadget SmokeGrenadeWhite = new Gadget("Smoke Grenade White"); 31 | public static readonly Gadget Flare = new Gadget("Flare"); 32 | public static readonly Gadget SledgeHammer = new Gadget("Sledge Hammer"); 33 | public static readonly Gadget AdvancedBinoculars = new Gadget("Advanced Binoculars"); 34 | public static readonly Gadget Mdx201 = new Gadget("Mdx 201"); 35 | public static readonly Gadget BinoSoflam = new Gadget("Bino Soflam"); 36 | public static readonly Gadget HeavyAmmoKit = new Gadget("Heavy Ammo Kit"); 37 | public static readonly Gadget Rpg7Pgo7Tandem = new Gadget("Rpg7 Pgo7 Tandem"); 38 | public static readonly Gadget Rpg7Pgo7HeatExplosive = new Gadget("Rpg7 Pgo7 Heat Explosive"); 39 | public static readonly Gadget Rpg7Pgo7Fragmentation = new Gadget("Rpg7 Pgo7 Fragmentation"); 40 | public static readonly Gadget Rpg7Fragmentation = new Gadget("Rpg7 Fragmentation"); 41 | public static readonly Gadget GrapplingHook = new Gadget("Grappling Hook"); 42 | public static readonly Gadget AirDrone = new Gadget("Air Drone"); 43 | public static readonly Gadget Flashbang = new Gadget("Flashbang"); 44 | public static readonly Gadget Pickaxe = new Gadget("Pickaxe"); 45 | public static readonly Gadget SuicideC4 = new Gadget("SuicideC4"); 46 | public static readonly Gadget SledgeHammerSkinA = new Gadget("Sledge Hammer SkinA"); 47 | public static readonly Gadget SledgeHammerSkinB = new Gadget("Sledge Hammer SkinB"); 48 | public static readonly Gadget SledgeHammerSkinC = new Gadget("Sledge Hammer SkinC"); 49 | public static readonly Gadget PickaxeIronPickaxe = new Gadget("Pickaxe IronPickaxe"); 50 | 51 | // ----- Public Calls ----- 52 | public static bool TryFind(string name, out Gadget item) 53 | { 54 | return mGadgets.TryGetValue(name, out item); 55 | } 56 | 57 | // ----- Init ----- 58 | static Gadgets() 59 | { 60 | var members = typeof(Gadgets).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); 61 | mGadgets = new Dictionary(members.Length); 62 | foreach (var memberInfo in members) 63 | { 64 | if (memberInfo.MemberType == System.Reflection.MemberTypes.Field) 65 | { 66 | var field = ((FieldInfo)memberInfo); 67 | if (field.FieldType == typeof(Gadget)) 68 | { 69 | var gad = (Gadget)field.GetValue(null); 70 | mGadgets.Add(gad.Name, gad); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/Map.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public class Map : IEquatable, IEquatable 4 | { 5 | public string Name { get; private set; } 6 | public Map(string name) 7 | { 8 | Name = name; 9 | } 10 | 11 | public override string ToString() 12 | { 13 | return this.Name; 14 | } 15 | public bool Equals(string other) 16 | { 17 | if (other == null) 18 | return false; 19 | return this.Name.Equals(other); 20 | } 21 | public bool Equals(Map other) 22 | { 23 | if (other == null) 24 | return false; 25 | return this.Name.Equals(other.Name); 26 | } 27 | 28 | public static bool operator ==(string left, Map right) 29 | { 30 | bool leftNull = object.ReferenceEquals(left, null); 31 | bool rightNull = object.ReferenceEquals(right, null); 32 | if (leftNull && rightNull) 33 | return true; 34 | if (leftNull || rightNull) 35 | return false; 36 | return right.Name.Equals(left); 37 | } 38 | public static bool operator !=(string left, Map right) 39 | { 40 | bool leftNull = object.ReferenceEquals(left, null); 41 | bool rightNull = object.ReferenceEquals(right, null); 42 | if (leftNull && rightNull) 43 | return true; 44 | if (leftNull || rightNull) 45 | return false; 46 | return right.Name.Equals(left); 47 | } 48 | public static bool operator ==(Map right, string left) 49 | { 50 | bool leftNull = object.ReferenceEquals(left, null); 51 | bool rightNull = object.ReferenceEquals(right, null); 52 | if (leftNull && rightNull) 53 | return true; 54 | if (leftNull || rightNull) 55 | return false; 56 | return right.Name.Equals(left); 57 | } 58 | public static bool operator !=(Map right, string left) 59 | { 60 | bool leftNull = object.ReferenceEquals(left, null); 61 | bool rightNull = object.ReferenceEquals(right, null); 62 | if (leftNull && rightNull) 63 | return true; 64 | if (leftNull || rightNull) 65 | return false; 66 | return right.Name.Equals(left); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/PlayerLoadout.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public struct PlayerLoadout 4 | { 5 | public WeaponItem PrimaryWeapon; 6 | public WeaponItem SecondaryWeapon; 7 | public string FirstAidName; 8 | public string LightGadgetName; 9 | public string HeavyGadgetName; 10 | public string ThrowableName; 11 | 12 | public byte PrimaryExtraMagazines; 13 | public byte SecondaryExtraMagazines; 14 | public byte FirstAidExtra; 15 | public byte LightGadgetExtra; 16 | public byte HeavyGadgetExtra; 17 | public byte ThrowableExtra; 18 | 19 | public Gadget FirstAid 20 | { 21 | get 22 | { 23 | if (Gadgets.TryFind(FirstAidName, out var gadget)) 24 | return gadget; 25 | return null; 26 | } 27 | set 28 | { 29 | if (value == null) 30 | this.FirstAidName = "none"; 31 | else 32 | this.FirstAidName = value.Name; 33 | } 34 | } 35 | public Gadget LightGadget 36 | { 37 | get 38 | { 39 | if (Gadgets.TryFind(LightGadgetName, out var gadget)) 40 | return gadget; 41 | return null; 42 | } 43 | set 44 | { 45 | if (value == null) 46 | this.LightGadgetName = "none"; 47 | else 48 | this.LightGadgetName = value.Name; 49 | } 50 | } 51 | public Gadget HeavyGadget 52 | { 53 | get 54 | { 55 | if (Gadgets.TryFind(HeavyGadgetName, out var gadget)) 56 | return gadget; 57 | return null; 58 | } 59 | set 60 | { 61 | if (value == null) 62 | this.HeavyGadgetName = "none"; 63 | else 64 | this.HeavyGadgetName = value.Name; 65 | } 66 | } 67 | public Gadget Throwable 68 | { 69 | get 70 | { 71 | if (Gadgets.TryFind(ThrowableName, out var gadget)) 72 | return gadget; 73 | return null; 74 | } 75 | set 76 | { 77 | if (value == null) 78 | this.ThrowableName = "none"; 79 | else 80 | this.ThrowableName = value.Name; 81 | } 82 | } 83 | 84 | public bool HasGadget(Gadget gadget) 85 | { 86 | if (this.FirstAid == gadget) 87 | return true; 88 | if (this.LightGadget == gadget) 89 | return true; 90 | if (this.HeavyGadget == gadget) 91 | return true; 92 | if (this.Throwable == gadget) 93 | return true; 94 | return false; 95 | } 96 | 97 | public void Write(Common.Serialization.Stream ser) 98 | { 99 | this.PrimaryWeapon.Write(ser); 100 | this.SecondaryWeapon.Write(ser); 101 | ser.WriteStringItem(this.FirstAidName); 102 | ser.WriteStringItem(this.LightGadgetName); 103 | ser.WriteStringItem(this.HeavyGadgetName); 104 | ser.WriteStringItem(this.ThrowableName); 105 | 106 | ser.Write(this.PrimaryExtraMagazines); 107 | ser.Write(this.SecondaryExtraMagazines); 108 | ser.Write(this.FirstAidExtra); 109 | ser.Write(this.LightGadgetExtra); 110 | ser.Write(this.HeavyGadgetExtra); 111 | ser.Write(this.ThrowableExtra); 112 | } 113 | public void Read(Common.Serialization.Stream ser) 114 | { 115 | this.PrimaryWeapon.Read(ser); 116 | this.SecondaryWeapon.Read(ser); 117 | ser.TryReadString(out this.FirstAidName); 118 | ser.TryReadString(out this.LightGadgetName); 119 | ser.TryReadString(out this.HeavyGadgetName); 120 | ser.TryReadString(out this.ThrowableName); 121 | 122 | this.PrimaryExtraMagazines = ser.ReadInt8(); 123 | this.SecondaryExtraMagazines = ser.ReadInt8(); 124 | this.FirstAidExtra = ser.ReadInt8(); 125 | this.LightGadgetExtra = ser.ReadInt8(); 126 | this.HeavyGadgetExtra = ser.ReadInt8(); 127 | this.ThrowableExtra = ser.ReadInt8(); 128 | } 129 | } 130 | public struct WeaponItem 131 | { 132 | public string ToolName; 133 | public string MainSightName; 134 | public byte MainSightIndex; 135 | public string TopSightName; 136 | public byte TopSightIndex; 137 | public string CantedSightName; 138 | public byte MainCantedIndex; 139 | public string BarrelName; 140 | public byte MainBarrelIndex; 141 | public string SideRailName; 142 | public byte MainSideRailIndex; 143 | public string UnderRailName; 144 | public byte MainUnderRailIndex; 145 | public string BoltActionName; 146 | public byte MainBoltActionIndex; 147 | public byte MagazineIndex; 148 | public byte MeshIndex; 149 | public byte UVIndex; 150 | public ushort CamoIndex; 151 | public byte AttachmentsUVIndex; 152 | public ushort AttachmentsCamoIndex; 153 | public ushort CharmIndex; 154 | public ushort BulletType; 155 | 156 | public Weapon Tool 157 | { 158 | get 159 | { 160 | if (Weapons.TryFind(ToolName, out var weapon)) 161 | return weapon; 162 | return null; 163 | } 164 | set 165 | { 166 | if (value == null) 167 | this.ToolName = "none"; 168 | else 169 | this.ToolName = value.Name; 170 | } 171 | } 172 | public Attachment MainSight 173 | { 174 | get 175 | { 176 | if (Attachments.TryFind(MainSightName, out var attachment)) 177 | return attachment; 178 | return null; 179 | } 180 | set 181 | { 182 | if (value == null) 183 | this.MainSightName = "none"; 184 | else 185 | this.MainSightName = value.Name; 186 | } 187 | } 188 | public Attachment TopSight 189 | { 190 | get 191 | { 192 | if (Attachments.TryFind(TopSightName, out var attachment)) 193 | return attachment; 194 | return null; 195 | } 196 | set 197 | { 198 | if (value == null) 199 | this.TopSightName = "none"; 200 | else 201 | this.TopSightName = value.Name; 202 | } 203 | } 204 | public Attachment CantedSight 205 | { 206 | get 207 | { 208 | if (Attachments.TryFind(CantedSightName, out var attachment)) 209 | return attachment; 210 | return null; 211 | } 212 | set 213 | { 214 | if (value == null) 215 | this.CantedSightName = "none"; 216 | else 217 | this.CantedSightName = value.Name; 218 | } 219 | } 220 | public Attachment Barrel 221 | { 222 | get 223 | { 224 | if (Attachments.TryFind(BarrelName, out var attachment)) 225 | return attachment; 226 | return null; 227 | } 228 | set 229 | { 230 | if (value == null) 231 | this.BarrelName = "none"; 232 | else 233 | this.BarrelName = value.Name; 234 | } 235 | } 236 | public Attachment SideRail 237 | { 238 | get 239 | { 240 | if (Attachments.TryFind(SideRailName, out var attachment)) 241 | return attachment; 242 | return null; 243 | } 244 | set 245 | { 246 | if (value == null) 247 | this.SideRailName = "none"; 248 | else 249 | this.SideRailName = value.Name; 250 | } 251 | } 252 | public Attachment UnderRail 253 | { 254 | get 255 | { 256 | if (Attachments.TryFind(UnderRailName, out var attachment)) 257 | return attachment; 258 | return null; 259 | } 260 | set 261 | { 262 | if (value == null) 263 | this.UnderRailName = "none"; 264 | else 265 | this.UnderRailName = value.Name; 266 | } 267 | } 268 | public Attachment BoltAction 269 | { 270 | get 271 | { 272 | if (Attachments.TryFind(BoltActionName, out var attachment)) 273 | return attachment; 274 | return null; 275 | } 276 | set 277 | { 278 | if (value == null) 279 | this.BoltActionName = "none"; 280 | else 281 | this.BoltActionName = value.Name; 282 | } 283 | } 284 | 285 | public bool HasAttachment(Attachment attachment) 286 | { 287 | switch (attachment.AttachmentType) 288 | { 289 | case AttachmentType.MainSight: 290 | return this.MainSight == attachment; 291 | case AttachmentType.TopSight: 292 | return this.TopSight == attachment; 293 | case AttachmentType.CantedSight: 294 | return this.CantedSight == attachment; 295 | case AttachmentType.Barrel: 296 | return this.Barrel == attachment; 297 | case AttachmentType.UnderRail: 298 | return this.UnderRail == attachment; 299 | case AttachmentType.SideRail: 300 | return this.SideRail == attachment; 301 | case AttachmentType.Bolt: 302 | return this.BoltAction == attachment; 303 | } 304 | return false; 305 | } 306 | public void SetAttachment(Attachment attachment) 307 | { 308 | switch (attachment.AttachmentType) 309 | { 310 | case AttachmentType.MainSight: 311 | this.MainSight = attachment; 312 | break; 313 | case AttachmentType.TopSight: 314 | this.TopSight = attachment; 315 | break; 316 | case AttachmentType.CantedSight: 317 | this.CantedSight = attachment; 318 | break; 319 | case AttachmentType.Barrel: 320 | this.Barrel = attachment; 321 | break; 322 | case AttachmentType.UnderRail: 323 | this.UnderRail = attachment; 324 | break; 325 | case AttachmentType.SideRail: 326 | this.SideRail = attachment; 327 | break; 328 | case AttachmentType.Bolt: 329 | this.BoltAction = attachment; 330 | break; 331 | } 332 | } 333 | 334 | public void Write(Common.Serialization.Stream ser) 335 | { 336 | ser.WriteStringItem(this.ToolName); 337 | 338 | ser.WriteStringItem(this.MainSightName); 339 | ser.Write(this.MainSightIndex); 340 | 341 | ser.WriteStringItem(this.TopSightName); 342 | ser.Write(this.TopSightIndex); 343 | 344 | ser.WriteStringItem(this.CantedSightName); 345 | ser.Write(this.MainCantedIndex); 346 | 347 | ser.WriteStringItem(this.BarrelName); 348 | ser.Write(MainBarrelIndex); 349 | 350 | ser.WriteStringItem(this.SideRailName); 351 | ser.Write(MainSideRailIndex); 352 | 353 | ser.WriteStringItem(this.UnderRailName); 354 | ser.Write(MainUnderRailIndex); 355 | 356 | ser.WriteStringItem(this.BoltActionName); 357 | ser.Write(MainBoltActionIndex); 358 | 359 | ser.Write(MagazineIndex); 360 | ser.Write(MeshIndex); 361 | 362 | ser.Write(UVIndex); 363 | ser.Write(CamoIndex); 364 | ser.Write(AttachmentsUVIndex); 365 | ser.Write(AttachmentsCamoIndex); 366 | ser.Write(CharmIndex); 367 | ser.Write(BulletType); 368 | } 369 | public void Read(Common.Serialization.Stream ser) 370 | { 371 | ser.TryReadString(out this.ToolName); 372 | 373 | ser.TryReadString(out this.MainSightName); 374 | MainSightIndex = ser.ReadInt8(); 375 | 376 | ser.TryReadString(out this.TopSightName); 377 | TopSightIndex = ser.ReadInt8(); 378 | 379 | ser.TryReadString(out this.CantedSightName); 380 | MainCantedIndex = ser.ReadInt8(); 381 | 382 | ser.TryReadString(out this.BarrelName); 383 | MainBarrelIndex = ser.ReadInt8(); 384 | 385 | ser.TryReadString(out this.SideRailName); 386 | MainSideRailIndex = ser.ReadInt8(); 387 | 388 | ser.TryReadString(out this.UnderRailName); 389 | MainUnderRailIndex = ser.ReadInt8(); 390 | 391 | ser.TryReadString(out this.BoltActionName); 392 | MainBoltActionIndex = ser.ReadInt8(); 393 | 394 | MagazineIndex = ser.ReadInt8(); 395 | MeshIndex = ser.ReadInt8(); 396 | UVIndex = ser.ReadInt8(); 397 | CamoIndex = ser.ReadUInt16(); 398 | AttachmentsUVIndex = ser.ReadInt8(); 399 | AttachmentsCamoIndex = ser.ReadUInt16(); 400 | CharmIndex = ser.ReadUInt16(); 401 | BulletType = ser.ReadUInt16(); 402 | } 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/PlayerStats.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public class PlayerStats 4 | { 5 | public PlayerStats() { } 6 | public PlayerStats(byte[] data) { Load(data); } 7 | 8 | public bool IsBanned; 9 | public Roles Roles; 10 | public PlayerProgess Progress = new PlayerProgess(); 11 | public byte[] ToolProgress; 12 | public byte[] Achievements; 13 | public byte[] Selections; 14 | 15 | public void Write(Common.Serialization.Stream ser) 16 | { 17 | ser.Write(this.IsBanned); 18 | ser.Write((ulong)this.Roles); 19 | 20 | Progress.Write(ser); 21 | 22 | if (ToolProgress != null) 23 | { 24 | ser.Write((ushort)ToolProgress.Length); 25 | ser.Write(ToolProgress, 0, ToolProgress.Length); 26 | } 27 | else 28 | { 29 | ser.Write((ushort)0); 30 | } 31 | 32 | if (Achievements != null) 33 | { 34 | ser.Write((ushort)Achievements.Length); 35 | ser.Write(Achievements, 0, Achievements.Length); 36 | } 37 | else 38 | { 39 | ser.Write((ushort)0); 40 | } 41 | 42 | if (Selections != null) 43 | { 44 | ser.Write((ushort)Selections.Length); 45 | ser.Write(Selections, 0, Selections.Length); 46 | } 47 | else 48 | { 49 | ser.Write((ushort)0); 50 | } 51 | } 52 | public void Read(Common.Serialization.Stream ser) 53 | { 54 | this.IsBanned = ser.ReadBool(); 55 | this.Roles = (Roles)ser.ReadUInt64(); 56 | 57 | this.Progress.Read(ser); 58 | 59 | int size = ser.ReadInt16(); 60 | this.ToolProgress = ser.ReadByteArray(size); 61 | 62 | size = ser.ReadInt16(); 63 | this.Achievements = ser.ReadByteArray(size); 64 | 65 | size = ser.ReadInt16(); 66 | this.Selections = ser.ReadByteArray(size); 67 | } 68 | 69 | public byte[] SerializeToByteArray() 70 | { 71 | using (var ser = Common.Serialization.Stream.Get()) 72 | { 73 | Write(ser); 74 | return ser.AsByteArrayData(); 75 | } 76 | } 77 | public void Load(byte[] data) 78 | { 79 | var ser = new Common.Serialization.Stream() 80 | { 81 | Buffer = data, 82 | InPool = false, 83 | ReadPosition = 0, 84 | WritePosition = data.Length, 85 | }; 86 | Read(ser); 87 | } 88 | 89 | public class PlayerProgess 90 | { 91 | private const uint ParamCount = 42; 92 | 93 | public uint KillCount; 94 | public uint LeaderKills; 95 | public uint AssaultKills; 96 | public uint MedicKills; 97 | public uint EngineerKills; 98 | public uint SupportKills; 99 | public uint ReconKills; 100 | public uint DeathCount; 101 | public uint WinCount; 102 | public uint LoseCount; 103 | public uint FriendlyShots; 104 | public uint FriendlyKills; 105 | public uint Revived; 106 | public uint RevivedTeamMates; 107 | public uint Assists; 108 | public uint Prestige; 109 | public uint Rank; 110 | public uint EXP; 111 | public uint ShotsFired; 112 | public uint ShotsHit; 113 | public uint Headshots; 114 | public uint ObjectivesComplated; 115 | public uint HealedHPs; 116 | public uint RoadKills; 117 | public uint Suicides; 118 | public uint VehiclesDestroyed; 119 | public uint VehicleHPRepaired; 120 | public uint LongestKill; 121 | public uint PlayTimeSeconds; 122 | public uint LeaderPlayTime; 123 | public uint AssaultPlayTime; 124 | public uint MedicPlayTime; 125 | public uint EngineerPlayTime; 126 | public uint SupportPlayTime; 127 | public uint ReconPlayTime; 128 | public uint LeaderScore; 129 | public uint AssaultScore; 130 | public uint MedicScore; 131 | public uint EngineerScore; 132 | public uint SupportScore; 133 | public uint ReconScore; 134 | public uint TotalScore; 135 | 136 | public void Write(Common.Serialization.Stream ser) 137 | { 138 | ser.Write(ParamCount); 139 | { 140 | ser.Write(KillCount); 141 | ser.Write(LeaderKills); 142 | ser.Write(AssaultKills); 143 | ser.Write(MedicKills); 144 | ser.Write(EngineerKills); 145 | ser.Write(SupportKills); 146 | ser.Write(ReconKills); 147 | ser.Write(DeathCount); 148 | ser.Write(WinCount); 149 | ser.Write(LoseCount); 150 | ser.Write(FriendlyShots); 151 | ser.Write(FriendlyKills); 152 | ser.Write(Revived); 153 | ser.Write(RevivedTeamMates); 154 | ser.Write(Assists); 155 | ser.Write(Prestige); 156 | ser.Write(Rank); 157 | ser.Write(EXP); 158 | ser.Write(ShotsFired); 159 | ser.Write(ShotsHit); 160 | ser.Write(Headshots); 161 | ser.Write(ObjectivesComplated); 162 | ser.Write(HealedHPs); 163 | ser.Write(RoadKills); 164 | ser.Write(Suicides); 165 | ser.Write(VehiclesDestroyed); 166 | ser.Write(VehicleHPRepaired); 167 | ser.Write(LongestKill); 168 | ser.Write(PlayTimeSeconds); 169 | ser.Write(LeaderPlayTime); 170 | ser.Write(AssaultPlayTime); 171 | ser.Write(MedicPlayTime); 172 | ser.Write(EngineerPlayTime); 173 | ser.Write(SupportPlayTime); 174 | ser.Write(ReconPlayTime); 175 | ser.Write(LeaderScore); 176 | ser.Write(AssaultScore); 177 | ser.Write(MedicScore); 178 | ser.Write(EngineerScore); 179 | ser.Write(SupportScore); 180 | ser.Write(ReconScore); 181 | ser.Write(TotalScore); 182 | } 183 | } 184 | public void Read(Common.Serialization.Stream ser) 185 | { 186 | Reset(); 187 | 188 | uint mParamCount = ser.ReadUInt32(); 189 | int maxReadPosition = ser.ReadPosition + (int)(mParamCount * 4); 190 | { 191 | bool canRead() => ser.ReadPosition < maxReadPosition; 192 | if (canRead()) 193 | this.KillCount = ser.ReadUInt32(); 194 | if (canRead()) 195 | this.LeaderKills = ser.ReadUInt32(); 196 | if (canRead()) 197 | this.AssaultKills = ser.ReadUInt32(); 198 | if (canRead()) 199 | this.MedicKills = ser.ReadUInt32(); 200 | if (canRead()) 201 | this.EngineerKills = ser.ReadUInt32(); 202 | if (canRead()) 203 | this.SupportKills = ser.ReadUInt32(); 204 | if (canRead()) 205 | this.ReconKills = ser.ReadUInt32(); 206 | if (canRead()) 207 | this.DeathCount = ser.ReadUInt32(); 208 | if (canRead()) 209 | this.WinCount = ser.ReadUInt32(); 210 | if (canRead()) 211 | this.LoseCount = ser.ReadUInt32(); 212 | if (canRead()) 213 | this.FriendlyShots = ser.ReadUInt32(); 214 | if (canRead()) 215 | this.FriendlyKills = ser.ReadUInt32(); 216 | if (canRead()) 217 | this.Revived = ser.ReadUInt32(); 218 | if (canRead()) 219 | this.RevivedTeamMates = ser.ReadUInt32(); 220 | if (canRead()) 221 | this.Assists = ser.ReadUInt32(); 222 | if (canRead()) 223 | this.Prestige = ser.ReadUInt32(); 224 | if (canRead()) 225 | this.Rank = ser.ReadUInt32(); 226 | if (canRead()) 227 | this.EXP = ser.ReadUInt32(); 228 | if (canRead()) 229 | this.ShotsFired = ser.ReadUInt32(); 230 | if (canRead()) 231 | this.ShotsHit = ser.ReadUInt32(); 232 | if (canRead()) 233 | this.Headshots = ser.ReadUInt32(); 234 | if (canRead()) 235 | this.ObjectivesComplated = ser.ReadUInt32(); 236 | if (canRead()) 237 | this.HealedHPs = ser.ReadUInt32(); 238 | if (canRead()) 239 | this.RoadKills = ser.ReadUInt32(); 240 | if (canRead()) 241 | this.Suicides = ser.ReadUInt32(); 242 | if (canRead()) 243 | this.VehiclesDestroyed = ser.ReadUInt32(); 244 | if (canRead()) 245 | this.VehicleHPRepaired = ser.ReadUInt32(); 246 | if (canRead()) 247 | this.LongestKill = ser.ReadUInt32(); 248 | if (canRead()) 249 | this.PlayTimeSeconds = ser.ReadUInt32(); 250 | if (canRead()) 251 | this.LeaderPlayTime = ser.ReadUInt32(); 252 | if (canRead()) 253 | this.AssaultPlayTime = ser.ReadUInt32(); 254 | if (canRead()) 255 | this.MedicPlayTime = ser.ReadUInt32(); 256 | if (canRead()) 257 | this.EngineerPlayTime = ser.ReadUInt32(); 258 | if (canRead()) 259 | this.SupportPlayTime = ser.ReadUInt32(); 260 | if (canRead()) 261 | this.ReconPlayTime = ser.ReadUInt32(); 262 | if (canRead()) 263 | this.LeaderScore = ser.ReadUInt32(); 264 | if (canRead()) 265 | this.AssaultScore = ser.ReadUInt32(); 266 | if (canRead()) 267 | this.MedicScore = ser.ReadUInt32(); 268 | if (canRead()) 269 | this.EngineerScore = ser.ReadUInt32(); 270 | if (canRead()) 271 | this.SupportScore = ser.ReadUInt32(); 272 | if (canRead()) 273 | this.ReconScore = ser.ReadUInt32(); 274 | if (canRead()) 275 | this.TotalScore = ser.ReadUInt32(); 276 | } 277 | ser.ReadPosition = maxReadPosition; 278 | } 279 | public void Reset() 280 | { 281 | KillCount = 0; 282 | LeaderKills = 0; 283 | AssaultKills = 0; 284 | MedicKills = 0; 285 | EngineerKills = 0; 286 | SupportKills = 0; 287 | ReconKills = 0; 288 | DeathCount = 0; 289 | WinCount = 0; 290 | LoseCount = 0; 291 | FriendlyShots = 0; 292 | FriendlyKills = 0; 293 | Revived = 0; 294 | RevivedTeamMates = 0; 295 | Assists = 0; 296 | Prestige = 0; 297 | Rank = 0; 298 | EXP = 0; 299 | ShotsFired = 0; 300 | ShotsHit = 0; 301 | Headshots = 0; 302 | ObjectivesComplated = 0; 303 | HealedHPs = 0; 304 | RoadKills = 0; 305 | Suicides = 0; 306 | VehiclesDestroyed = 0; 307 | VehicleHPRepaired = 0; 308 | LongestKill = 0; 309 | PlayTimeSeconds = 0; 310 | LeaderPlayTime = 0; 311 | AssaultPlayTime = 0; 312 | MedicPlayTime = 0; 313 | EngineerPlayTime = 0; 314 | SupportPlayTime = 0; 315 | ReconPlayTime = 0; 316 | LeaderScore = 0; 317 | AssaultScore = 0; 318 | MedicScore = 0; 319 | EngineerScore = 0; 320 | SupportScore = 0; 321 | ReconScore = 0; 322 | TotalScore = 0; 323 | } 324 | } 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/PlayerWearings.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public struct PlayerWearings 4 | { 5 | public string Head; 6 | public string Chest; 7 | public string Belt; 8 | public string Backbag; 9 | public string Eye; 10 | public string Face; 11 | public string Hair; 12 | public string Skin; 13 | public string Uniform; 14 | public string Camo; 15 | 16 | public void Write(Common.Serialization.Stream ser) 17 | { 18 | ser.WriteStringItem(this.Head); 19 | ser.WriteStringItem(this.Chest); 20 | ser.WriteStringItem(this.Belt); 21 | ser.WriteStringItem(this.Backbag); 22 | ser.WriteStringItem(this.Eye); 23 | ser.WriteStringItem(this.Face); 24 | ser.WriteStringItem(this.Hair); 25 | ser.WriteStringItem(this.Skin); 26 | ser.WriteStringItem(this.Uniform); 27 | ser.WriteStringItem(this.Camo); 28 | } 29 | public void Read(Common.Serialization.Stream ser) 30 | { 31 | ser.TryReadString(out this.Head); 32 | ser.TryReadString(out this.Chest); 33 | ser.TryReadString(out this.Belt); 34 | ser.TryReadString(out this.Backbag); 35 | ser.TryReadString(out this.Eye); 36 | ser.TryReadString(out this.Face); 37 | ser.TryReadString(out this.Hair); 38 | ser.TryReadString(out this.Skin); 39 | ser.TryReadString(out this.Uniform); 40 | ser.TryReadString(out this.Camo); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/VoxelBlockData.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public struct VoxelBlockData 4 | { 5 | public VoxelTextures TextureID; 6 | 7 | public void Write(BattleBitAPI.Common.Serialization.Stream ser) 8 | { 9 | ser.Write((byte)TextureID); 10 | } 11 | public void Read(BattleBitAPI.Common.Serialization.Stream ser) 12 | { 13 | this.TextureID = (VoxelTextures)ser.ReadInt8(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Data/Weapon.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BattleBitAPI.Common 4 | { 5 | public class Weapon : IEquatable, IEquatable 6 | { 7 | public string Name { get; private set; } 8 | public WeaponType WeaponType { get; private set; } 9 | public Weapon(string name, WeaponType weaponType) 10 | { 11 | Name = name; 12 | WeaponType = weaponType; 13 | } 14 | 15 | public override string ToString() 16 | { 17 | return this.Name; 18 | } 19 | public bool Equals(string other) 20 | { 21 | if (other == null) 22 | return false; 23 | return this.Name.Equals(other); 24 | } 25 | public bool Equals(Weapon other) 26 | { 27 | if (other == null) 28 | return false; 29 | return this.Name.Equals(other.Name); 30 | } 31 | 32 | public static bool operator ==(string left, Weapon right) 33 | { 34 | bool leftNull = object.ReferenceEquals(left, null); 35 | bool rightNull = object.ReferenceEquals(right, null); 36 | if (leftNull && rightNull) 37 | return true; 38 | if (leftNull || rightNull) 39 | return false; 40 | return right.Name.Equals(left); 41 | } 42 | public static bool operator !=(string left, Weapon right) 43 | { 44 | bool leftNull = object.ReferenceEquals(left, null); 45 | bool rightNull = object.ReferenceEquals(right, null); 46 | if (leftNull && rightNull) 47 | return true; 48 | if (leftNull || rightNull) 49 | return false; 50 | return right.Name.Equals(left); 51 | } 52 | public static bool operator ==(Weapon right, string left) 53 | { 54 | bool leftNull = object.ReferenceEquals(left, null); 55 | bool rightNull = object.ReferenceEquals(right, null); 56 | if (leftNull && rightNull) 57 | return true; 58 | if (leftNull || rightNull) 59 | return false; 60 | return right.Name.Equals(left); 61 | } 62 | public static bool operator !=(Weapon right, string left) 63 | { 64 | bool leftNull = object.ReferenceEquals(left, null); 65 | bool rightNull = object.ReferenceEquals(right, null); 66 | if (leftNull && rightNull) 67 | return true; 68 | if (leftNull || rightNull) 69 | return false; 70 | return right.Name.Equals(left); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /BattleBitAPI/Common/Datasets/Attachments.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace BattleBitAPI.Common 4 | { 5 | public static class Attachments 6 | { 7 | // ----- Private Variables ----- 8 | private static Dictionary mAttachments; 9 | 10 | // ----- Barrels ----- 11 | public static readonly Attachment Basic = new Attachment("Basic", AttachmentType.Barrel); 12 | public static readonly Attachment Compensator = new Attachment("Compensator", AttachmentType.Barrel); 13 | public static readonly Attachment Heavy = new Attachment("Heavy", AttachmentType.Barrel); 14 | public static readonly Attachment LongBarrel = new Attachment("Long_Barrel", AttachmentType.Barrel); 15 | public static readonly Attachment MuzzleBreak = new Attachment("Muzzle_Break", AttachmentType.Barrel); 16 | public static readonly Attachment Ranger = new Attachment("Ranger", AttachmentType.Barrel); 17 | public static readonly Attachment SuppressorLong = new Attachment("Suppressor_Long", AttachmentType.Barrel); 18 | public static readonly Attachment SuppressorShort = new Attachment("Suppressor_Short", AttachmentType.Barrel); 19 | public static readonly Attachment Tactical = new Attachment("Tactical", AttachmentType.Barrel); 20 | public static readonly Attachment FlashHider = new Attachment("Flash_Hider", AttachmentType.Barrel); 21 | public static readonly Attachment Osprey9 = new Attachment("Osprey_9", AttachmentType.Barrel); 22 | public static readonly Attachment DGN308 = new Attachment("DGN-308", AttachmentType.Barrel); 23 | public static readonly Attachment VAMB762 = new Attachment("VAMB-762", AttachmentType.Barrel); 24 | public static readonly Attachment SDN6762 = new Attachment("SDN-6_762", AttachmentType.Barrel); 25 | public static readonly Attachment NT4556 = new Attachment("NT-4_556", AttachmentType.Barrel); 26 | 27 | // ----- Canted Sights ----- 28 | public static readonly Attachment Ironsight = new Attachment("Ironsight", AttachmentType.CantedSight); 29 | public static readonly Attachment CantedRedDot = new Attachment("Canted_Red_Dot", AttachmentType.CantedSight); 30 | public static readonly Attachment FYouCanted = new Attachment("FYou_Canted", AttachmentType.CantedSight); 31 | public static readonly Attachment HoloDot = new Attachment("Holo_Dot", AttachmentType.CantedSight); 32 | 33 | // ----- Scope ----- 34 | public static readonly Attachment _6xScope = new Attachment("6x_Scope", AttachmentType.MainSight); 35 | public static readonly Attachment _8xScope = new Attachment("8x_Scope", AttachmentType.MainSight); 36 | public static readonly Attachment _15xScope = new Attachment("15x_Scope", AttachmentType.MainSight); 37 | public static readonly Attachment _20xScope = new Attachment("20x_Scope", AttachmentType.MainSight); 38 | public static readonly Attachment PTR40Hunter = new Attachment("PTR-40_Hunter", AttachmentType.MainSight); 39 | public static readonly Attachment _1P78 = new Attachment("1P78", AttachmentType.MainSight); 40 | public static readonly Attachment Acog = new Attachment("Acog", AttachmentType.MainSight); 41 | public static readonly Attachment M125 = new Attachment("M_125", AttachmentType.MainSight); 42 | public static readonly Attachment Prisma = new Attachment("Prisma", AttachmentType.MainSight); 43 | public static readonly Attachment Slip = new Attachment("Slip", AttachmentType.MainSight); 44 | public static readonly Attachment PistolDeltaSight = new Attachment("Pistol_Delta_Sight", AttachmentType.MainSight); 45 | public static readonly Attachment PistolRedDot = new Attachment("Pistol_Red_Dot", AttachmentType.MainSight); 46 | public static readonly Attachment AimComp = new Attachment("Aim_Comp", AttachmentType.MainSight); 47 | public static readonly Attachment Holographic = new Attachment("Holographic", AttachmentType.MainSight); 48 | public static readonly Attachment Kobra = new Attachment("Kobra", AttachmentType.MainSight); 49 | public static readonly Attachment OKP7 = new Attachment("OKP7", AttachmentType.MainSight); 50 | public static readonly Attachment PKAS = new Attachment("PK-AS", AttachmentType.MainSight); 51 | public static readonly Attachment RedDot = new Attachment("Red_Dot", AttachmentType.MainSight); 52 | public static readonly Attachment Reflex = new Attachment("Reflex", AttachmentType.MainSight); 53 | public static readonly Attachment Strikefire = new Attachment("Strikefire", AttachmentType.MainSight); 54 | public static readonly Attachment Razor = new Attachment("Razor", AttachmentType.MainSight); 55 | public static readonly Attachment Flir = new Attachment("Flir", AttachmentType.MainSight); 56 | public static readonly Attachment Echo = new Attachment("Echo", AttachmentType.MainSight); 57 | public static readonly Attachment TRI4X32 = new Attachment("TRI4X32", AttachmentType.MainSight); 58 | public static readonly Attachment FYouSight = new Attachment("FYou_Sight", AttachmentType.MainSight); 59 | public static readonly Attachment HoloPK120 = new Attachment("Holo_PK-120", AttachmentType.MainSight); 60 | public static readonly Attachment Pistol8xScope = new Attachment("Pistol_8x_Scope", AttachmentType.MainSight); 61 | public static readonly Attachment BurrisAR332 = new Attachment("BurrisAR332", AttachmentType.MainSight); 62 | public static readonly Attachment HS401G5 = new Attachment("HS401G5", AttachmentType.MainSight); 63 | 64 | // ----- Top Scope ----- 65 | public static readonly Attachment DeltaSightTop = new Attachment("Delta_Sight_Top", AttachmentType.TopSight); 66 | public static readonly Attachment RedDotTop = new Attachment("Red_Dot_Top", AttachmentType.TopSight); 67 | public static readonly Attachment CRedDotTop = new Attachment("C_Red_Dot_Top", AttachmentType.TopSight); 68 | public static readonly Attachment FYouTop = new Attachment("FYou_Top", AttachmentType.TopSight); 69 | 70 | // ----- Under Rails ----- 71 | public static readonly Attachment AngledGrip = new Attachment("Angled_Grip", AttachmentType.UnderRail); 72 | public static readonly Attachment Bipod = new Attachment("Bipod", AttachmentType.UnderRail); 73 | public static readonly Attachment VerticalGrip = new Attachment("Vertical_Grip", AttachmentType.UnderRail); 74 | public static readonly Attachment StubbyGrip = new Attachment("Stubby_Grip", AttachmentType.UnderRail); 75 | public static readonly Attachment StabilGrip = new Attachment("Stabil_Grip", AttachmentType.UnderRail); 76 | public static readonly Attachment VerticalSkeletonGrip = new Attachment("Vertical_Skeleton_Grip", AttachmentType.UnderRail); 77 | public static readonly Attachment FABDTFG = new Attachment("FAB-DTFG", AttachmentType.UnderRail); 78 | public static readonly Attachment MagpulAngled = new Attachment("Magpul_Angled", AttachmentType.UnderRail); 79 | public static readonly Attachment BCMGunFighter = new Attachment("BCM-Gun_Fighter", AttachmentType.UnderRail); 80 | public static readonly Attachment ShiftShortAngledGrip = new Attachment("Shift_Short_Angled_Grip", AttachmentType.UnderRail); 81 | public static readonly Attachment SE5Grip = new Attachment("SE-5_Grip", AttachmentType.UnderRail); 82 | public static readonly Attachment RK6Foregrip = new Attachment("RK-6_Foregrip", AttachmentType.UnderRail); 83 | public static readonly Attachment HeraCQRFront = new Attachment("HeraCQR_Front", AttachmentType.UnderRail); 84 | public static readonly Attachment B25URK = new Attachment("B-25URK", AttachmentType.UnderRail); 85 | public static readonly Attachment VTACUVGTacticalGrip = new Attachment("VTAC_UVG_TacticalGrip", AttachmentType.UnderRail); 86 | 87 | // ----- Side Rails ----- 88 | public static readonly Attachment Flashlight = new Attachment("Flashlight", AttachmentType.SideRail); 89 | public static readonly Attachment Rangefinder = new Attachment("Rangefinder", AttachmentType.SideRail); 90 | public static readonly Attachment Redlaser = new Attachment("Redlaser", AttachmentType.SideRail); 91 | public static readonly Attachment TacticalFlashlight = new Attachment("Tactical_Flashlight", AttachmentType.SideRail); 92 | public static readonly Attachment Greenlaser = new Attachment("Greenlaser", AttachmentType.SideRail); 93 | public static readonly Attachment Searchlight = new Attachment("Searchlight", AttachmentType.SideRail); 94 | 95 | // ----- Bolts ----- 96 | public static readonly Attachment BoltActionA = new Attachment("Bolt_Action_A", AttachmentType.Bolt); 97 | public static readonly Attachment BoltActionB = new Attachment("Bolt_Action_B", AttachmentType.Bolt); 98 | public static readonly Attachment BoltActionC = new Attachment("Bolt_Action_C", AttachmentType.Bolt); 99 | public static readonly Attachment BoltActionD = new Attachment("Bolt_Action_D", AttachmentType.Bolt); 100 | public static readonly Attachment BoltActionE = new Attachment("Bolt_Action_E", AttachmentType.Bolt); 101 | 102 | // ----- Public Calls ----- 103 | public static bool TryFind(string name, out Attachment item) 104 | { 105 | return mAttachments.TryGetValue(name, out item); 106 | } 107 | 108 | // ----- Init ----- 109 | static Attachments() 110 | { 111 | var members = typeof(Attachments).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); 112 | mAttachments = new Dictionary(members.Length); 113 | foreach (var memberInfo in members) 114 | { 115 | if (memberInfo.MemberType == System.Reflection.MemberTypes.Field) 116 | { 117 | var field = ((FieldInfo)memberInfo); 118 | if (field.FieldType == typeof(Attachment)) 119 | { 120 | var att = (Attachment)field.GetValue(null); 121 | mAttachments.Add(att.Name, att); 122 | } 123 | } 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Datasets/Weapons.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualBasic; 2 | using System.Reflection; 3 | 4 | namespace BattleBitAPI.Common 5 | { 6 | public static class Weapons 7 | { 8 | // ----- Private Variables ----- 9 | private static Dictionary mWeapons; 10 | 11 | // ----- Public Variables ----- 12 | public readonly static Weapon ACR = new Weapon("ACR", WeaponType.Rifle); 13 | public readonly static Weapon AK15 = new Weapon("AK15", WeaponType.Rifle); 14 | public readonly static Weapon AK74 = new Weapon("AK74", WeaponType.Rifle); 15 | public readonly static Weapon G36C = new Weapon("G36C", WeaponType.Rifle); 16 | public readonly static Weapon HoneyBadger = new Weapon("Honey Badger", WeaponType.PersonalDefenseWeapon_PDW); 17 | public readonly static Weapon KrissVector = new Weapon("Kriss Vector", WeaponType.SubmachineGun_SMG); 18 | public readonly static Weapon L86A1 = new Weapon("L86A1", WeaponType.LightSupportGun_LSG); 19 | public readonly static Weapon L96 = new Weapon("L96", WeaponType.SniperRifle); 20 | public readonly static Weapon M4A1 = new Weapon("M4A1", WeaponType.Rifle); 21 | public readonly static Weapon M9 = new Weapon("M9", WeaponType.Pistol); 22 | public readonly static Weapon M110 = new Weapon("M110", WeaponType.DMR); 23 | public readonly static Weapon M249 = new Weapon("M249", WeaponType.LightMachineGun_LMG); 24 | public readonly static Weapon MK14EBR = new Weapon("MK14 EBR", WeaponType.DMR); 25 | public readonly static Weapon MK20 = new Weapon("MK20", WeaponType.DMR); 26 | public readonly static Weapon MP7 = new Weapon("MP7", WeaponType.SubmachineGun_SMG); 27 | public readonly static Weapon PP2000 = new Weapon("PP2000", WeaponType.SubmachineGun_SMG); 28 | public readonly static Weapon SCARH = new Weapon("SCAR-H", WeaponType.Rifle); 29 | public readonly static Weapon SSG69 = new Weapon("SSG 69", WeaponType.SniperRifle); 30 | public readonly static Weapon SV98 = new Weapon("SV-98", WeaponType.SniperRifle); 31 | public readonly static Weapon UMP45 = new Weapon("UMP-45", WeaponType.SubmachineGun_SMG); 32 | public readonly static Weapon Unica = new Weapon("Unica", WeaponType.HeavyPistol); 33 | public readonly static Weapon USP = new Weapon("USP", WeaponType.Pistol); 34 | public readonly static Weapon AsVal = new Weapon("As Val", WeaponType.Carbine); 35 | public readonly static Weapon AUGA3 = new Weapon("AUG A3", WeaponType.Rifle); 36 | public readonly static Weapon DesertEagle = new Weapon("Desert Eagle", WeaponType.HeavyPistol); 37 | public readonly static Weapon FAL = new Weapon("FAL", WeaponType.Rifle); 38 | public readonly static Weapon Glock18 = new Weapon("Glock 18", WeaponType.AutoPistol); 39 | public readonly static Weapon M200 = new Weapon("M200", WeaponType.SniperRifle); 40 | public readonly static Weapon MP443 = new Weapon("MP 443", WeaponType.Pistol); 41 | public readonly static Weapon FAMAS = new Weapon("FAMAS", WeaponType.Rifle); 42 | public readonly static Weapon MP5 = new Weapon("MP5", WeaponType.SubmachineGun_SMG); 43 | public readonly static Weapon P90 = new Weapon("P90", WeaponType.PersonalDefenseWeapon_PDW); 44 | public readonly static Weapon MSR = new Weapon("MSR", WeaponType.SniperRifle); 45 | public readonly static Weapon PP19 = new Weapon("PP19", WeaponType.SubmachineGun_SMG); 46 | public readonly static Weapon SVD = new Weapon("SVD", WeaponType.DMR); 47 | public readonly static Weapon Rem700 = new Weapon("Rem700", WeaponType.SniperRifle); 48 | public readonly static Weapon SG550 = new Weapon("SG550", WeaponType.Rifle); 49 | public readonly static Weapon Groza = new Weapon("Groza", WeaponType.PersonalDefenseWeapon_PDW); 50 | public readonly static Weapon HK419 = new Weapon("HK419", WeaponType.Rifle); 51 | public readonly static Weapon ScorpionEVO = new Weapon("ScorpionEVO", WeaponType.Carbine); 52 | public readonly static Weapon Rsh12 = new Weapon("Rsh12", WeaponType.HeavyPistol); 53 | public readonly static Weapon MG36 = new Weapon("MG36", WeaponType.LightSupportGun_LSG); 54 | public readonly static Weapon AK5C = new Weapon("AK5C", WeaponType.Rifle); 55 | public readonly static Weapon Ultimax100 = new Weapon("Ultimax100", WeaponType.LightMachineGun_LMG); 56 | 57 | // ----- Public Calls ----- 58 | public static bool TryFind(string name, out Weapon item) 59 | { 60 | return mWeapons.TryGetValue(name, out item); 61 | } 62 | 63 | // ----- Init ----- 64 | static Weapons() 65 | { 66 | var members = typeof(Weapons).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); 67 | mWeapons = new Dictionary(members.Length); 68 | foreach (var memberInfo in members) 69 | { 70 | if (memberInfo.MemberType == System.Reflection.MemberTypes.Field) 71 | { 72 | var field = ((FieldInfo)memberInfo); 73 | if (field.FieldType == typeof(Weapon)) 74 | { 75 | var wep = (Weapon)field.GetValue(null); 76 | mWeapons.Add(wep.Name, wep); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/AttachmentType.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum AttachmentType 4 | { 5 | MainSight, 6 | TopSight, 7 | CantedSight, 8 | Barrel, 9 | UnderRail, 10 | SideRail, 11 | Bolt, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/ChatChannel.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum ChatChannel 4 | { 5 | AllChat, 6 | TeamChat, 7 | SquadChat 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/DamageReason.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace BattleBitAPI.Common 8 | { 9 | public enum ReasonOfDamage : byte 10 | { 11 | Server = 0, 12 | Weapon = 1, 13 | Bleeding = 2, 14 | Fall = 3, 15 | HelicopterBlade = 4, 16 | VehicleExplosion = 5, 17 | Explosion = 6, 18 | vehicleRunOver = 7, 19 | BuildingCollapsing = 8, 20 | SledgeHammer = 9, 21 | TreeFall = 10, 22 | CountAsKill = 11, 23 | Suicide = 12, 24 | HelicopterCrash = 13, 25 | BarbedWire = 14, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/GameRole.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum GameRole 4 | { 5 | Assault = 0, Medic = 1, Support = 2, Engineer = 3, Recon = 4, Leader = 5 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/GameState.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum GameState : byte 4 | { 5 | WaitingForPlayers = 0, 6 | CountingDown = 1, 7 | Playing = 2, 8 | EndingGame = 3 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/LeaningSide.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum LeaningSide 4 | { 5 | Left, None, Right 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/LoadoutIndex.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum LoadoutIndex : byte 4 | { 5 | Primary = 0, 6 | Secondary = 1, 7 | FirstAid = 2, 8 | LightGadget = 3, 9 | HeavyGadget = 4, 10 | Throwable = 5, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/LogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | [System.Flags] 4 | public enum LogLevel : ulong 5 | { 6 | None = 0, 7 | 8 | /// 9 | /// Output logs from low level sockets. 10 | /// 11 | Sockets = 1 << 0, 12 | 13 | /// 14 | /// Output logs from remote game server (Highly recommended) 15 | /// 16 | GameServerErrors = 1 << 1, 17 | 18 | /// 19 | /// Output logs of game server connects, reconnects. 20 | /// 21 | GameServers = 1 << 2, 22 | 23 | /// 24 | /// Output logs of player connects, disconnects 25 | /// 26 | Players = 1 << 3, 27 | 28 | /// 29 | /// Output logs of squad changes (someone joining, leaving etc) 30 | /// 31 | Squads = 1 << 4, 32 | 33 | /// 34 | /// Output logs of kills/giveups/revives. 35 | /// 36 | KillsAndSpawns = 1 << 5, 37 | 38 | /// 39 | /// Output logs of role changes (player changing role to medic, support etc). 40 | /// 41 | Roles = 1 << 6, 42 | 43 | /// 44 | /// Output logs player's healt changes. (When received damage or healed) 45 | /// 46 | HealtChanges = 1 << 7, 47 | 48 | /// 49 | /// Output everything. 50 | /// 51 | All = ulong.MaxValue, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/MapDayNight.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum MapDayNight : byte 4 | { 5 | Day = 0, 6 | Night = 1, 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/MapSize.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum MapSize : byte 4 | { 5 | None = 0, 6 | _8v8=8, 7 | _16vs16 = 16, 8 | _32vs32 = 32, 9 | _64vs64 = 64, 10 | _127vs127 = 90, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/PlayerBody.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum PlayerBody : byte 4 | { 5 | None = 0, 6 | Head = 2, 7 | Neck = 3, 8 | Shoulder = 4, 9 | Arm = 5, 10 | Leg = 6, 11 | Foot = 7, 12 | Chest = 10, 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/PlayerSpawningPoint.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum PlayerSpawningPosition : byte 4 | { 5 | SpawnAtPoint, SpawnAtRally, SpawnAtFriend, SpawnAtVehicle, Null 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/PlayerStand.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum PlayerStand : byte 4 | { 5 | Standing = 0, Crouching = 1, Proning = 2 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/ReportReason.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum ReportReason 4 | { 5 | Cheating_WallHack = 0, 6 | Cheating_Aimbot = 1, 7 | Cheating_Speedhack = 2, 8 | 9 | Racism_Discrimination_Text = 3, 10 | Racism_Discrimination_Voice = 4, 11 | 12 | Spamming_Text = 5, 13 | Spamming_Voice = 6, 14 | 15 | Bad_Language_Text = 7, 16 | Bad_Language_Voice = 8, 17 | 18 | Griefing = 9, 19 | Exploiting = 10, 20 | OtherToxicBehaviour = 11, 21 | UserProfileNamePicture = 12, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/Roles.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum Roles : ulong 4 | { 5 | None = 0, 6 | 7 | Admin = 1 << 0, 8 | Moderator = 1 << 1, 9 | Special = 1 << 2, 10 | Vip = 1 << 3, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/SpawningRule.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | [System.Flags] 4 | public enum SpawningRule : ulong 5 | { 6 | None = 0, 7 | 8 | Flags = 1 << 0, 9 | SquadMates = 1 << 1, 10 | SquadCaptain = 1 << 2, 11 | 12 | Tanks = 1 << 3, 13 | Transports = 1 << 4, 14 | Boats = 1 << 5, 15 | Helicopters = 1 << 6, 16 | APCs = 1 << 7, 17 | 18 | RallyPoints = 1 << 8, 19 | 20 | All = ulong.MaxValue, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/Squads.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum Squads 4 | { 5 | NoSquad = 0, 6 | 7 | Alpha = 1, 8 | Bravo = 2, 9 | Charlie = 3, 10 | Delta = 4, 11 | Echo = 5, 12 | Foxtrot = 6, 13 | Golf = 7, 14 | Hotel = 8, 15 | India = 9, 16 | Juliett = 10, 17 | Kilo = 11, 18 | Lima = 12, 19 | Mike = 13, 20 | November = 14, 21 | Oscar = 15, 22 | Papa = 16, 23 | Quebec = 17, 24 | Romeo = 18, 25 | Sierra = 19, 26 | Tango = 20, 27 | Uniform = 21, 28 | Whiskey = 22, 29 | Xray = 23, 30 | Yankee = 24, 31 | Zulu = 25, 32 | Ash = 26, 33 | Baker = 27, 34 | Cast = 28, 35 | Diver = 29, 36 | Eagle = 30, 37 | Fisher = 31, 38 | George = 32, 39 | Hanover = 33, 40 | Ice = 34, 41 | Jake = 35, 42 | King = 36, 43 | Lash = 37, 44 | Mule = 38, 45 | Neptune = 39, 46 | Ostend = 40, 47 | Page = 41, 48 | Quail = 42, 49 | Raft = 43, 50 | Scout = 44, 51 | Tare = 45, 52 | Unit = 46, 53 | William = 47, 54 | Xaintrie = 48, 55 | Yoke = 49, 56 | Zebra = 50, 57 | Ace = 51, 58 | Beer = 52, 59 | Cast2 = 53, 60 | Duff = 54, 61 | Edward = 55, 62 | Freddy = 56, 63 | Gustav = 57, 64 | Henry = 58, 65 | Ivar = 59, 66 | Jazz = 60, 67 | Key = 61, 68 | Lincoln = 62, 69 | Mary = 63, 70 | Nora = 64 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/Team.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum Team : byte 4 | { 5 | TeamA = 0, 6 | TeamB = 1, 7 | None = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/VehicleType.cs: -------------------------------------------------------------------------------- 1 | [System.Flags] 2 | public enum VehicleType : byte 3 | { 4 | None = 0, 5 | 6 | Tank = 1 << 1, 7 | Transport = 1 << 2, 8 | SeaVehicle = 1 << 3, 9 | APC = 1 << 4, 10 | Helicopters = 1 << 5, 11 | 12 | All = 255, 13 | } -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/VoxelTextures.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum VoxelTextures : byte 4 | { 5 | Default = 0, 6 | NeonOrange = 1, 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Enums/WeaponType.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common 2 | { 3 | public enum WeaponType : int 4 | { 5 | Rifle, 6 | DMR, 7 | SniperRifle, 8 | LightSupportGun_LSG, 9 | LightMachineGun_LMG, 10 | SubmachineGun_SMG, 11 | Pistol, 12 | AutoPistol, 13 | HeavyPistol, 14 | Carbine, 15 | PersonalDefenseWeapon_PDW, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Extentions/Extentions.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Sockets; 3 | 4 | namespace BattleBitAPI.Common.Extentions 5 | { 6 | public static class Extentions 7 | { 8 | public static long TickCount 9 | { 10 | get 11 | { 12 | #if NETCOREAPP 13 | return System.Environment.TickCount64; 14 | #else 15 | return (long)Environment.TickCount; 16 | #endif 17 | } 18 | } 19 | public unsafe static uint ToUInt(this IPAddress address) 20 | { 21 | #if NETCOREAPP 22 | return BitConverter.ToUInt32(address.GetAddressBytes()); 23 | #else 24 | return BitConverter.ToUInt32(address.GetAddressBytes(), 0); 25 | #endif 26 | } 27 | 28 | public static void Replace(this Dictionary dic, TKey key, TValue value) 29 | { 30 | dic.Remove(key); 31 | dic.Add(key, value); 32 | } 33 | 34 | public static void SafeClose(this TcpClient client) 35 | { 36 | try { client.Close(); } catch { } 37 | try { client.Dispose(); } catch { } 38 | } 39 | public static async Task Read(this NetworkStream networkStream, Serialization.Stream outputStream, int size, CancellationToken token = default) 40 | { 41 | int read = 0; 42 | int readUntil = outputStream.WritePosition + size; 43 | 44 | //Ensure we have space. 45 | outputStream.EnsureWriteBufferSize(size); 46 | 47 | //Continue reading until we have the package. 48 | while (outputStream.WritePosition < readUntil) 49 | { 50 | int sizeToRead = readUntil - outputStream.WritePosition; 51 | int received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); 52 | if (received <= 0) 53 | throw new Exception("NetworkStream was closed."); 54 | 55 | read += received; 56 | outputStream.WritePosition += received; 57 | } 58 | 59 | return read; 60 | } 61 | public static async Task TryRead(this NetworkStream networkStream, Serialization.Stream outputStream, int size, CancellationToken token = default) 62 | { 63 | try 64 | { 65 | int readUntil = outputStream.WritePosition + size; 66 | 67 | //Ensure we have space. 68 | outputStream.EnsureWriteBufferSize(size); 69 | 70 | //Continue reading until we have the package. 71 | while (outputStream.WritePosition < readUntil) 72 | { 73 | int sizeToRead = readUntil - outputStream.WritePosition; 74 | int received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); 75 | if (received <= 0) 76 | throw new Exception("NetworkStream was closed."); 77 | outputStream.WritePosition += received; 78 | } 79 | 80 | return true; 81 | } 82 | catch 83 | { 84 | return false; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Serialization/IStreamSerializble.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Common.Serialization 2 | { 3 | public interface IStreamSerializable 4 | { 5 | void Read(Stream ser); 6 | void Write(Stream ser); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /BattleBitAPI/Common/Serialization/Stream.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common.Extentions; 2 | using System.Net; 3 | 4 | namespace BattleBitAPI.Common.Serialization 5 | { 6 | public class Stream : IDisposable 7 | { 8 | public const int DefaultBufferSize = 1024 * 512; 9 | 10 | #if BIGENDIAN 11 | public static readonly bool IsLittleEndian = false; 12 | #else 13 | public static readonly bool IsLittleEndian = true; 14 | #endif 15 | 16 | public byte[] Buffer; 17 | public int WritePosition; 18 | public int ReadPosition; 19 | public bool InPool; 20 | 21 | public bool CanRead(int size) 22 | { 23 | int readableLenght = WritePosition - ReadPosition; 24 | return (readableLenght >= size); 25 | } 26 | public void EnsureWriteBufferSize(int requiredSize) 27 | { 28 | int bufferLenght = Buffer.Length; 29 | 30 | int leftSpace = bufferLenght - WritePosition; 31 | if (leftSpace < requiredSize) 32 | { 33 | int newSize = bufferLenght + Math.Max(requiredSize, 1024); 34 | System.Array.Resize(ref Buffer, newSize); 35 | } 36 | } 37 | 38 | // -------- Write ------ 39 | public void Write(byte value) 40 | { 41 | EnsureWriteBufferSize(1); 42 | Buffer[WritePosition] = value; 43 | WritePosition += 1; 44 | } 45 | public void Write(bool value) 46 | { 47 | EnsureWriteBufferSize(1); 48 | Buffer[WritePosition] = value ? (byte)1 : (byte)0; 49 | WritePosition += 1; 50 | } 51 | public unsafe void Write(short value) 52 | { 53 | EnsureWriteBufferSize(2); 54 | fixed (byte* ptr = &Buffer[WritePosition]) 55 | *((short*)ptr) = value; 56 | WritePosition += 2; 57 | } 58 | public unsafe void Write(ushort value) 59 | { 60 | EnsureWriteBufferSize(2); 61 | fixed (byte* ptr = &Buffer[WritePosition]) 62 | *((ushort*)ptr) = value; 63 | WritePosition += 2; 64 | } 65 | public unsafe void Write(int value) 66 | { 67 | EnsureWriteBufferSize(4); 68 | fixed (byte* ptr = &Buffer[WritePosition]) 69 | *((int*)ptr) = value; 70 | WritePosition += 4; 71 | } 72 | public unsafe void Write(uint value) 73 | { 74 | EnsureWriteBufferSize(4); 75 | fixed (byte* ptr = &Buffer[WritePosition]) 76 | *((uint*)ptr) = value; 77 | WritePosition += 4; 78 | } 79 | public unsafe void Write(long value) 80 | { 81 | EnsureWriteBufferSize(8); 82 | fixed (byte* ptr = &Buffer[WritePosition]) 83 | *((long*)ptr) = value; 84 | WritePosition += 8; 85 | } 86 | public unsafe void Write(ulong value) 87 | { 88 | EnsureWriteBufferSize(8); 89 | fixed (byte* ptr = &Buffer[WritePosition]) 90 | *((ulong*)ptr) = value; 91 | WritePosition += 8; 92 | } 93 | public unsafe void Write(decimal value) 94 | { 95 | EnsureWriteBufferSize(16); 96 | fixed (byte* ptr = &Buffer[WritePosition]) 97 | *((decimal*)ptr) = value; 98 | WritePosition += 16; 99 | } 100 | public unsafe void Write(double value) 101 | { 102 | EnsureWriteBufferSize(8); 103 | fixed (byte* ptr = &Buffer[WritePosition]) 104 | *((double*)ptr) = value; 105 | WritePosition += 8; 106 | } 107 | public unsafe void Write(float value) 108 | { 109 | int intValue = *((int*)&value); 110 | EnsureWriteBufferSize(4); 111 | fixed (byte* ptr = &Buffer[WritePosition]) 112 | *((int*)ptr) = intValue; 113 | WritePosition += 4; 114 | } 115 | public unsafe void Write(string value) 116 | { 117 | int charCount = value.Length; 118 | fixed (char* strPtr = value) 119 | { 120 | int size = System.Text.Encoding.UTF8.GetByteCount(strPtr, charCount); 121 | EnsureWriteBufferSize(size + 2); 122 | 123 | 124 | fixed (byte* buffPtr = &Buffer[WritePosition]) 125 | { 126 | *((ushort*)buffPtr) = (ushort)size; 127 | System.Text.Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr + 2, size); 128 | } 129 | WritePosition += size + 2; 130 | } 131 | } 132 | public unsafe void Write(DateTime value) 133 | { 134 | var utc = value.ToUniversalTime(); 135 | 136 | EnsureWriteBufferSize(8); 137 | fixed (byte* ptr = &Buffer[WritePosition]) 138 | *((long*)ptr) = utc.Ticks; 139 | WritePosition += 8; 140 | } 141 | public unsafe void Write(IPAddress value) 142 | { 143 | uint ip = value.ToUInt(); 144 | Write(ip); 145 | } 146 | public unsafe void Write(IPEndPoint value) 147 | { 148 | uint ip = value.Address.ToUInt(); 149 | 150 | Write(ip); 151 | Write((ushort)value.Port); 152 | } 153 | public unsafe void WriteRaw(string value) 154 | { 155 | int charCount = value.Length; 156 | fixed (char* strPtr = value) 157 | { 158 | int size = System.Text.Encoding.UTF8.GetByteCount(strPtr, charCount); 159 | EnsureWriteBufferSize(size); 160 | 161 | fixed (byte* buffPtr = &Buffer[WritePosition]) 162 | System.Text.Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr, size); 163 | WritePosition += size; 164 | } 165 | } 166 | public unsafe void Write(T value) where T : IStreamSerializable 167 | { 168 | value.Write(this); 169 | } 170 | public void Write(byte[] source, int sourceIndex, int length) 171 | { 172 | if (length == 0) 173 | return; 174 | 175 | EnsureWriteBufferSize(length); 176 | System.Array.Copy(source, sourceIndex, this.Buffer, this.WritePosition, length); 177 | this.WritePosition += length; 178 | } 179 | public void Write(Stream source) 180 | { 181 | EnsureWriteBufferSize(source.WritePosition); 182 | System.Array.Copy(source.Buffer, 0, this.Buffer, this.WritePosition, source.WritePosition); 183 | this.WritePosition += source.WritePosition; 184 | } 185 | public void WriteStringItem(string value) 186 | { 187 | if (value == null) 188 | this.Write("none"); 189 | else 190 | this.Write(value); 191 | } 192 | 193 | public unsafe void WriteAt(byte value, int position) 194 | { 195 | Buffer[position] = value; 196 | } 197 | public unsafe void WriteAt(short value, int position) 198 | { 199 | fixed (byte* ptr = &Buffer[position]) 200 | *((short*)ptr) = value; 201 | } 202 | public unsafe void WriteAt(ushort value, int position) 203 | { 204 | fixed (byte* ptr = &Buffer[position]) 205 | *((ushort*)ptr) = value; 206 | } 207 | public unsafe void WriteAt(int value, int position) 208 | { 209 | fixed (byte* ptr = &Buffer[position]) 210 | *((int*)ptr) = value; 211 | } 212 | public unsafe void WriteAt(uint value, int position) 213 | { 214 | fixed (byte* ptr = &Buffer[position]) 215 | *((uint*)ptr) = value; 216 | } 217 | public unsafe void WriteAt(long value, int position) 218 | { 219 | fixed (byte* ptr = &Buffer[position]) 220 | *((long*)ptr) = value; 221 | } 222 | public unsafe void WriteAt(ulong value, int position) 223 | { 224 | fixed (byte* ptr = &Buffer[position]) 225 | *((ulong*)ptr) = value; 226 | } 227 | 228 | // -------- Read ------ 229 | public byte ReadInt8() 230 | { 231 | 232 | var value = Buffer[ReadPosition]; 233 | ReadPosition++; 234 | 235 | return value; 236 | } 237 | public bool ReadBool() 238 | { 239 | 240 | 241 | var value = Buffer[ReadPosition]; 242 | ReadPosition++; 243 | 244 | return value == 1; 245 | } 246 | public unsafe short ReadInt16() 247 | { 248 | short value = 0; 249 | 250 | fixed (byte* pbyte = &Buffer[ReadPosition]) 251 | { 252 | if (ReadPosition % 2 == 0) 253 | { 254 | value = *((short*)pbyte); 255 | } 256 | else 257 | { 258 | if (IsLittleEndian) 259 | { 260 | value = (short)((*pbyte) | (*(pbyte + 1) << 8)); 261 | } 262 | else 263 | { 264 | value = (short)((*pbyte << 8) | (*(pbyte + 1))); 265 | } 266 | } 267 | } 268 | 269 | ReadPosition += 2; 270 | return value; 271 | } 272 | public unsafe ushort ReadUInt16() 273 | { 274 | ushort value = 0; 275 | 276 | fixed (byte* pbyte = &Buffer[ReadPosition]) 277 | { 278 | if (ReadPosition % 2 == 0) 279 | { 280 | value = *((ushort*)pbyte); 281 | } 282 | else 283 | { 284 | if (IsLittleEndian) 285 | { 286 | value = (ushort)((*pbyte) | (*(pbyte + 1) << 8)); 287 | } 288 | else 289 | { 290 | value = (ushort)((*pbyte << 8) | (*(pbyte + 1))); 291 | } 292 | } 293 | } 294 | 295 | ReadPosition += 2; 296 | return value; 297 | } 298 | public unsafe int ReadInt32() 299 | { 300 | int value = 0; 301 | fixed (byte* pbyte = &Buffer[ReadPosition]) 302 | { 303 | if (ReadPosition % 4 == 0) 304 | { 305 | value = *((int*)pbyte); 306 | } 307 | else 308 | { 309 | if (IsLittleEndian) 310 | { 311 | value = (int)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); 312 | } 313 | else 314 | { 315 | value = (int)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); 316 | } 317 | } 318 | } 319 | ReadPosition += 4; 320 | 321 | return value; 322 | } 323 | public unsafe uint ReadUInt32() 324 | { 325 | uint value = 0; 326 | fixed (byte* pbyte = &Buffer[ReadPosition]) 327 | { 328 | if (ReadPosition % 4 == 0) 329 | { 330 | value = *((uint*)pbyte); 331 | } 332 | else 333 | { 334 | if (IsLittleEndian) 335 | { 336 | value = (uint)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); 337 | } 338 | else 339 | { 340 | value = (uint)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); 341 | } 342 | } 343 | } 344 | ReadPosition += 4; 345 | 346 | return value; 347 | } 348 | public unsafe long ReadInt64() 349 | { 350 | long value = 0; 351 | fixed (byte* pbyte = &Buffer[ReadPosition]) 352 | { 353 | if (ReadPosition % 8 == 0) 354 | { 355 | value = *((long*)pbyte); 356 | } 357 | else 358 | { 359 | if (IsLittleEndian) 360 | { 361 | int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); 362 | int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); 363 | value = (uint)i1 | ((long)i2 << 32); 364 | } 365 | else 366 | { 367 | int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); 368 | int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); 369 | value = (uint)i2 | ((long)i1 << 32); 370 | } 371 | } 372 | } 373 | ReadPosition += 8; 374 | 375 | return value; 376 | } 377 | public unsafe ulong ReadUInt64() 378 | { 379 | ulong value = 0; 380 | fixed (byte* pbyte = &Buffer[ReadPosition]) 381 | { 382 | if (ReadPosition % 8 == 0) 383 | { 384 | value = *((ulong*)pbyte); 385 | } 386 | else 387 | { 388 | if (IsLittleEndian) 389 | { 390 | int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); 391 | int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); 392 | value = (uint)i1 | ((ulong)i2 << 32); 393 | } 394 | else 395 | { 396 | int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); 397 | int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); 398 | value = (uint)i2 | ((ulong)i1 << 32); 399 | } 400 | } 401 | } 402 | ReadPosition += 8; 403 | 404 | return value; 405 | } 406 | public unsafe decimal ReadInt128() 407 | { 408 | 409 | 410 | decimal value = 0; 411 | fixed (byte* ptr = &Buffer[ReadPosition]) 412 | { 413 | value = *((decimal*)ptr); 414 | } 415 | ReadPosition += 16; 416 | 417 | return value; 418 | } 419 | public unsafe double ReadDouble() 420 | { 421 | double value = 0; 422 | fixed (byte* ptr = &Buffer[ReadPosition]) 423 | { 424 | value = *((double*)ptr); 425 | } 426 | ReadPosition += 8; 427 | 428 | return value; 429 | } 430 | public unsafe float ReadFloat() 431 | { 432 | int value = 0; 433 | fixed (byte* pbyte = &Buffer[ReadPosition]) 434 | { 435 | if (ReadPosition % 4 == 0) 436 | { 437 | value = *((int*)pbyte); 438 | } 439 | else 440 | { 441 | if (IsLittleEndian) 442 | { 443 | value = (int)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); 444 | } 445 | else 446 | { 447 | value = (int)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); 448 | } 449 | } 450 | } 451 | ReadPosition += 4; 452 | 453 | return *(float*)&value; 454 | } 455 | public DateTime ReadDateTime() 456 | { 457 | long value = ReadInt64(); 458 | try 459 | { 460 | return new DateTime(value, DateTimeKind.Utc); 461 | } 462 | catch 463 | { 464 | return DateTime.MinValue; 465 | } 466 | } 467 | public bool TryReadDateTime(out DateTime time) 468 | { 469 | long value = ReadInt64(); 470 | try 471 | { 472 | time = new DateTime(value, DateTimeKind.Utc); 473 | return true; 474 | } 475 | catch { } 476 | 477 | time = default; 478 | return false; 479 | } 480 | public unsafe IPAddress ReadIPAddress() 481 | { 482 | uint ip = ReadUInt32(); 483 | return new IPAddress(ip); 484 | } 485 | public unsafe IPEndPoint ReadIPEndPoint() 486 | { 487 | uint ip = ReadUInt32(); 488 | ushort port = ReadUInt16(); 489 | 490 | return new IPEndPoint(ip, port); 491 | } 492 | public T Read() where T : IStreamSerializable 493 | { 494 | T value = default; 495 | value.Read(this); 496 | return value; 497 | } 498 | 499 | public byte[] ReadByteArray(int lenght) 500 | { 501 | if (lenght == 0) 502 | return new byte[0]; 503 | 504 | byte[] newBuffer = new byte[lenght]; 505 | System.Array.Copy(this.Buffer, this.ReadPosition, newBuffer, 0, lenght); 506 | this.ReadPosition += lenght; 507 | return newBuffer; 508 | } 509 | public void ReadTo(byte[] buffer, int offset, int size) 510 | { 511 | System.Array.Copy(this.Buffer, this.ReadPosition, buffer, offset, size); 512 | this.ReadPosition += size; 513 | } 514 | public unsafe string ReadString(int size) 515 | { 516 | string str; 517 | 518 | #if NETCOREAPP 519 | fixed (byte* ptr = &Buffer[ReadPosition]) 520 | str = System.Text.Encoding.UTF8.GetString(ptr, size); 521 | #else 522 | str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); 523 | #endif 524 | ReadPosition += size; 525 | 526 | return str; 527 | } 528 | public unsafe bool TryReadString(out string str) 529 | { 530 | if (!CanRead(2)) 531 | { 532 | str = null; 533 | return false; 534 | } 535 | 536 | 537 | int size = 0; 538 | fixed (byte* ptr = &Buffer[ReadPosition]) 539 | size = *((ushort*)ptr); 540 | ReadPosition += 2; 541 | 542 | if (!CanRead(size)) 543 | { 544 | str = null; 545 | return false; 546 | } 547 | 548 | #if NETCOREAPP 549 | fixed (byte* ptr = &Buffer[ReadPosition]) 550 | str = System.Text.Encoding.UTF8.GetString(ptr, size); 551 | #else 552 | str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); 553 | #endif 554 | 555 | ReadPosition += size; 556 | 557 | return true; 558 | } 559 | public unsafe bool TryReadString(out string str, int maximumSize = ushort.MaxValue) 560 | { 561 | if (!CanRead(2)) 562 | { 563 | str = null; 564 | return false; 565 | } 566 | 567 | 568 | int size = 0; 569 | fixed (byte* ptr = &Buffer[ReadPosition]) 570 | size = *((ushort*)ptr); 571 | ReadPosition += 2; 572 | 573 | if (size > maximumSize) 574 | { 575 | str = null; 576 | return false; 577 | } 578 | 579 | if (!CanRead(size)) 580 | { 581 | str = null; 582 | return false; 583 | } 584 | 585 | #if NETCOREAPP 586 | fixed (byte* ptr = &Buffer[ReadPosition]) 587 | str = System.Text.Encoding.UTF8.GetString(ptr, size); 588 | #else 589 | str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); 590 | #endif 591 | 592 | ReadPosition += size; 593 | 594 | return true; 595 | } 596 | public unsafe bool TrySkipString() 597 | { 598 | if (!CanRead(2)) 599 | return false; 600 | 601 | int size = 0; 602 | fixed (byte* ptr = &Buffer[ReadPosition]) 603 | size = *((ushort*)ptr); 604 | ReadPosition += 2; 605 | 606 | if (!CanRead(size)) 607 | return false; 608 | 609 | ReadPosition += size; 610 | return true; 611 | } 612 | 613 | public int NumberOfBytesReadable 614 | { 615 | get => WritePosition - ReadPosition; 616 | } 617 | public void SkipWriting(int size) 618 | { 619 | EnsureWriteBufferSize(size); 620 | WritePosition += size; 621 | } 622 | public void SkipReading(int size) 623 | { 624 | ReadPosition += size; 625 | } 626 | 627 | // -------- Finalizing ------ 628 | public byte[] AsByteArrayData() 629 | { 630 | var data = new byte[this.WritePosition]; 631 | System.Array.Copy(this.Buffer, 0, data, 0, this.WritePosition); 632 | return data; 633 | } 634 | public void Reset() 635 | { 636 | this.ReadPosition = 0; 637 | this.WritePosition = 0; 638 | } 639 | public void Dispose() 640 | { 641 | if (InPool) 642 | return; 643 | InPool = true; 644 | 645 | lock (mPool) 646 | mPool.Enqueue(this); 647 | } 648 | 649 | // ------- Pool ----- 650 | private static Queue mPool = new Queue(1024 * 256); 651 | public static Stream Get() 652 | { 653 | lock (mPool) 654 | { 655 | if (mPool.Count > 0) 656 | { 657 | var item = mPool.Dequeue(); 658 | item.WritePosition = 0; 659 | item.ReadPosition = 0; 660 | item.InPool = false; 661 | 662 | return item; 663 | } 664 | } 665 | 666 | return new Stream() 667 | { 668 | Buffer = new byte[DefaultBufferSize], 669 | InPool = false, 670 | ReadPosition = 0, 671 | WritePosition = 0, 672 | }; 673 | } 674 | } 675 | } -------------------------------------------------------------------------------- /BattleBitAPI/Common/Threading/ThreadSafe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace BattleBitAPI.Common.Threading 5 | { 6 | public class ThreadSafe 7 | { 8 | private System.Threading.ReaderWriterLockSlim mLock; 9 | public T Value; 10 | 11 | public ThreadSafe(T value) 12 | { 13 | this.Value = value; 14 | this.mLock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.SupportsRecursion); 15 | } 16 | 17 | public SafeWriteHandle GetWriteHandle() => new SafeWriteHandle(this.mLock); 18 | public SafeReadHandle GetReadHandle() => new SafeReadHandle(this.mLock); 19 | 20 | /// 21 | /// Swaps current value with new value and returns old one. 22 | /// 23 | /// 24 | /// Old value 25 | public T SwapValue(T newValue) 26 | { 27 | using (new SafeWriteHandle(this.mLock)) 28 | { 29 | var oldValue = this.Value; 30 | this.Value = newValue; 31 | return oldValue; 32 | } 33 | } 34 | } 35 | public class SafeWriteHandle : System.IDisposable 36 | { 37 | private System.Threading.ReaderWriterLockSlim mLock; 38 | private bool mDisposed; 39 | public SafeWriteHandle(System.Threading.ReaderWriterLockSlim mLock) 40 | { 41 | this.mLock = mLock; 42 | mLock.EnterWriteLock(); 43 | } 44 | public void Dispose() 45 | { 46 | if (mDisposed) 47 | return; 48 | mDisposed = true; 49 | mLock.ExitWriteLock(); 50 | } 51 | } 52 | public class SafeReadHandle : System.IDisposable 53 | { 54 | private System.Threading.ReaderWriterLockSlim mLock; 55 | private bool mDisposed; 56 | public SafeReadHandle(System.Threading.ReaderWriterLockSlim mLock) 57 | { 58 | this.mLock = mLock; 59 | mLock.EnterReadLock(); 60 | } 61 | public void Dispose() 62 | { 63 | if (mDisposed) 64 | return; 65 | mDisposed = true; 66 | 67 | mLock.ExitReadLock(); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /BattleBitAPI/Networking/NetworkCommuncation.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Networking 2 | { 3 | public enum NetworkCommuncation : byte 4 | { 5 | None = 0, 6 | Hail = 1, 7 | Accepted = 2, 8 | Denied = 3, 9 | 10 | ExecuteCommand = 10, 11 | SendPlayerStats = 11, 12 | SpawnPlayer = 12, 13 | SetNewRoomSettings = 13, 14 | RespondPlayerMessage = 14, 15 | SetNewRoundState = 15, 16 | SetPlayerWeapon = 16, 17 | SetPlayerGadget = 17, 18 | SetPlayerModifications = 18, 19 | EndgameWithPlayers = 19, 20 | PlaceVoxelBlock = 20, 21 | RemoveVoxelBlock = 21, 22 | 23 | PlayerConnected = 50, 24 | PlayerDisconnected = 51, 25 | OnPlayerTypedMessage = 52, 26 | OnAPlayerDownedAnotherPlayer = 53, 27 | OnPlayerJoining = 54, 28 | SavePlayerStats = 55, 29 | OnPlayerAskingToChangeRole = 56, 30 | OnPlayerChangedRole = 57, 31 | OnPlayerJoinedASquad = 58, 32 | OnPlayerLeftSquad = 59, 33 | OnPlayerChangedTeam = 60, 34 | OnPlayerRequestingToSpawn = 61, 35 | OnPlayerReport = 62, 36 | OnPlayerSpawn = 63, 37 | OnPlayerDie = 64, 38 | NotifyNewMapRotation = 65, 39 | NotifyNewGamemodeRotation = 66, 40 | NotifyNewRoundState = 67, 41 | OnPlayerAskingToChangeTeam = 68, 42 | GameTick = 69, 43 | OnPlayerGivenUp = 70, 44 | OnPlayerRevivedAnother = 71, 45 | OnSquadPointsChanged = 72, 46 | NotifyNewRoundID = 73, 47 | Log = 74, 48 | OnSquadLeaderChanged = 75, 49 | UpdateNewGameData = 76, 50 | UpdateConnectedPlayers = 77, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /BattleBitAPI/Pooling/ItemPooling.cs: -------------------------------------------------------------------------------- 1 | namespace BattleBitAPI.Pooling 2 | { 3 | public class ItemPooling 4 | { 5 | private Queue.List> mPool; 6 | private int mDefaultCount; 7 | public ItemPooling(int defaultCount) 8 | { 9 | this.mPool = new Queue.List>(6); 10 | this.mDefaultCount = defaultCount; 11 | } 12 | 13 | public ItemPooling.List Get() 14 | { 15 | lock (mPool) 16 | { 17 | if (mPool.Count > 0) 18 | return mPool.Dequeue(); 19 | } 20 | return new ItemPooling.List(this, mDefaultCount); 21 | } 22 | public void Post(ItemPooling.List item) 23 | { 24 | lock (mPool) 25 | mPool.Enqueue(item); 26 | } 27 | 28 | public class List : IDisposable 29 | { 30 | private ItemPooling mParent; 31 | public List ListItems; 32 | 33 | public List(ItemPooling parent, int count) 34 | { 35 | this.mParent = parent; 36 | this.ListItems = new List(count); 37 | } 38 | 39 | 40 | public void Dispose() 41 | { 42 | ListItems.Clear(); 43 | mParent.Post(this); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Internal/GamemodeRotation.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | 3 | namespace BattleBitAPI.Server 4 | { 5 | public class GamemodeRotation where TPlayer : Player 6 | { 7 | private GameServer.Internal mResources; 8 | public GamemodeRotation(GameServer.Internal resources) 9 | { 10 | mResources = resources; 11 | } 12 | 13 | public IEnumerable GetGamemodeRotation() 14 | { 15 | lock (mResources._GamemodeRotation) 16 | return new List(mResources._GamemodeRotation); 17 | } 18 | public bool InRotation(string gamemode) 19 | { 20 | lock (mResources._GamemodeRotation) 21 | return mResources._GamemodeRotation.Contains(gamemode); 22 | } 23 | public bool RemoveFromRotation(string gamemode) 24 | { 25 | lock (mResources._GamemodeRotation) 26 | if (!mResources._GamemodeRotation.Remove(gamemode)) 27 | return false; 28 | mResources.IsDirtyGamemodeRotation = true; 29 | return true; 30 | } 31 | public bool AddToRotation(string gamemode) 32 | { 33 | lock (mResources._GamemodeRotation) 34 | if (!mResources._GamemodeRotation.Add(gamemode)) 35 | return false; 36 | mResources.IsDirtyGamemodeRotation = true; 37 | return true; 38 | } 39 | public void SetRotation(params string[] gamemodes) 40 | { 41 | lock (mResources._GamemodeRotation) 42 | { 43 | mResources._GamemodeRotation.Clear(); 44 | foreach (var item in gamemodes) 45 | mResources._GamemodeRotation.Add(item); 46 | } 47 | mResources.IsDirtyGamemodeRotation = true; 48 | } 49 | public void ClearRotation() 50 | { 51 | lock (mResources._GamemodeRotation) 52 | { 53 | if (mResources._GamemodeRotation.Count == 0) 54 | return; 55 | 56 | mResources._GamemodeRotation.Clear(); 57 | } 58 | mResources.IsDirtyGamemodeRotation = true; 59 | } 60 | 61 | public void Reset() 62 | { 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Internal/MapRotation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace BattleBitAPI.Server 3 | { 4 | public class MapRotation where TPlayer : Player 5 | { 6 | private GameServer.Internal mResources; 7 | public MapRotation(GameServer.Internal resources) 8 | { 9 | mResources = resources; 10 | } 11 | 12 | public IEnumerable GetMapRotation() 13 | { 14 | lock (mResources._MapRotation) 15 | return new List(mResources._MapRotation); 16 | } 17 | public bool InRotation(string map) 18 | { 19 | map = map.ToUpperInvariant(); 20 | 21 | lock (mResources._MapRotation) 22 | return mResources._MapRotation.Contains(map); 23 | } 24 | public bool RemoveFromRotation(string map) 25 | { 26 | map = map.ToUpperInvariant(); 27 | 28 | lock (mResources._MapRotation) 29 | if (!mResources._MapRotation.Remove(map)) 30 | return false; 31 | mResources.IsDirtyMapRotation = true; 32 | return true; 33 | } 34 | public bool AddToRotation(string map) 35 | { 36 | map = map.ToUpperInvariant(); 37 | 38 | lock (mResources._MapRotation) 39 | if (!mResources._MapRotation.Add(map)) 40 | return false; 41 | mResources.IsDirtyMapRotation = true; 42 | return true; 43 | } 44 | public void SetRotation(params string[] maps) 45 | { 46 | lock (mResources._MapRotation) 47 | { 48 | mResources._MapRotation.Clear(); 49 | foreach (var item in maps) 50 | mResources._MapRotation.Add(item); 51 | } 52 | mResources.IsDirtyMapRotation = true; 53 | } 54 | public void ClearRotation() 55 | { 56 | lock (mResources._MapRotation) 57 | { 58 | if (mResources._MapRotation.Count == 0) 59 | return; 60 | 61 | mResources._MapRotation.Clear(); 62 | } 63 | mResources.IsDirtyMapRotation = true; 64 | } 65 | 66 | public void Reset() 67 | { 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Internal/PlayerModifications.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | using System.Runtime.ConstrainedExecution; 3 | 4 | namespace BattleBitAPI.Server 5 | { 6 | public class PlayerModifications where TPlayer : Player 7 | { 8 | // ---- Construction ---- 9 | private Player.Internal @internal; 10 | public PlayerModifications(Player.Internal @internal) 11 | { 12 | this.@internal = @internal; 13 | } 14 | 15 | // ---- Variables ---- 16 | public float RunningSpeedMultiplier 17 | { 18 | get => @internal._Modifications.RunningSpeedMultiplier; 19 | set 20 | { 21 | if (@internal._Modifications.RunningSpeedMultiplier == value) 22 | return; 23 | @internal._Modifications.RunningSpeedMultiplier = value; 24 | @internal._Modifications.IsDirtyFlag = true; 25 | } 26 | } 27 | public float ReceiveDamageMultiplier 28 | { 29 | get => @internal._Modifications.ReceiveDamageMultiplier; 30 | set 31 | { 32 | if (@internal._Modifications.ReceiveDamageMultiplier == value) 33 | return; 34 | @internal._Modifications.ReceiveDamageMultiplier = value; 35 | @internal._Modifications.IsDirtyFlag = true; 36 | } 37 | } 38 | public float GiveDamageMultiplier 39 | { 40 | get => @internal._Modifications.GiveDamageMultiplier; 41 | set 42 | { 43 | if (@internal._Modifications.GiveDamageMultiplier == value) 44 | return; 45 | @internal._Modifications.GiveDamageMultiplier = value; 46 | @internal._Modifications.IsDirtyFlag = true; 47 | } 48 | } 49 | public float JumpHeightMultiplier 50 | { 51 | get => @internal._Modifications.JumpHeightMultiplier; 52 | set 53 | { 54 | if (@internal._Modifications.JumpHeightMultiplier == value) 55 | return; 56 | @internal._Modifications.JumpHeightMultiplier = value; 57 | @internal._Modifications.IsDirtyFlag = true; 58 | } 59 | } 60 | public float FallDamageMultiplier 61 | { 62 | get => @internal._Modifications.FallDamageMultiplier; 63 | set 64 | { 65 | if (@internal._Modifications.FallDamageMultiplier == value) 66 | return; 67 | @internal._Modifications.FallDamageMultiplier = value; 68 | @internal._Modifications.IsDirtyFlag = true; 69 | } 70 | } 71 | public float ReloadSpeedMultiplier 72 | { 73 | get => @internal._Modifications.ReloadSpeedMultiplier; 74 | set 75 | { 76 | if (@internal._Modifications.ReloadSpeedMultiplier == value) 77 | return; 78 | @internal._Modifications.ReloadSpeedMultiplier = value; 79 | @internal._Modifications.IsDirtyFlag = true; 80 | } 81 | } 82 | public bool CanUseNightVision 83 | { 84 | get => @internal._Modifications.CanUseNightVision; 85 | set 86 | { 87 | if (@internal._Modifications.CanUseNightVision == value) 88 | return; 89 | @internal._Modifications.CanUseNightVision = value; 90 | @internal._Modifications.IsDirtyFlag = true; 91 | } 92 | } 93 | public float DownTimeGiveUpTime 94 | { 95 | get => @internal._Modifications.DownTimeGiveUpTime; 96 | set 97 | { 98 | if (@internal._Modifications.DownTimeGiveUpTime == value) 99 | return; 100 | @internal._Modifications.DownTimeGiveUpTime = value; 101 | @internal._Modifications.IsDirtyFlag = true; 102 | } 103 | } 104 | public bool AirStrafe 105 | { 106 | get => @internal._Modifications.AirStrafe; 107 | set 108 | { 109 | if (@internal._Modifications.AirStrafe == value) 110 | return; 111 | @internal._Modifications.AirStrafe = value; 112 | @internal._Modifications.IsDirtyFlag = true; 113 | } 114 | } 115 | public bool CanDeploy 116 | { 117 | get => @internal._Modifications.CanDeploy; 118 | set 119 | { 120 | if (@internal._Modifications.CanDeploy == value) 121 | return; 122 | @internal._Modifications.CanDeploy = value; 123 | @internal._Modifications.IsDirtyFlag = true; 124 | } 125 | } 126 | public bool CanSpectate 127 | { 128 | get => @internal._Modifications.CanSpectate; 129 | set 130 | { 131 | if (@internal._Modifications.CanSpectate == value) 132 | return; 133 | @internal._Modifications.CanSpectate = value; 134 | @internal._Modifications.IsDirtyFlag = true; 135 | } 136 | } 137 | public bool IsTextChatMuted 138 | { 139 | get => @internal._Modifications.IsTextChatMuted; 140 | set 141 | { 142 | if (@internal._Modifications.IsTextChatMuted == value) 143 | return; 144 | @internal._Modifications.IsTextChatMuted = value; 145 | @internal._Modifications.IsDirtyFlag = true; 146 | } 147 | } 148 | public bool IsVoiceChatMuted 149 | { 150 | get => @internal._Modifications.IsVoiceChatMuted; 151 | set 152 | { 153 | if (@internal._Modifications.IsVoiceChatMuted == value) 154 | return; 155 | @internal._Modifications.IsVoiceChatMuted = value; 156 | @internal._Modifications.IsDirtyFlag = true; 157 | } 158 | } 159 | public float RespawnTime 160 | { 161 | get => @internal._Modifications.RespawnTime; 162 | set 163 | { 164 | if (@internal._Modifications.RespawnTime == value) 165 | return; 166 | @internal._Modifications.RespawnTime = value; 167 | @internal._Modifications.IsDirtyFlag = true; 168 | } 169 | } 170 | public bool CanSuicide 171 | { 172 | get => @internal._Modifications.CanSuicide; 173 | set 174 | { 175 | if (@internal._Modifications.CanSuicide == value) 176 | return; 177 | @internal._Modifications.CanSuicide = value; 178 | @internal._Modifications.IsDirtyFlag = true; 179 | } 180 | } 181 | public float MinimumDamageToStartBleeding 182 | { 183 | get => @internal._Modifications.MinDamageToStartBleeding; 184 | set 185 | { 186 | if (@internal._Modifications.MinDamageToStartBleeding == value) 187 | return; 188 | @internal._Modifications.MinDamageToStartBleeding = value; 189 | @internal._Modifications.IsDirtyFlag = true; 190 | } 191 | } 192 | public float MinimumHpToStartBleeding 193 | { 194 | get => @internal._Modifications.MinHpToStartBleeding; 195 | set 196 | { 197 | if (@internal._Modifications.MinHpToStartBleeding == value) 198 | return; 199 | @internal._Modifications.MinHpToStartBleeding = value; 200 | @internal._Modifications.IsDirtyFlag = true; 201 | } 202 | } 203 | public float HpPerBandage 204 | { 205 | get => @internal._Modifications.HPperBandage; 206 | set 207 | { 208 | if (value >= 100f) 209 | value = 100f; 210 | else if (value < 0) 211 | value = 0f; 212 | 213 | if (@internal._Modifications.HPperBandage == value) 214 | return; 215 | @internal._Modifications.HPperBandage = value; 216 | @internal._Modifications.IsDirtyFlag = true; 217 | } 218 | } 219 | public bool StaminaEnabled 220 | { 221 | get => @internal._Modifications.StaminaEnabled; 222 | set 223 | { 224 | if (@internal._Modifications.StaminaEnabled == value) 225 | return; 226 | @internal._Modifications.StaminaEnabled = value; 227 | @internal._Modifications.IsDirtyFlag = true; 228 | } 229 | } 230 | public bool HitMarkersEnabled 231 | { 232 | get => @internal._Modifications.HitMarkersEnabled; 233 | set 234 | { 235 | if (@internal._Modifications.HitMarkersEnabled == value) 236 | return; 237 | @internal._Modifications.HitMarkersEnabled = value; 238 | @internal._Modifications.IsDirtyFlag = true; 239 | } 240 | } 241 | public bool FriendlyHUDEnabled 242 | { 243 | get => @internal._Modifications.FriendlyHUDEnabled; 244 | set 245 | { 246 | if (@internal._Modifications.FriendlyHUDEnabled == value) 247 | return; 248 | @internal._Modifications.FriendlyHUDEnabled = value; 249 | @internal._Modifications.IsDirtyFlag = true; 250 | } 251 | } 252 | public float CaptureFlagSpeedMultiplier 253 | { 254 | get => @internal._Modifications.CaptureFlagSpeedMultiplier; 255 | set 256 | { 257 | if (@internal._Modifications.CaptureFlagSpeedMultiplier == value) 258 | return; 259 | @internal._Modifications.CaptureFlagSpeedMultiplier = value; 260 | @internal._Modifications.IsDirtyFlag = true; 261 | } 262 | } 263 | public bool PointLogHudEnabled 264 | { 265 | get => @internal._Modifications.PointLogHudEnabled; 266 | set 267 | { 268 | if (@internal._Modifications.PointLogHudEnabled == value) 269 | return; 270 | @internal._Modifications.PointLogHudEnabled = value; 271 | @internal._Modifications.IsDirtyFlag = true; 272 | } 273 | } 274 | public bool KillFeed 275 | { 276 | get => @internal._Modifications.KillFeed; 277 | set 278 | { 279 | if (@internal._Modifications.KillFeed == value) 280 | return; 281 | @internal._Modifications.KillFeed = value; 282 | @internal._Modifications.IsDirtyFlag = true; 283 | } 284 | } 285 | public bool IsExposedOnMap 286 | { 287 | get => @internal._Modifications.IsExposedOnMap; 288 | set 289 | { 290 | if (@internal._Modifications.IsExposedOnMap == value) 291 | return; 292 | @internal._Modifications.IsExposedOnMap = value; 293 | @internal._Modifications.IsDirtyFlag = true; 294 | } 295 | } 296 | public SpawningRule SpawningRule 297 | { 298 | get => @internal._Modifications.SpawningRule; 299 | set 300 | { 301 | if (@internal._Modifications.SpawningRule == value) 302 | return; 303 | @internal._Modifications.SpawningRule = value; 304 | @internal._Modifications.IsDirtyFlag = true; 305 | } 306 | } 307 | public VehicleType AllowedVehicles 308 | { 309 | get => @internal._Modifications.AllowedVehicles; 310 | set 311 | { 312 | if (@internal._Modifications.AllowedVehicles == value) 313 | return; 314 | @internal._Modifications.AllowedVehicles = value; 315 | @internal._Modifications.IsDirtyFlag = true; 316 | } 317 | } 318 | public bool Freeze 319 | { 320 | get => @internal._Modifications.Freeze; 321 | set 322 | { 323 | if (@internal._Modifications.Freeze == value) 324 | return; 325 | @internal._Modifications.Freeze = value; 326 | @internal._Modifications.IsDirtyFlag = true; 327 | } 328 | } 329 | public float ReviveHP 330 | { 331 | get => @internal._Modifications.ReviveHP; 332 | set 333 | { 334 | if (@internal._Modifications.ReviveHP == value) 335 | return; 336 | @internal._Modifications.ReviveHP = value; 337 | @internal._Modifications.IsDirtyFlag = true; 338 | } 339 | } 340 | public bool HideOnMap 341 | { 342 | get => @internal._Modifications.HideOnMap; 343 | set 344 | { 345 | if (@internal._Modifications.HideOnMap == value) 346 | return; 347 | @internal._Modifications.HideOnMap = value; 348 | @internal._Modifications.IsDirtyFlag = true; 349 | } 350 | } 351 | 352 | public void DisableBleeding() 353 | { 354 | this.MinimumDamageToStartBleeding = 100f; 355 | this.MinimumHpToStartBleeding = 0f; 356 | } 357 | public void EnableBleeding(float minimumHP = 40f, float minimumDamage = 10f) 358 | { 359 | this.MinimumDamageToStartBleeding = minimumDamage; 360 | this.MinimumHpToStartBleeding = minimumHP; 361 | } 362 | 363 | // ---- Classes ---- 364 | public class mPlayerModifications 365 | { 366 | public float RunningSpeedMultiplier = 1f; 367 | public float ReceiveDamageMultiplier = 1f; 368 | public float GiveDamageMultiplier = 1f; 369 | public float JumpHeightMultiplier = 1f; 370 | public float FallDamageMultiplier = 1f; 371 | public float ReloadSpeedMultiplier = 1f; 372 | public bool CanUseNightVision = true; 373 | public float DownTimeGiveUpTime = 60f; 374 | public bool AirStrafe = true; 375 | public bool CanDeploy = true; 376 | public bool CanSpectate = true; 377 | public bool IsTextChatMuted = false; 378 | public bool IsVoiceChatMuted = false; 379 | public float RespawnTime = 10f; 380 | public bool CanSuicide = true; 381 | public float MinDamageToStartBleeding = 10f; 382 | public float MinHpToStartBleeding = 40f; 383 | public float HPperBandage = 50f; 384 | public bool StaminaEnabled = false; 385 | public bool HitMarkersEnabled = true; 386 | public bool FriendlyHUDEnabled = true; 387 | public float CaptureFlagSpeedMultiplier = 1f; 388 | public bool PointLogHudEnabled = true; 389 | public bool KillFeed = false; 390 | public bool IsExposedOnMap = false; 391 | public SpawningRule SpawningRule; 392 | public VehicleType AllowedVehicles; 393 | public bool Freeze = false; 394 | public float ReviveHP = 35f; 395 | public bool HideOnMap = false; 396 | 397 | public bool IsDirtyFlag = false; 398 | public void Write(BattleBitAPI.Common.Serialization.Stream ser) 399 | { 400 | ser.Write(this.RunningSpeedMultiplier); 401 | ser.Write(this.ReceiveDamageMultiplier); 402 | ser.Write(this.GiveDamageMultiplier); 403 | ser.Write(this.JumpHeightMultiplier); 404 | ser.Write(this.FallDamageMultiplier); 405 | ser.Write(this.ReloadSpeedMultiplier); 406 | ser.Write(this.CanUseNightVision); 407 | ser.Write(this.DownTimeGiveUpTime); 408 | ser.Write(this.AirStrafe); 409 | ser.Write(this.CanDeploy); 410 | ser.Write(this.CanSpectate); 411 | ser.Write(this.IsTextChatMuted); 412 | ser.Write(this.IsVoiceChatMuted); 413 | ser.Write(this.RespawnTime); 414 | ser.Write(this.CanSuicide); 415 | 416 | ser.Write(this.MinDamageToStartBleeding); 417 | ser.Write(this.MinHpToStartBleeding); 418 | ser.Write(this.HPperBandage); 419 | ser.Write(this.StaminaEnabled); 420 | ser.Write(this.HitMarkersEnabled); 421 | ser.Write(this.FriendlyHUDEnabled); 422 | ser.Write(this.CaptureFlagSpeedMultiplier); 423 | ser.Write(this.PointLogHudEnabled); 424 | ser.Write(this.KillFeed); 425 | ser.Write(this.IsExposedOnMap); 426 | ser.Write((ulong)this.SpawningRule); 427 | ser.Write((byte)this.AllowedVehicles); 428 | ser.Write(this.Freeze); 429 | ser.Write(this.ReviveHP); 430 | ser.Write(this.HideOnMap); 431 | } 432 | public void Read(BattleBitAPI.Common.Serialization.Stream ser) 433 | { 434 | this.RunningSpeedMultiplier = ser.ReadFloat(); 435 | if (this.RunningSpeedMultiplier <= 0f) 436 | this.RunningSpeedMultiplier = 0.01f; 437 | 438 | this.ReceiveDamageMultiplier = ser.ReadFloat(); 439 | this.GiveDamageMultiplier = ser.ReadFloat(); 440 | this.JumpHeightMultiplier = ser.ReadFloat(); 441 | this.FallDamageMultiplier = ser.ReadFloat(); 442 | this.ReloadSpeedMultiplier = ser.ReadFloat(); 443 | this.CanUseNightVision = ser.ReadBool(); 444 | this.DownTimeGiveUpTime = ser.ReadFloat(); 445 | this.AirStrafe = ser.ReadBool(); 446 | this.CanDeploy = ser.ReadBool(); 447 | this.CanSpectate = ser.ReadBool(); 448 | this.IsTextChatMuted = ser.ReadBool(); 449 | this.IsVoiceChatMuted = ser.ReadBool(); 450 | this.RespawnTime = ser.ReadFloat(); 451 | this.CanSuicide = ser.ReadBool(); 452 | 453 | this.MinDamageToStartBleeding = ser.ReadFloat(); 454 | this.MinHpToStartBleeding = ser.ReadFloat(); 455 | this.HPperBandage = ser.ReadFloat(); 456 | this.StaminaEnabled = ser.ReadBool(); 457 | this.HitMarkersEnabled = ser.ReadBool(); 458 | this.FriendlyHUDEnabled = ser.ReadBool(); 459 | this.CaptureFlagSpeedMultiplier = ser.ReadFloat(); 460 | this.PointLogHudEnabled = ser.ReadBool(); 461 | this.KillFeed = ser.ReadBool(); 462 | this.IsExposedOnMap = ser.ReadBool(); 463 | this.SpawningRule = (SpawningRule)ser.ReadUInt64(); 464 | this.AllowedVehicles = (VehicleType)ser.ReadInt8(); 465 | 466 | this.Freeze = ser.ReadBool(); 467 | this.ReviveHP = ser.ReadFloat(); 468 | this.HideOnMap = ser.ReadBool(); 469 | } 470 | public void Reset() 471 | { 472 | this.RunningSpeedMultiplier = 1f; 473 | this.ReceiveDamageMultiplier = 1f; 474 | this.GiveDamageMultiplier = 1f; 475 | this.JumpHeightMultiplier = 1f; 476 | this.FallDamageMultiplier = 1f; 477 | this.ReloadSpeedMultiplier = 1f; 478 | this.CanUseNightVision = true; 479 | this.DownTimeGiveUpTime = 60f; 480 | this.AirStrafe = true; 481 | this.CanDeploy = true; 482 | this.CanSpectate = true; 483 | this.IsTextChatMuted = false; 484 | this.IsVoiceChatMuted = false; 485 | this.RespawnTime = 5f; 486 | this.CanSuicide = true; 487 | this.MinDamageToStartBleeding = 10f; 488 | this.MinHpToStartBleeding = 40f; 489 | this.HPperBandage = 50f; 490 | this.StaminaEnabled = false; 491 | this.HitMarkersEnabled = true; 492 | this.FriendlyHUDEnabled = true; 493 | this.CaptureFlagSpeedMultiplier = 1f; 494 | this.PointLogHudEnabled = true; 495 | this.KillFeed = false; 496 | this.SpawningRule = SpawningRule.All; 497 | this.AllowedVehicles = VehicleType.All; 498 | this.Freeze = false; 499 | this.ReviveHP = 35f; 500 | this.HideOnMap = false; 501 | } 502 | } 503 | } 504 | } 505 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Internal/RoundSettings.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | 3 | namespace BattleBitAPI.Server 4 | { 5 | public class RoundSettings where TPlayer : Player 6 | { 7 | // ---- Construction ---- 8 | private GameServer.Internal mResources; 9 | public RoundSettings(GameServer.Internal resources) 10 | { 11 | mResources = resources; 12 | } 13 | 14 | // ---- Variables ---- 15 | public GameState State 16 | { 17 | get => this.mResources._RoundSettings.State; 18 | } 19 | public double TeamATickets 20 | { 21 | get => this.mResources._RoundSettings.TeamATickets; 22 | set 23 | { 24 | this.mResources._RoundSettings.TeamATickets = value; 25 | this.mResources.IsDirtyRoundSettings = true; 26 | } 27 | } 28 | public double TeamBTickets 29 | { 30 | get => this.mResources._RoundSettings.TeamBTickets; 31 | set 32 | { 33 | this.mResources._RoundSettings.TeamBTickets = value; 34 | this.mResources.IsDirtyRoundSettings = true; 35 | } 36 | } 37 | public double MaxTickets 38 | { 39 | get => this.mResources._RoundSettings.MaxTickets; 40 | set 41 | { 42 | this.mResources._RoundSettings.MaxTickets = value; 43 | this.mResources.IsDirtyRoundSettings = true; 44 | } 45 | } 46 | public int PlayersToStart 47 | { 48 | get => this.mResources._RoundSettings.PlayersToStart; 49 | set 50 | { 51 | this.mResources._RoundSettings.PlayersToStart = value; 52 | this.mResources.IsDirtyRoundSettings = true; 53 | } 54 | } 55 | public int SecondsLeft 56 | { 57 | get => this.mResources._RoundSettings.SecondsLeft; 58 | set 59 | { 60 | this.mResources._RoundSettings.SecondsLeft = value; 61 | this.mResources.IsDirtyRoundSettings = true; 62 | } 63 | } 64 | 65 | // ---- Reset ---- 66 | public void Reset() 67 | { 68 | 69 | } 70 | 71 | // ---- Classes ---- 72 | public class mRoundSettings 73 | { 74 | public const int Size = 1 + 8 + 8 + 8 + 4 + 4; 75 | 76 | public GameState State = GameState.WaitingForPlayers; 77 | public double TeamATickets = 0; 78 | public double TeamBTickets = 0; 79 | public double MaxTickets = 1; 80 | public int PlayersToStart = 16; 81 | public int SecondsLeft = 60; 82 | 83 | public void Write(Common.Serialization.Stream ser) 84 | { 85 | ser.Write((byte)this.State); 86 | ser.Write(this.TeamATickets); 87 | ser.Write(this.TeamBTickets); 88 | ser.Write(this.MaxTickets); 89 | ser.Write(this.PlayersToStart); 90 | ser.Write(this.SecondsLeft); 91 | } 92 | public void Read(Common.Serialization.Stream ser) 93 | { 94 | this.State = (GameState)ser.ReadInt8(); 95 | this.TeamATickets = ser.ReadDouble(); 96 | this.TeamBTickets = ser.ReadDouble(); 97 | this.MaxTickets = ser.ReadDouble(); 98 | this.PlayersToStart = ser.ReadInt32(); 99 | this.SecondsLeft = ser.ReadInt32(); 100 | } 101 | 102 | public void Reset() 103 | { 104 | this.State = GameState.WaitingForPlayers; 105 | this.TeamATickets = 0; 106 | this.TeamBTickets = 0; 107 | this.MaxTickets = 1; 108 | this.PlayersToStart = 16; 109 | this.SecondsLeft = 60; 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Internal/ServerSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.ConstrainedExecution; 2 | 3 | namespace BattleBitAPI.Server 4 | { 5 | public class ServerSettings where TPlayer : Player 6 | { 7 | // ---- Construction ---- 8 | private GameServer.Internal mResources; 9 | public ServerSettings(GameServer.Internal resources) 10 | { 11 | mResources = resources; 12 | } 13 | 14 | // ---- Variables ---- 15 | public float DamageMultiplier 16 | { 17 | get => mResources._RoomSettings.DamageMultiplier; 18 | set 19 | { 20 | if (mResources._RoomSettings.DamageMultiplier == value) 21 | return; 22 | mResources._RoomSettings.DamageMultiplier = value; 23 | mResources.IsDirtyRoomSettings = true; 24 | } 25 | } 26 | public bool FriendlyFireEnabled 27 | { 28 | get => mResources._RoomSettings.FriendlyFireEnabled; 29 | set 30 | { 31 | if (mResources._RoomSettings.FriendlyFireEnabled == value) 32 | return; 33 | mResources._RoomSettings.FriendlyFireEnabled = value; 34 | mResources.IsDirtyRoomSettings = true; 35 | } 36 | } 37 | public bool OnlyWinnerTeamCanVote 38 | { 39 | get => mResources._RoomSettings.OnlyWinnerTeamCanVote; 40 | set 41 | { 42 | if (mResources._RoomSettings.OnlyWinnerTeamCanVote == value) 43 | return; 44 | mResources._RoomSettings.OnlyWinnerTeamCanVote = value; 45 | mResources.IsDirtyRoomSettings = true; 46 | } 47 | } 48 | public bool PlayerCollision 49 | { 50 | get => mResources._RoomSettings.PlayerCollision; 51 | set 52 | { 53 | if (mResources._RoomSettings.PlayerCollision == value) 54 | return; 55 | mResources._RoomSettings.PlayerCollision = value; 56 | mResources.IsDirtyRoomSettings = true; 57 | } 58 | } 59 | public bool HideMapVotes 60 | { 61 | get => mResources._RoomSettings.HideMapVotes; 62 | set 63 | { 64 | if (mResources._RoomSettings.HideMapVotes == value) 65 | return; 66 | mResources._RoomSettings.HideMapVotes = value; 67 | mResources.IsDirtyRoomSettings = true; 68 | } 69 | } 70 | public bool CanVoteDay 71 | { 72 | get => mResources._RoomSettings.CanVoteDay; 73 | set 74 | { 75 | if (mResources._RoomSettings.CanVoteDay == value) 76 | return; 77 | mResources._RoomSettings.CanVoteDay = value; 78 | mResources.IsDirtyRoomSettings = true; 79 | } 80 | } 81 | public bool CanVoteNight 82 | { 83 | get => mResources._RoomSettings.CanVoteNight; 84 | set 85 | { 86 | if (mResources._RoomSettings.CanVoteNight == value) 87 | return; 88 | mResources._RoomSettings.CanVoteNight = value; 89 | mResources.IsDirtyRoomSettings = true; 90 | } 91 | } 92 | 93 | public byte MedicLimitPerSquad 94 | { 95 | get => mResources._RoomSettings.MedicLimitPerSquad; 96 | set 97 | { 98 | if (mResources._RoomSettings.MedicLimitPerSquad == value) 99 | return; 100 | mResources._RoomSettings.MedicLimitPerSquad = value; 101 | mResources.IsDirtyRoomSettings = true; 102 | } 103 | } 104 | public byte EngineerLimitPerSquad 105 | { 106 | get => mResources._RoomSettings.EngineerLimitPerSquad; 107 | set 108 | { 109 | if (mResources._RoomSettings.EngineerLimitPerSquad == value) 110 | return; 111 | mResources._RoomSettings.EngineerLimitPerSquad = value; 112 | mResources.IsDirtyRoomSettings = true; 113 | } 114 | } 115 | public byte SupportLimitPerSquad 116 | { 117 | get => mResources._RoomSettings.SupportLimitPerSquad; 118 | set 119 | { 120 | if (mResources._RoomSettings.SupportLimitPerSquad == value) 121 | return; 122 | mResources._RoomSettings.SupportLimitPerSquad = value; 123 | mResources.IsDirtyRoomSettings = true; 124 | } 125 | } 126 | public byte ReconLimitPerSquad 127 | { 128 | get => mResources._RoomSettings.ReconLimitPerSquad; 129 | set 130 | { 131 | if (mResources._RoomSettings.ReconLimitPerSquad == value) 132 | return; 133 | mResources._RoomSettings.ReconLimitPerSquad = value; 134 | mResources.IsDirtyRoomSettings = true; 135 | } 136 | } 137 | 138 | public float TankSpawnDelayMultipler 139 | { 140 | get => mResources._RoomSettings.TankSpawnDelayMultipler; 141 | set 142 | { 143 | if (mResources._RoomSettings.TankSpawnDelayMultipler == value) 144 | return; 145 | mResources._RoomSettings.TankSpawnDelayMultipler = value; 146 | mResources.IsDirtyRoomSettings = true; 147 | } 148 | } 149 | public float TransportSpawnDelayMultipler 150 | { 151 | get => mResources._RoomSettings.TransportSpawnDelayMultipler; 152 | set 153 | { 154 | if (mResources._RoomSettings.TransportSpawnDelayMultipler == value) 155 | return; 156 | mResources._RoomSettings.TransportSpawnDelayMultipler = value; 157 | mResources.IsDirtyRoomSettings = true; 158 | } 159 | } 160 | public float SeaVehicleSpawnDelayMultipler 161 | { 162 | get => mResources._RoomSettings.SeaVehicleSpawnDelayMultipler; 163 | set 164 | { 165 | if (mResources._RoomSettings.SeaVehicleSpawnDelayMultipler == value) 166 | return; 167 | mResources._RoomSettings.SeaVehicleSpawnDelayMultipler = value; 168 | mResources.IsDirtyRoomSettings = true; 169 | } 170 | } 171 | public float APCSpawnDelayMultipler 172 | { 173 | get => mResources._RoomSettings.APCSpawnDelayMultipler; 174 | set 175 | { 176 | if (mResources._RoomSettings.APCSpawnDelayMultipler == value) 177 | return; 178 | mResources._RoomSettings.APCSpawnDelayMultipler = value; 179 | mResources.IsDirtyRoomSettings = true; 180 | } 181 | } 182 | public float HelicopterSpawnDelayMultipler 183 | { 184 | get => mResources._RoomSettings.HelicopterSpawnDelayMultipler; 185 | set 186 | { 187 | if (mResources._RoomSettings.HelicopterSpawnDelayMultipler == value) 188 | return; 189 | mResources._RoomSettings.HelicopterSpawnDelayMultipler = value; 190 | mResources.IsDirtyRoomSettings = true; 191 | } 192 | } 193 | 194 | public bool UnlockAllAttachments 195 | { 196 | get => mResources._RoomSettings.UnlockAllAttachments; 197 | set 198 | { 199 | if (mResources._RoomSettings.UnlockAllAttachments == value) 200 | return; 201 | mResources._RoomSettings.UnlockAllAttachments = value; 202 | mResources.IsDirtyRoomSettings = true; 203 | } 204 | } 205 | public bool TeamlessMode 206 | { 207 | get => mResources._RoomSettings.TeamlessMode; 208 | set 209 | { 210 | if (mResources._RoomSettings.TeamlessMode == value) 211 | return; 212 | mResources._RoomSettings.TeamlessMode = value; 213 | mResources.IsDirtyRoomSettings = true; 214 | } 215 | } 216 | public bool SquadRequiredToChangeRole 217 | { 218 | get => mResources._RoomSettings.SquadRequiredToChangeRole; 219 | set 220 | { 221 | if (mResources._RoomSettings.SquadRequiredToChangeRole == value) 222 | return; 223 | mResources._RoomSettings.SquadRequiredToChangeRole = value; 224 | mResources.IsDirtyRoomSettings = true; 225 | } 226 | } 227 | 228 | // ---- Reset ---- 229 | public void Reset() 230 | { 231 | 232 | } 233 | 234 | // ---- Classes ---- 235 | public class mRoomSettings 236 | { 237 | public float DamageMultiplier = 1.0f; 238 | public bool FriendlyFireEnabled = false; 239 | public bool HideMapVotes = true; 240 | public bool OnlyWinnerTeamCanVote = false; 241 | public bool PlayerCollision = false; 242 | 243 | public byte MedicLimitPerSquad = 8; 244 | public byte EngineerLimitPerSquad = 8; 245 | public byte SupportLimitPerSquad = 8; 246 | public byte ReconLimitPerSquad = 8; 247 | 248 | public bool CanVoteDay = true; 249 | public bool CanVoteNight = true; 250 | 251 | public float TankSpawnDelayMultipler = 1.0f; 252 | public float TransportSpawnDelayMultipler = 1.0f; 253 | public float SeaVehicleSpawnDelayMultipler = 1.0f; 254 | public float APCSpawnDelayMultipler = 1.0f; 255 | public float HelicopterSpawnDelayMultipler = 1.0f; 256 | 257 | public bool UnlockAllAttachments = false; 258 | public bool TeamlessMode = false; 259 | public bool SquadRequiredToChangeRole = true; 260 | 261 | public void Write(Common.Serialization.Stream ser) 262 | { 263 | ser.Write(this.DamageMultiplier); 264 | ser.Write(this.FriendlyFireEnabled); 265 | ser.Write(this.HideMapVotes); 266 | ser.Write(this.OnlyWinnerTeamCanVote); 267 | ser.Write(this.PlayerCollision); 268 | 269 | ser.Write(this.MedicLimitPerSquad); 270 | ser.Write(this.EngineerLimitPerSquad); 271 | ser.Write(this.SupportLimitPerSquad); 272 | ser.Write(this.ReconLimitPerSquad); 273 | 274 | ser.Write(this.CanVoteDay); 275 | ser.Write(this.CanVoteNight); 276 | 277 | ser.Write(this.TankSpawnDelayMultipler); 278 | ser.Write(this.TransportSpawnDelayMultipler); 279 | ser.Write(this.SeaVehicleSpawnDelayMultipler); 280 | ser.Write(this.APCSpawnDelayMultipler); 281 | ser.Write(this.HelicopterSpawnDelayMultipler); 282 | 283 | ser.Write(this.UnlockAllAttachments); 284 | ser.Write(this.TeamlessMode); 285 | ser.Write(this.SquadRequiredToChangeRole); 286 | } 287 | public void Read(Common.Serialization.Stream ser) 288 | { 289 | this.DamageMultiplier = ser.ReadFloat(); 290 | this.FriendlyFireEnabled = ser.ReadBool(); 291 | this.HideMapVotes = ser.ReadBool(); 292 | this.OnlyWinnerTeamCanVote = ser.ReadBool(); 293 | this.PlayerCollision=ser.ReadBool(); 294 | 295 | this.MedicLimitPerSquad = ser.ReadInt8(); 296 | this.EngineerLimitPerSquad = ser.ReadInt8(); 297 | this.SupportLimitPerSquad = ser.ReadInt8(); 298 | this.ReconLimitPerSquad = ser.ReadInt8(); 299 | 300 | this.CanVoteDay = ser.ReadBool(); 301 | this.CanVoteNight = ser.ReadBool(); 302 | 303 | this.TankSpawnDelayMultipler = ser.ReadFloat(); 304 | this.TransportSpawnDelayMultipler = ser.ReadFloat(); 305 | this.SeaVehicleSpawnDelayMultipler = ser.ReadFloat(); 306 | this.APCSpawnDelayMultipler = ser.ReadFloat(); 307 | this.HelicopterSpawnDelayMultipler = ser.ReadFloat(); 308 | 309 | this.UnlockAllAttachments = ser.ReadBool(); 310 | this.TeamlessMode = ser.ReadBool(); 311 | this.SquadRequiredToChangeRole = ser.ReadBool(); 312 | } 313 | public void Reset() 314 | { 315 | this.DamageMultiplier = 1.0f; 316 | this.FriendlyFireEnabled = false; 317 | this.HideMapVotes = true; 318 | this.OnlyWinnerTeamCanVote = false; 319 | this.PlayerCollision = false; 320 | 321 | this.MedicLimitPerSquad = 8; 322 | this.EngineerLimitPerSquad = 8; 323 | this.SupportLimitPerSquad = 8; 324 | this.ReconLimitPerSquad = 8; 325 | 326 | this.CanVoteDay = true; 327 | this.CanVoteNight = true; 328 | 329 | this.TankSpawnDelayMultipler = 1.0f; 330 | this.TransportSpawnDelayMultipler = 1.0f; 331 | this.SeaVehicleSpawnDelayMultipler = 1.0f; 332 | this.APCSpawnDelayMultipler = 1.0f; 333 | this.HelicopterSpawnDelayMultipler = 1.0f; 334 | 335 | this.UnlockAllAttachments = false; 336 | this.TeamlessMode = false; 337 | this.SquadRequiredToChangeRole = true; 338 | } 339 | } 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Internal/Squad.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | 3 | namespace BattleBitAPI.Server 4 | { 5 | public class Squad where TPlayer : Player 6 | { 7 | public Team Team => @internal.Team; 8 | public Squads Name => @internal.Name; 9 | public GameServer Server => @internal.Server; 10 | public int NumberOfMembers => @internal.Members.Count; 11 | public bool IsEmpty => NumberOfMembers == 0; 12 | public IEnumerable Members => @internal.Server.IterateMembersOf(this); 13 | public int SquadPoints 14 | { 15 | get => @internal.SquadPoints; 16 | 17 | set 18 | { 19 | @internal.SquadPoints = value; 20 | Server.SetSquadPointsOf(@internal.Team, @internal.Name, value); 21 | } 22 | } 23 | public TPlayer Leader 24 | { 25 | get 26 | { 27 | if (this.@internal.SquadLeader != 0 && this.Server.TryGetPlayer(this.@internal.SquadLeader, out var captain)) 28 | return captain; 29 | return null; 30 | } 31 | set 32 | { 33 | if (value != null) 34 | { 35 | if (!value.IsSquadLeader) 36 | value.PromoteToSquadLeader(); 37 | } 38 | } 39 | } 40 | 41 | private Internal @internal; 42 | public Squad(Internal @internal) 43 | { 44 | this.@internal = @internal; 45 | } 46 | 47 | public void DisbandSquad() 48 | { 49 | var leader = this.Leader; 50 | if (leader != null) 51 | leader.DisbandTheSquad(); 52 | } 53 | 54 | public override string ToString() 55 | { 56 | return "Squad " + Name; 57 | } 58 | 59 | // ---- Internal ---- 60 | public class Internal 61 | { 62 | public readonly Team Team; 63 | public readonly Squads Name; 64 | public int SquadPoints; 65 | public GameServer Server; 66 | public HashSet Members; 67 | public ulong SquadLeader; 68 | 69 | public Internal(GameServer server, Team team, Squads squads) 70 | { 71 | this.Team = team; 72 | this.Name = squads; 73 | this.Server = server; 74 | this.Members = new HashSet(8); 75 | this.SquadLeader = 0; 76 | } 77 | 78 | public void Reset() 79 | { 80 | 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /BattleBitAPI/Server/Player.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | using BattleBitAPI.Server; 3 | using System.Net; 4 | using System.Numerics; 5 | 6 | namespace BattleBitAPI 7 | { 8 | public class Player where TPlayer : Player 9 | { 10 | private Internal mInternal; 11 | 12 | // ---- Variables ---- 13 | public ulong SteamID => mInternal.SteamID; 14 | public string Name => mInternal.Name; 15 | public IPAddress IP => mInternal.IP; 16 | public GameServer GameServer => mInternal.GameServer; 17 | public GameRole Role 18 | { 19 | get => mInternal.Role; 20 | set 21 | { 22 | if (value == mInternal.Role) 23 | return; 24 | SetNewRole(value); 25 | } 26 | } 27 | public Team Team 28 | { 29 | get => mInternal.Team; 30 | set 31 | { 32 | if (mInternal.Team != value) 33 | ChangeTeam(value); 34 | } 35 | } 36 | public Squads SquadName 37 | { 38 | get => mInternal.SquadName; 39 | set 40 | { 41 | if (value == mInternal.SquadName) 42 | return; 43 | if (value == Squads.NoSquad) 44 | KickFromSquad(); 45 | else 46 | JoinSquad(value); 47 | } 48 | } 49 | public Squad Squad 50 | { 51 | get => GameServer.GetSquad(mInternal.Team, mInternal.SquadName); 52 | set 53 | { 54 | if (value == Squad) 55 | return; 56 | 57 | if (value == null) 58 | KickFromSquad(); 59 | else 60 | { 61 | if (value.Team != this.Team) 62 | ChangeTeam(value.Team); 63 | JoinSquad(value.Name); 64 | } 65 | } 66 | } 67 | public bool InSquad => mInternal.SquadName != Squads.NoSquad; 68 | public int PingMs => mInternal.PingMs; 69 | public long CurrentSessionID => mInternal.SessionID; 70 | public bool IsSquadLeader 71 | { 72 | get 73 | { 74 | if (this.SquadName != Squads.NoSquad) 75 | { 76 | var squad = this.Squad; 77 | return squad.Leader == this; 78 | } 79 | return false; 80 | } 81 | } 82 | public bool IsConnected => mInternal.SessionID != 0; 83 | 84 | public float HP 85 | { 86 | get => mInternal.HP; 87 | set 88 | { 89 | if (mInternal.HP > 0) 90 | { 91 | float v = value; 92 | if (v <= 0) 93 | v = 0.1f; 94 | else if (v > 100f) 95 | v = 100f; 96 | 97 | SetHP(v); 98 | } 99 | } 100 | } 101 | public bool IsAlive => mInternal.HP >= 0f; 102 | public bool IsUp => mInternal.HP > 0f; 103 | public bool IsDown => mInternal.HP == 0f; 104 | public bool IsDead => mInternal.HP == -1f; 105 | 106 | public Vector3 Position 107 | { 108 | get => mInternal.Position; 109 | set => Teleport(value); 110 | } 111 | public PlayerStand StandingState => mInternal.Standing; 112 | public LeaningSide LeaningState => mInternal.Leaning; 113 | public LoadoutIndex CurrentLoadoutIndex => mInternal.CurrentLoadoutIndex; 114 | public bool InVehicle => mInternal.InVehicle; 115 | public bool IsBleeding => mInternal.IsBleeding; 116 | public PlayerLoadout CurrentLoadout => mInternal.CurrentLoadout; 117 | public PlayerWearings CurrentWearings => mInternal.CurrentWearings; 118 | public PlayerModifications Modifications => mInternal.Modifications; 119 | 120 | // ---- Events ---- 121 | public virtual void OnCreated() 122 | { 123 | 124 | } 125 | 126 | public virtual async Task OnConnected() 127 | { 128 | 129 | } 130 | public virtual async Task OnSpawned() 131 | { 132 | 133 | } 134 | public virtual async Task OnDowned() 135 | { 136 | 137 | } 138 | public virtual async Task OnGivenUp() 139 | { 140 | 141 | } 142 | public virtual async Task OnRevivedByAnotherPlayer() 143 | { 144 | 145 | } 146 | public virtual async Task OnRevivedAnotherPlayer() 147 | { 148 | 149 | } 150 | public virtual async Task OnDied() 151 | { 152 | 153 | } 154 | public virtual async Task OnChangedTeam() 155 | { 156 | 157 | } 158 | public virtual async Task OnChangedRole(GameRole newRole) 159 | { 160 | 161 | } 162 | public virtual async Task OnJoinedSquad(Squad newSquad) 163 | { 164 | 165 | } 166 | public virtual async Task OnPlayerPromotedToSquadLeader() 167 | { 168 | 169 | } 170 | public virtual async Task OnLeftSquad(Squad oldSquad) 171 | { 172 | 173 | } 174 | public virtual async Task OnDisconnected() 175 | { 176 | 177 | } 178 | public virtual async Task OnSessionChanged(long oldSessionID, long newSessionID) 179 | { 180 | 181 | } 182 | 183 | // ---- Functions ---- 184 | public void Kick(string reason = "") 185 | { 186 | if (IsConnected) 187 | GameServer.Kick(this, reason); 188 | } 189 | public void Kill() 190 | { 191 | if (IsConnected) 192 | GameServer.Kill(this); 193 | } 194 | public void ChangeTeam() 195 | { 196 | if (IsConnected) 197 | GameServer.ChangeTeam(this); 198 | } 199 | public void ChangeTeam(Team team) 200 | { 201 | if (IsConnected) 202 | GameServer.ChangeTeam(this, team); 203 | } 204 | public void KickFromSquad() 205 | { 206 | if (IsConnected) 207 | GameServer.KickFromSquad(this); 208 | } 209 | public void JoinSquad(Squads targetSquad) 210 | { 211 | if (IsConnected) 212 | GameServer.JoinSquad(this, targetSquad); 213 | } 214 | public void DisbandTheSquad() 215 | { 216 | if (IsConnected) 217 | GameServer.DisbandPlayerCurrentSquad(this); 218 | } 219 | public void PromoteToSquadLeader() 220 | { 221 | if (IsConnected) 222 | GameServer.PromoteSquadLeader(this); 223 | } 224 | public void WarnPlayer(string msg) 225 | { 226 | if (IsConnected) 227 | GameServer.WarnPlayer(this, msg); 228 | } 229 | public void Message(string msg) 230 | { 231 | if (IsConnected) 232 | GameServer.MessageToPlayer(this, msg); 233 | } 234 | public void SayToChat(string msg) 235 | { 236 | if (IsConnected) 237 | GameServer.SayToChat(msg, this); 238 | } 239 | 240 | public void Message(string msg, float fadeoutTime) 241 | { 242 | if (IsConnected) 243 | GameServer.MessageToPlayer(this, msg, fadeoutTime); 244 | } 245 | public void SetNewRole(GameRole role) 246 | { 247 | if (IsConnected) 248 | GameServer.SetRoleTo(this, role); 249 | } 250 | public void Teleport(Vector3 target) 251 | { 252 | GameServer.Teleport(this, target); 253 | } 254 | public void SpawnPlayer(PlayerLoadout loadout, PlayerWearings wearings, Vector3 position, Vector3 lookDirection, PlayerStand stand, float spawnProtection) 255 | { 256 | if (IsConnected) 257 | GameServer.SpawnPlayer(this, loadout, wearings, position, lookDirection, stand, spawnProtection); 258 | } 259 | public void SetHP(float newHP) 260 | { 261 | if (IsConnected) 262 | GameServer.SetHP(this, newHP); 263 | } 264 | public void GiveDamage(float damage) 265 | { 266 | if (IsConnected) 267 | GameServer.GiveDamage(this, damage); 268 | } 269 | public void Heal(float hp) 270 | { 271 | if (IsConnected) 272 | GameServer.Heal(this, hp); 273 | } 274 | public void SetPrimaryWeapon(WeaponItem item, int extraMagazines, bool clear = false) 275 | { 276 | if (IsConnected) 277 | GameServer.SetPrimaryWeapon(this, item, extraMagazines, clear); 278 | } 279 | public void SetSecondaryWeapon(WeaponItem item, int extraMagazines, bool clear = false) 280 | { 281 | if (IsConnected) 282 | GameServer.SetSecondaryWeapon(this, item, extraMagazines, clear); 283 | } 284 | public void SetFirstAidGadget(string item, int extra, bool clear = false) 285 | { 286 | if (IsConnected) 287 | GameServer.SetFirstAid(this, item, extra, clear); 288 | } 289 | public void SetLightGadget(string item, int extra, bool clear = false) 290 | { 291 | if (IsConnected) 292 | GameServer.SetLightGadget(this, item, extra, clear); 293 | } 294 | public void SetHeavyGadget(string item, int extra, bool clear = false) 295 | { 296 | if (IsConnected) 297 | GameServer.SetHeavyGadget(this, item, extra, clear); 298 | } 299 | public void SetThrowable(string item, int extra, bool clear = false) 300 | { 301 | if (IsConnected) 302 | GameServer.SetThrowable(this, item, extra, clear); 303 | } 304 | 305 | // ---- Static ---- 306 | internal static void SetInstance(TPlayer player, Player.Internal @internal) 307 | { 308 | player.mInternal = @internal; 309 | } 310 | 311 | // ---- Overrides ---- 312 | public override string ToString() 313 | { 314 | return Name + " (" + SteamID + ")"; 315 | } 316 | 317 | // ---- Internal ---- 318 | public class Internal 319 | { 320 | public ulong SteamID; 321 | public string Name; 322 | public IPAddress IP; 323 | public GameServer GameServer; 324 | public GameRole Role; 325 | public Team Team; 326 | public Squads SquadName; 327 | public int PingMs = 999; 328 | public long PreviousSessionID = 0; 329 | public long SessionID = 0; 330 | 331 | public bool IsAlive; 332 | public float HP; 333 | public Vector3 Position; 334 | public PlayerStand Standing; 335 | public LeaningSide Leaning; 336 | public LoadoutIndex CurrentLoadoutIndex; 337 | public bool InVehicle; 338 | public bool IsBleeding; 339 | public PlayerLoadout CurrentLoadout; 340 | public PlayerWearings CurrentWearings; 341 | 342 | public PlayerModifications.mPlayerModifications _Modifications; 343 | public PlayerModifications Modifications; 344 | 345 | public Internal() 346 | { 347 | this._Modifications = new PlayerModifications.mPlayerModifications(); 348 | this.Modifications = new PlayerModifications(this); 349 | } 350 | 351 | public void OnDie() 352 | { 353 | IsAlive = false; 354 | HP = -1f; 355 | Position = default; 356 | Standing = PlayerStand.Standing; 357 | Leaning = LeaningSide.None; 358 | CurrentLoadoutIndex = LoadoutIndex.Primary; 359 | InVehicle = false; 360 | IsBleeding = false; 361 | CurrentLoadout = new PlayerLoadout(); 362 | CurrentWearings = new PlayerWearings(); 363 | } 364 | } 365 | } 366 | } 367 | -------------------------------------------------------------------------------- /BattleBitAPI/Storage/DiskStorage.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | 3 | namespace BattleBitAPI.Storage 4 | { 5 | public class DiskStorage : IPlayerStatsDatabase 6 | { 7 | private string mDirectory; 8 | public DiskStorage(string directory) 9 | { 10 | var info = new DirectoryInfo(directory); 11 | if (!info.Exists) 12 | info.Create(); 13 | 14 | this.mDirectory = info.FullName + Path.DirectorySeparatorChar; 15 | } 16 | 17 | public async Task GetPlayerStatsOf(ulong steamID) 18 | { 19 | var file = this.mDirectory + steamID + ".data"; 20 | if (File.Exists(file)) 21 | { 22 | try 23 | { 24 | var data = await File.ReadAllBytesAsync(file); 25 | return new PlayerStats(data); 26 | } 27 | catch { } 28 | } 29 | return null; 30 | } 31 | public async Task SavePlayerStatsOf(ulong steamID, PlayerStats stats) 32 | { 33 | var file = this.mDirectory + steamID + ".data"; 34 | try 35 | { 36 | await File.WriteAllBytesAsync(file, stats.SerializeToByteArray()); 37 | } 38 | catch { } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /BattleBitAPI/Storage/IPlayerStatsDatabase.cs: -------------------------------------------------------------------------------- 1 | using BattleBitAPI.Common; 2 | 3 | namespace BattleBitAPI.Storage 4 | { 5 | public interface IPlayerStatsDatabase 6 | { 7 | public Task GetPlayerStatsOf(ulong steamID); 8 | public Task SavePlayerStatsOf(ulong steamID, PlayerStats stats); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CommunityServerAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Library 5 | net6.0 6 | enable 7 | disable 8 | True 9 | True 10 | BattleBitRemastered.CommunityAPI.Core 11 | SgtOkiDoki 12 | OkigamesLimited 13 | BattleBit Remastered 14 | API to customize game servers for BattleBit Remastered. 15 | 16 | MIT 17 | README.md 18 | https://github.com/MrOkiDoki/BattleBit-Community-Server-API 19 | https://github.com/MrOkiDoki/BattleBit-Community-Server-API 20 | BattleBit 21 | 1.0.8.1 22 | 23 | 24 | 25 | 26 | True 27 | \ 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /CommunityServerAPI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33205.214 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityServerAPI", "CommunityServerAPI.csproj", "{787887A1-8AEE-43E4-AF9B-A3883DE04486}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BattleBitAPI.Program", "..\BattleBitAPI.Program\BattleBitAPI.Program.csproj", "{96D55E1B-2711-47E2-9DA1-41B645F4FCF2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {107CE7B8-8DB9-4467-AF24-1F22E52469E5} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This is a multi-stage Dockerfile, in this case it means that 2 | # we use a "heavy" SDK image with all compiler tools to build the application, but 3 | # then only use the runtime and generated binaries when actually running the app. 4 | # This allows us to make the resulting image much smaller in size. 5 | 6 | # We start off by using the SDK to build the application 7 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build 8 | WORKDIR /src 9 | 10 | # We first copy ONLY the project definition file, instead of all files at once. 11 | # This prevents us from having to restore all dependencies (slow) every time 12 | # we build, since every step in the Dockerfile build process is reusable. So 13 | # if only our code changes, but our project file (incl. dependencies) does not, 14 | # we can skip these two steps before recompiling, saving us quite some time. 15 | COPY ["CommunityServerAPI.csproj", "./"] 16 | RUN dotnet restore "CommunityServerAPI.csproj" 17 | 18 | # Now we can copy all source files (except those listed in `.dockerignore`) 19 | # and build the application 20 | COPY [".", "./"] 21 | RUN dotnet build "CommunityServerAPI.csproj" --no-restore -c Release -o /app 22 | 23 | 24 | ########## 25 | # The next step is to take the built/compiled source code and package it 26 | # into a single "publishable" binary 27 | FROM build as publish 28 | RUN dotnet publish "CommunityServerAPI.csproj" -c Release -o /app 29 | 30 | ######### 31 | # Then, we start over with a completely new environment 32 | # that just contains the .NET runtime. Here, we copy over the 33 | # built and packaged binary files from the other environment to be able to run it. 34 | FROM mcr.microsoft.com/dotnet/runtime:6.0 AS final 35 | WORKDIR /app 36 | 37 | # We expose port 29294 as the default port on which our app runs. 38 | EXPOSE 29294 39 | 40 | COPY --from=publish /app . 41 | 42 | # Set the default action when the container is started, which in this case runs the API. 43 | ENTRYPOINT [ "dotnet", "CommunityServerAPI.dll" ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 MrOkiDoki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-esES.md: -------------------------------------------------------------------------------- 1 | # BattleBit Remastered Community Server API 2 | 3 | [![Licencia: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Language [English](/README.md) | [Русский](/README-ruRU.md) | [中文](/README-zhCN.md) | [한국어](/README-koKR.md) | Español | [Português](/README-ptBR.md) 6 | 7 | Este repositorio proporciona una API que puede ser usada para manejar eventos en tu servidor de comunidad y manipularlos. 8 | 9 | ## Primeros pasos 10 | 11 | ### Preequisitos 12 | 13 | - Tu proprio servidor de BattleBit Remastered con la progresión **deshabilitada** y acceso a los parámetros de lanzamiento. 14 | - Poder escribir y compilar [.NET 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) en C#. 15 | - (para entorno de producción) Un espacio donde alojar esta API 16 | 17 | ### Información 18 | 19 | La documentación y algunos ejemplos se pueden encontrar en la [wiki](https://github.com/MrOkiDoki/BattleBit-Community-Server-API/wiki) (WIP). 20 | 21 | La manera de utilizar esta API es instanciando una clase `ServerListener` (y ejecutándola) a la cual le pasas tus *propias* subclases de `Player` y `GameServer`. En esas subclases, puedes hacer tus propias modificaciones a los métodos que ya existen en `Player` y `GameServer`. Tambien puedes añadir tus propios atributos y métodos. 22 | 23 | La manera más fácil de empezar, es usando el archivo proporcionado `Program.cs` y agregar tus propias modificaciones. dentro de `MyPlayer` y `MyGameServer`. 24 | 25 | ### Compilación 26 | 27 | El proyecto se puede compilar tanto usando el comando [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) en una línea de comandos o usando las opciones de compilar dentro de tu IDE preferido. 28 | 29 | Alternativamente, puedes usar docker para ejecutarlo. Una forma fácil de hacer eso es ejecutar el comando `docker compose up`. 30 | 31 | ### Conectando al servidor(es) 32 | 33 | Después de programar y compilar el proyecto, necesitarás un sitio donde alojarlo. Esto se podría hacer en el mismo sitio que el servidor del juego donde la latencia sería mínima, o en cualquier lugar completamente diferente. Es recomendable mantener la latencia entre el servidor y la API lo más baja posible para favorecer el rendimiento. Un mismo `ServerListener` puede ser utilizado para *múltiples* servidores del juego al mismo tiempo. Puedes especificar la API (direccion y puerto) en los parámetros de lanzamiento del servidor de juego. 34 | 35 | #### Parámetros de lanzamiento del servidor de juego 36 | 37 | El servidor se conecta a la API a través del parámetro `"-apiendpoint=:"`, donde `` es el puerto donde el listener escucha y `` es la dirección IP de la API. 38 | 39 | Si se requiere verificación por `Api Token` en tu API, tendrás que añadir el parámetro `"-apiToken="` a los parámetros de lanzamiento de los servidor(es). Si el `` del servidor es el mismo `Api Token` que está definido en la API, los servidores se podrán comunicar con la API. De no ser así, la conexión será rechazada. 40 | 41 | Cuando el servidor de juego esté iniciado completamente, puedes modificar direcamente el `Api Token` del servidor usando el comando `setapitoken ` en la ventana de comandos del servidor que se ha iniciado. 42 | 43 | #### Ajustar puerto de escucha de la API 44 | 45 | El proyecto está actualmente configurado para escuchar en el puerto `29294`. Si quisieses cambiar esto, asegurate de cambiarlo en el código (en tu `listener.start(port)`). El puerto `29294` tambien está expuesto en Docker y ligado al mismo puerto enel host en Docker Compose. Esto significa que, usando Docker, se tendrá que cambiar el puerto en el archivo `Dockerfile` y en el archivo `docker-compose.yml` (cuando se utiliza Compose) tambien. Léase [EXPOSE in the Dockerfile reference](https://docs.docker.com/engine/reference/builder/#expose) y [networking in Compose](https://docs.docker.com/compose/networking/). 46 | -------------------------------------------------------------------------------- /README-koKR.md: -------------------------------------------------------------------------------- 1 | # BattleBit Remastered Community Server API 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Language [English](/README.md) | [Русский](/README-ruRU.md) | [中文](/README-zhCN.md) | 한국어 | [Español](/README-esES.md) | [Português](/README-ptBR.md) 6 | 7 | 이 레포지토리는 BattleBit Remastered 커뮤니티 서버에서 이벤트를 처리하고 조작하는 데 사용할 수 있는 API를 제공합니다. 8 | 9 | ## 시작하기 10 | 11 | ### 사전 요구 사항 12 | 13 | - BattleBit Remastered 커뮤니티 서버를 개설할 수 있는 권한을 보유하고 BattleBit Remastered 에서 요구하는 조건을 충족해야 합니다. 14 | - [.NET 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)을 이용해 C# 코드를 작성하고 컴파일할 수 있어야 합니다. 15 | - (프로덕션 한정) 이 API를 호스팅할 장소가 필요합니다. 16 | 17 | ### 작성 18 | 19 | 문서와 예제는 [wiki](https://github.com/MrOkiDoki/BattleBit-Community-Server-API/wiki)에서 확인할 수 있습니다. 20 | 21 | 이 API를 사용하는 방법은 `Player` 및 `GameServer`의 *자체* 서브클래스의 유형을 전달하는 `ServerListener` 인스턴스를 생성하고 이를 시작하는 것입니다. 이러한 서브클래스에서는 `Player` 및 `GameServer`에 이미 존재하는 메서드를 오버라이드하여 자신만의 메서드, 필드 및 프로퍼티를 추가할 수 있습니다 22 | 23 | 이 모든 걸 시작하는 가장 쉬운 방법은 `Program.cs`에서 `MyPlayer` 및 `MyGameServer`에 오버라이드 등을 추가하는 것입니다. 24 | 25 | ### 빌드 26 | 27 | 이 프로젝트는 CMD에서 [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build)를 사용하거나 선호하는 IDE에서 Run / Build 옵션을 이용하여 빌드할 수 있습니다. 28 | 29 | 또는, Docker를 사용할 수 있습니다. 이를 시작하는 쉬운 방법은 `docker compose up`을 실행하는 것입니다. 30 | 31 | ### 게임 서버와 연결하기 32 | 33 | API를 작성하고 컴파일한 후, 다른 곳에서 호스팅하고 싶을 수도 있습니다. 게임 서버가 실행되는 서버와 동일한 서버일 수 있으며 완전히 다른 서버일 수도 있습니다. 보다 원활하고 빠른 통신을 위해 게임 서버와의 지연 시간을 최소화하는 것이 좋습니다. 동일한 `ServerListener`를 동시에 *여러* 게임 서버에 사용할 수 있습니다. 게임 서버의 실행 옵션에서 API 서버(주소와 포트)를 지정할 수 있습니다. 34 | 35 | #### 게임 서버 시작 인수 36 | 37 | 게임 서버는 실행 인수 `-apiendpoint=:`를 사용하여 API에 연결합니다. 여기서 는 리스터가 수신하는 포트이고, IP는 API 서버의 IP입니다. 38 | 39 | API 서버에서 API 토큰 확인이 필요한 경우, 게임 서버의 시작 인수에 `"-apiToken="`을 추가해야 합니다.``이 API 서버에 정의된 API 토큰과 같으면 게임 서버는 API 서버와 통신할 수 있습니다. 40 | 41 | 게임 서버가 시작되면 커맨드라인에 `setapitoken `을 입력하여 게임 서버의 API 토큰을 직접 수정할 수 있습니다. 42 | 43 | #### API 수신 포트 설정 44 | 45 | 현재 프로젝트의 API는 `29294` 포트에서 수신 대기하도록 구성되어 있습니다. 이를 변경하려면 `listener.start(port)`에서 변경해야 합니다. `29294` 포트는 Docker에 노출되며 Docker Compose에서 호스트의 동일한 포트에 바인딩됩니다. 즉, Docker를 사용할 때 `Dockerfile` 및 `docker-compose.yml` (Compose를 사용할 때)에서도 포트를 변경해야 합니다. [EXPOSE 문서](https://docs.docker.com/engine/reference/builder/#expose) 와 [NETWORKING 문서](https://docs.docker.com/compose/networking/)를 참고하세요. -------------------------------------------------------------------------------- /README-ptBR.md: -------------------------------------------------------------------------------- 1 | # BattleBit Remastered Community Server API 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Language [English](/README.md) | [Русский](/README-ruRU.md) | [中文](/README-zhCN.md) | [한국어](/README-koKR.md) | [Español](/README-esES.md) | Português 6 | 7 | Este repositório proporciona uma API que pode ser usada para manipular eventos em seu(s) servidor(es) da comunidade. 8 | 9 | ## Começando 10 | 11 | ### Prerequisitos 12 | 13 | - Ter seu próprio servidor de BattleBit Remastered com a progressão **desabilitada** e ter acesso às opções de inicializção. 14 | - Conseguir escrever e compilar [.NET 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) em C#. 15 | - (para produção) Um lugar para hospedar essa API. 16 | 17 | ### Escrevendo 18 | 19 | A documentação e exemplos podem ser encontrados na [wiki](https://github.com/MrOkiDoki/BattleBit-Community-Server-API/wiki) (WIP). 20 | 21 | O jeito de usar esta API é criando uma instancia do `ServerListener` (e inicia-lo) na qual você passa os tipos da suas próprias subclasses do `Player` e `GameServer`. Nessas subclasses, você pode sobre escrever funções existentes em `Player` e `GameServer`. Você tambem pode adicionar suas próprias funções campos e propriedades. 22 | A maneira mais fácil de começar com tudo isso é usando `Program.cs` e adicionar suas substituições etc. dentro de `MyPlayer` e `MyGameServer`. 23 | 24 | ### Compilando 25 | 26 | Este projeto pode ser compilado tanto com [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) na linha te comando ou usando as opções de build sua IDE preferida. 27 | 28 | Alternativamente, você pode usar o Docker para compilar. Uma maneira fácil de fazer isso é executar `docker compose up`. 29 | 30 | ### Conectando ao servidor do jogo 31 | 32 | Depois de editar e compilar este projeto. Você vai querer hospedá-lo em algum lugar. Isso pode ser no mesmo servidor em que os servidores de jogos são executados ou em um local completamente diferente. Recomendamos que a latência para o servidor de jogos seja mínima para uma comunicação mais suave e rápida. O mesmo `ServerListener` pode ser usado para *múltiplos* servidores de jogos ao mesmo tempo. Você pode especificar o servidor de API (endereço e porta) nas opções de inicialização do servidor de jogos 33 | 34 | #### Argumentos de inicialização do servidor de jogos 35 | 36 | O servidor de jogos se conecta à API com o argumento de inicialização `"-apiendpoint=:"`, em que `` é a porta que o ouvinte escuta e `` é o IP do serviço da API 37 | 38 | Se a verificação de `Api Token` for necessária em sua API do servidor, você precisará adicionar `"-apiToken="` aos parâmetros de inicialização do(s) servidor(es) de jogos. Deve `` ser igual ao `Api Token` definido na API do servidor, o(s) servidor(es) de jogos poderá(ão) se comunicar com a API do servidor. 39 | 40 | Quando o servidor de jogos estiver ativo, você também poderá modificar diretamente o `Api Token` do servidor de jogos digitando `setapitoken ` em sua linha de comando. 41 | 42 | #### Ajustar a porta da API 43 | 44 | O projeto está atualmente configurado para que a API escute na porta `29294`. Se você quiser alterar isso, certifique-se de alterá-lo no código (em seu `listener.start(port)`). A porta `29294` também é exposta no Docker e vinculada à mesma porta no host do Docker Compose. Isso significa que, ao usar o Docker, você terá que alterar a porta no `Dockerfile` e no `docker-compose.yml` (ao usar o Compose) também. Consulte [EXPOSE in the Dockerfile reference](https://docs.docker.com/engine/reference/builder/#expose) e [networking in Compose](https://docs.docker.com/compose/networking/). 45 | -------------------------------------------------------------------------------- /README-ruRU.md: -------------------------------------------------------------------------------- 1 | # BattleBit Remastered Community Server API 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Language [English](/README.md) | [中文](/README-zhCN.md) | Русский | [한국어](/README-koKR.md) | [Español](/README-esES.md) | [Português](/README-ptBR.md) 6 | 7 | Этот репозиторий предоставляет API, который можно использовать для обработки событий на сервере/серверах и манипулирования ими. 8 | 9 | ## Приступая к работе 10 | 11 | ### Предварительные условия 12 | 13 | - Собственный коммьюнити сервер в BattleBit Remastered c **отключенной** официальной прогрессией для доступа к параметрам запуска. 14 | - Способность писать и компилировать [.NET 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) C# код. 15 | - (Для продакшена) Место, на котором будет размещен этот API. 16 | 17 | ### Написание кода 18 | 19 | Документацию и примеры можно найти на [wiki](https://github.com/MrOkiDoki/BattleBit-Community-Server-API/wiki) (WIP). 20 | 21 | Способ использования этого API заключается в создании инстанции `ServerListener` (и ее запуске), которой вы передаете типы ваших *собственных* подклассов `Player` и `GameServer`. В этих подклассах вы можете делать свои собственные переопределения уже существующих методов в `Player` и `GameServer`. Вы также можете добавлять свои собственные методы и поля/свойства. 22 | 23 | Самый простой способ начать работу со всем этим - использовать `Program.cs` и добавить свои переопределения и т.п. в `MyPlayer` и `MyGameServer`. 24 | 25 | ### Сборка 26 | 27 | Этот проект можно собрать с помощью команды [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) в командной строке или с помощью опций run / build в предпочитаемой вами IDE. 28 | В качестве альтернативы вы можете использовать [Docker](https://docs.docker.com/get-started/overview/) для его запуска. Простой способ сделать это - запустить `docker compose up`. 29 | 30 | ### Подключение к игровому серверу/серверам 31 | 32 | После написания и компиляции этого проекта, вы захотите разместить его где-нибудь. Это может быть тот же сервер, на котором запущен текущий игровой сервер, или совершенно другой. Мы рекомендуем поддерживать минимальную задержку до игрового сервера для более плавной и быстрой коммуникации между ними. Один и тот же `ServerListener` может использоваться для *нескольких* игровых серверов одновременно. Вы можете указать API-сервер (адрес и порт) в параметрах запуска игрового сервера. 33 | 34 | #### Параметры запуска игрового сервера 35 | 36 | Игровой сервер подключается к API с помощью параметра запуска `«-apiendpoint=:»`, где `` - это порт, который слушает слушатель, а `` - IP сервера API. 37 | 38 | Если в вашем Server API требуется проверка `Api Token`, вам необходимо добавить `«-apiToken=»` в параметры запуска игрового сервера/серверов. Если `` совпадает с `Api Token`, определенным в Server API, игровой сервер(ы) смогут взаимодействовать с Server API. 39 | 40 | Когда игровой сервер запущен, вы также можете напрямую изменить `Api Token` игрового сервера, введя `setapitoken ` в его командной строке. 41 | 42 | #### Настройка порта прослушивания API 43 | 44 | В настоящее время проект настроен на прослушивание API на порту `29294`. Если вы хотите изменить это, обязательно измените это в коде (на вашем `listener.start(port)`). Порт `29294` также открыт в Docker и привязан к тому же порту на хосте в Docker Compose. Это означает, что при использовании Docker вам придется изменить порт в `Dockerfile` и в `docker-compose.yml` (при использовании Compose). Подробнее в [EXPOSE в справке по Dockerfile](https://docs.docker.com/engine/reference/builder/#expose) и [networking in Compose](https://docs.docker.com/compose/networking/). 45 | -------------------------------------------------------------------------------- /README-zhCN.md: -------------------------------------------------------------------------------- 1 | # BattleBit Remastered 服务端 API 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Language [English](/README.md) | 中文 | [Русский](/README-ruRU.md) | [한국어](/README-koKR.md) | [Español](/README-esES.md) | [Português](/README-ptBR.md) 6 | 7 | BBR(像素战地)的服务端 API 在部署后可以提供`社区服`所需要的游戏服务端事件处理以及事件控制。 8 | 9 | ## 如何开始 10 | 11 | ### 前置需求 12 | 13 | - 拥有 BBR 服务端的开服权限,且满足开服条件。 14 | - 可以写基于 [.NET 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) 的 C# 代码。 15 | - 可以在生产环境中部署此代码。 16 | 17 | ### 制作功能 18 | 19 | 制作对应的功能可以 [查看维基(制作中)](https://github.com/MrOkiDoki/BattleBit-Community-Server-API/wiki). 20 | 21 | 本 API 将在运行后开启一个`ServerListener` 的监听进程,传递你 *自己定义* 的 `Player` 和 `GameServer` 类型覆盖原本游戏自身的 `Player` 和 `GameServer` 类型。在这些类型中添加任何你想要的功能,以此来定制属于你自己的游戏玩法。 22 | 如果想给你的游戏服务端添加功能,可以直接把覆盖的功能写入 `Program.cs` 的 `MyPlayer` 和 `MyGameServer`中,当然你也可以按照框架规范进行其他的功能纂写。 23 | 24 | ### 编译 25 | 26 | 可以直接使用 [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) 的命令进行编译,或者在你的 IDE 中自定义编译。 27 | 28 | ### 连接游戏服务端 29 | 30 | 当你将此项目的功能写完并进行了编译后,需要将此 API 服务进行部署。此 API 服务可以部署在本地网络、本机网络或者广域网中。我们强烈建议以「最低延迟」为基准进行部署,以保证 `ServerListener` 可以同时监听 *多个* 游戏服务端。 31 | 32 | 你可以在游戏服务端的启动配置中对 API 的地址和端口进行设定。 33 | 34 | #### 启动参数 35 | 游戏服务端通过启动参数 `"-apiEndpoint=:<端口>"` 来与本 API 实例进行通信, 启动参数中的 `<端口>` 指的是本 API 服务中指定的端口 `` 指的是本 API 服务部署实例的 IP 地址。 36 | 37 | 如果你在 API 服务中定义游戏服务端连接 API 服务时需要进行 `Api Token` 的验证,那么在游戏服务端的启动参数中需要增加 `"-apiToken=<你在程序中设置的 ApiToken>"`,当游戏服务端启动项的`Api Token`与 API 服务中`Api Token`的一致时,游戏服务端才可以与指定的 API 服务进行通信。 38 | 39 | 在游戏服务端的运行时,你也可以通过在命令行中输入 `setapitoken <新的token>` 来直接修改运行中的服务端的 `Api Token`。 40 | 41 | #### 调整 API 端口 42 | 如果游戏服务端实例与本 API 实例不在同一个实例上进行部署,且你想修改本 API 实例的端口 `29294`,你可以查看 `Progran.cs` 中 `listener.Start(29294);` 并把 `29294` 修改为你想指定或防火墙等安全策略已通过的端口号。 43 | 44 | 如果你的实例运行在 Docker 容器中,端口 `29294` (或你修改的其他端口)也同时需要在 Docker 容器配置中进行修改并对外暴露。也就是说你需要修改 `Dockerfile` 且(如果有使用到容器集群编排)还有可能需要修改 `docker-compose.yml` 。相关参考资料可以查看 Docker 官方文档 [EXPOSE in the Dockerfile reference](https://docs.docker.com/engine/reference/builder/#expose) 以及 [networking in Compose](https://docs.docker.com/compose/networking/)。 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BattleBit Remastered Community Server API 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Language English | [中文](/README-zhCN.md) | [Русский](/README-ruRU.md) | [한국어](/README-koKR.md) | [Español](/README-esES.md) | [Português](/README-ptBR.md) 6 | 7 | This repository provides an API that can be used to handle events on your community server(s) and manipulate them. 8 | 9 | ## Getting started 10 | 11 | ### Prerequisites 12 | 13 | - Your own community server within BattleBit Remastered with progression **disabled** and access to its launch options. 14 | - The ability to write and compile [.NET 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) C# code. 15 | - (for production) A place to host this API on. 16 | 17 | ### Writing 18 | 19 | Documentation and examples can be found on the [wiki](https://github.com/MrOkiDoki/BattleBit-Community-Server-API/wiki) (WIP). 20 | 21 | The way to use this API is to make an instance of `ServerListener` (and start it) on which you pass the types of your *own* subclasses of `Player` & `GameServer`. In those subclasses, you can make your own overrides to the already existing methods in `Player` and `GameServer`. You can also add your own methods and fields/properties. 22 | 23 | The easiest way to get started with all of this, is to use `Program.cs` and add your overrides etc. into `MyPlayer` & `MyGameServer`. 24 | 25 | ### Building 26 | 27 | This project can either be built by using [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) on the command-line or by using the run / build options inside your preferred IDE. 28 | 29 | Alternatively, you can use Docker to run it. An easy way to do this it to run `docker compose up`. 30 | 31 | ### Connecting to the gameserver(s) 32 | 33 | After writing and compiling this project. You will want to host it somewhere. This could be on the same server that the gameservers run on, or somewhere completely different. We do recommend to keep the latency to the gameserver minimal for smoother and faster communication. The same `ServerListener` can be used for *multiple* gameservers at the same time. You can specify the API server (address & port) in the launch options of the gameserver. 34 | 35 | #### Gameserver start arguments 36 | 37 | The gameserver connects to the API with the launch argument `"-apiendpoint=:"`, where `` is the port that the listener listens on and the `` is the IP of the API server. 38 | 39 | If `Api Token` verification is required in your Server API, you need to add `"-apiToken="` to the startup parameters of the gameserver(s). Should `` the same as `Api Token` defined in Server API, gameserver(s) can communicate with Server API. 40 | 41 | When the gameserver is up, you can also directly modify the `Api Token` of the gameserver by entering `setapitoken ` in its command line. 42 | 43 | #### Adjust API listening port 44 | 45 | The project is currently configured to have the API listen on port `29294`. If you want to change this, make sure to change it in the code (on your `listener.start(port)`). Port `29294` is also exposed in Docker and bound to the same port on the host in Docker Compose. This means that when using Docker, you will have to change the port in the `Dockerfile` and in `docker-compose.yml` (when using Compose) as well. See [EXPOSE in the Dockerfile reference](https://docs.docker.com/engine/reference/builder/#expose) and [networking in Compose](https://docs.docker.com/compose/networking/). 46 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | # In the docker compose file, we define some services (containers) to run. 4 | # This will be geared towards production. 5 | services: 6 | 7 | battlebit-community-api: 8 | image: bb-community-server-api:latest 9 | build: 10 | # Specify how to build the image above. 11 | context: . 12 | 13 | restart: always 14 | ports: 15 | - "29294:29294" 16 | --------------------------------------------------------------------------------