├── .gitignore
├── BattleNET client
├── BattleNET client.csproj
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── app.config
├── BattleNET.sln
├── BattleNET
├── BattlEyeClient.cs
├── BattlEyeCommand.cs
├── BattlEyeCommandResult.cs
├── BattlEyeConnectionResult.cs
├── BattlEyeDisconnectEventArgs.cs
├── BattlEyeDisconnectionType.cs
├── BattlEyeMessageEventArgs.cs
├── BattlEyePacketType.cs
├── BattleEyeLoginCredentials.cs
├── BattleNET.csproj
├── BattleNET.nuspec
├── CRC32.cs
└── Helpers.cs
├── README.md
├── authors.txt
├── changelog.txt
└── license.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | [Rr]eleases/
14 | x64/
15 | x86/
16 | build/
17 | bld/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Roslyn cache directories
22 | *.ide/
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 | # Build Results of an ATL Project
33 | [Dd]ebugPS/
34 | [Rr]eleasePS/
35 | dlldata.c
36 |
37 | *_i.c
38 | *_p.c
39 | *_i.h
40 | *.ilk
41 | *.meta
42 | *.obj
43 | *.pch
44 | *.pdb
45 | *.pgc
46 | *.pgd
47 | *.rsp
48 | *.sbr
49 | *.tlb
50 | *.tli
51 | *.tlh
52 | *.tmp
53 | *.tmp_proj
54 | *.log
55 | *.vspscc
56 | *.vssscc
57 | .builds
58 | *.pidb
59 | *.svclog
60 | *.scc
61 |
62 | # Chutzpah Test files
63 | _Chutzpah*
64 |
65 | # Visual C++ cache files
66 | ipch/
67 | *.aps
68 | *.ncb
69 | *.opensdf
70 | *.sdf
71 | *.cachefile
72 |
73 | # Visual Studio profiler
74 | *.psess
75 | *.vsp
76 | *.vspx
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # ReSharper is a .NET coding add-in
85 | _ReSharper*/
86 | *.[Rr]e[Ss]harper
87 | *.DotSettings.user
88 |
89 | # JustCode is a .NET coding addin-in
90 | .JustCode
91 |
92 | # TeamCity is a build add-in
93 | _TeamCity*
94 |
95 | # DotCover is a Code Coverage Tool
96 | *.dotCover
97 |
98 | # NCrunch
99 | _NCrunch_*
100 | .*crunch*.local.xml
101 |
102 | # MightyMoose
103 | *.mm.*
104 | AutoTest.Net/
105 |
106 | # Web workbench (sass)
107 | .sass-cache/
108 |
109 | # Installshield output folder
110 | [Ee]xpress/
111 |
112 | # DocProject is a documentation generator add-in
113 | DocProject/buildhelp/
114 | DocProject/Help/*.HxT
115 | DocProject/Help/*.HxC
116 | DocProject/Help/*.hhc
117 | DocProject/Help/*.hhk
118 | DocProject/Help/*.hhp
119 | DocProject/Help/Html2
120 | DocProject/Help/html
121 |
122 | # Click-Once directory
123 | publish/
124 |
125 | # Publish Web Output
126 | *.[Pp]ublish.xml
127 | *.azurePubxml
128 | # TODO: Comment the next line if you want to checkin your web deploy settings
129 | # but database connection strings (with potential passwords) will be unencrypted
130 | *.pubxml
131 | *.publishproj
132 |
133 | # NuGet Packages
134 | *.nupkg
135 | # The packages folder can be ignored because of Package Restore
136 | **/packages/*
137 | # except build/, which is used as an MSBuild target.
138 | !**/packages/build/
139 | # If using the old MSBuild-Integrated Package Restore, uncomment this:
140 | #!**/packages/repositories.config
141 |
142 | # Windows Azure Build Output
143 | csx/
144 | *.build.csdef
145 |
146 | # Windows Store app package directory
147 | AppPackages/
148 |
149 | # Others
150 | sql/
151 | *.Cache
152 | ClientBin/
153 | [Ss]tyle[Cc]op.*
154 | ~$*
155 | *~
156 | *.dbmdl
157 | *.dbproj.schemaview
158 | *.pfx
159 | *.publishsettings
160 | node_modules/
161 |
162 | # RIA/Silverlight projects
163 | Generated_Code/
164 |
165 | # Backup & report files from converting an old project file
166 | # to a newer Visual Studio version. Backup files are not needed,
167 | # because we have git ;-)
168 | _UpgradeReport_Files/
169 | Backup*/
170 | UpgradeLog*.XML
171 | UpgradeLog*.htm
172 |
173 | # SQL Server files
174 | *.mdf
175 | *.ldf
176 |
177 | # Business Intelligence projects
178 | *.rdl.data
179 | *.bim.layout
180 | *.bim_*.settings
181 |
182 | # Microsoft Fakes
183 | FakesAssemblies/
184 | src/.vs/
185 | *.orig
186 | .vs/
187 |
--------------------------------------------------------------------------------
/BattleNET client/BattleNET client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {F6671269-E70E-4502-A7F5-7B2AD6955900}
9 | Exe
10 | Properties
11 | BattleNET_client
12 | BattleNET client
13 | v4.6.1
14 |
15 |
16 | 512
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 0
28 | 1.0.0.%2a
29 | false
30 | false
31 | true
32 |
33 |
34 | x86
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 | false
43 |
44 |
45 | x86
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | false
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}
70 | BattleNET
71 |
72 |
73 |
74 |
75 | False
76 | Microsoft .NET Framework 4 Client Profile %28x86 and x64%29
77 | true
78 |
79 |
80 | False
81 | .NET Framework 3.5 SP1 Client Profile
82 | false
83 |
84 |
85 | False
86 | .NET Framework 3.5 SP1
87 | false
88 |
89 |
90 | False
91 | Windows Installer 3.1
92 | true
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
--------------------------------------------------------------------------------
/BattleNET client/Program.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 | using System.Net;
10 | using System.Text;
11 | using BattleNET;
12 |
13 | namespace BattleNET_client
14 | {
15 | internal class Program
16 | {
17 | private static void Main(string[] args)
18 | {
19 | Console.WriteLine(
20 | "BattleNET v1.3.4 - BattlEye Library and Client\n\n" +
21 | "Copyright (C) 2018 by it's authors.\n" +
22 | "Some rights reserved. See license.txt, authors.txt.\n"
23 | );
24 |
25 | BattlEyeLoginCredentials loginCredentials;
26 | string command = "";
27 |
28 | Console.OutputEncoding = Encoding.UTF8;
29 |
30 | if (args.Length > 0)
31 | {
32 | loginCredentials = GetLoginCredentials(args);
33 |
34 | for (int i = 0; i < args.Length; i++)
35 | {
36 | if (args[i] == "-command")
37 | {
38 | try
39 | {
40 | command = args[i + 1];
41 | }
42 | catch
43 | {
44 | Console.WriteLine("No command given!");
45 | loginCredentials.Host = null;
46 | }
47 | }
48 | }
49 |
50 | if (loginCredentials.Host == null || loginCredentials.Port == 0 || loginCredentials.Password == "")
51 | {
52 | Console.WriteLine("BattleNET client usage:");
53 | Console.WriteLine("BattleNET client.exe -host 127.0.0.1 -port 2302 -password admin [-command shutdown]");
54 | Console.Read();
55 | Environment.Exit(0);
56 | }
57 | }
58 | else
59 | {
60 | loginCredentials = GetLoginCredentials();
61 | }
62 |
63 | Console.Title = string.Format("BattleNET client v1.3.4 - {0}:{1}", loginCredentials.Host, loginCredentials.Port);
64 |
65 | BattlEyeClient b = new BattlEyeClient(loginCredentials);
66 | b.BattlEyeMessageReceived += BattlEyeMessageReceived;
67 | b.BattlEyeConnected += BattlEyeConnected;
68 | b.BattlEyeDisconnected += BattlEyeDisconnected;
69 | b.ReconnectOnPacketLoss = true;
70 | b.Connect();
71 |
72 | if (command != "")
73 | {
74 | b.SendCommand(command);
75 | while (b.CommandQueue > 0) { /* wait until server received packet */ };
76 | }
77 | else
78 | {
79 | while (true)
80 | {
81 | string cmd = Console.ReadLine();
82 |
83 | if (cmd == "exit" || cmd == "logout")
84 | {
85 | break;
86 | }
87 |
88 | if (b.Connected)
89 | {
90 | b.SendCommand(cmd);
91 | }
92 | else
93 | {
94 | Environment.Exit(0);
95 | }
96 | }
97 | }
98 |
99 | b.Disconnect();
100 | }
101 |
102 | private static void BattlEyeConnected(BattlEyeConnectEventArgs args)
103 | {
104 | //if (args.ConnectionResult == BattlEyeConnectionResult.Success) { /* Connected successfully */ }
105 | //if (args.ConnectionResult == BattlEyeConnectionResult.InvalidLogin) { /* Connection failed, invalid login details */ }
106 | //if (args.ConnectionResult == BattlEyeConnectionResult.ConnectionFailed) { /* Connection failed, host unreachable */ }
107 |
108 | Console.WriteLine(args.Message);
109 | }
110 |
111 | private static void BattlEyeDisconnected(BattlEyeDisconnectEventArgs args)
112 | {
113 | //if (args.DisconnectionType == BattlEyeDisconnectionType.ConnectionLost) { /* Connection lost (timeout), if ReconnectOnPacketLoss is set to true it will reconnect */ }
114 | //if (args.DisconnectionType == BattlEyeDisconnectionType.SocketException) { /* Something went terribly wrong... */ }
115 | //if (args.DisconnectionType == BattlEyeDisconnectionType.Manual) { /* Disconnected by implementing application, that would be you */ }
116 |
117 | Console.WriteLine(args.Message);
118 | }
119 |
120 | private static void BattlEyeMessageReceived(BattlEyeMessageEventArgs args)
121 | {
122 | //if (args.Id == playerListId)
123 | //{
124 | // playerList = args.Message;
125 | //}
126 |
127 | Console.WriteLine(args.Message);
128 | }
129 |
130 | private static BattlEyeLoginCredentials GetLoginCredentials(string[] args)
131 | {
132 | BattlEyeLoginCredentials loginCredentials = new BattlEyeLoginCredentials();
133 | loginCredentials.Host = null;
134 | loginCredentials.Port = 0;
135 | loginCredentials.Password = "";
136 |
137 | for (int i = 0; i < args.Length; i = i + 2)
138 | {
139 | switch (args[i])
140 | {
141 | case "-host":
142 | {
143 | try
144 | {
145 | IPAddress ip = Dns.GetHostAddresses(args[i + 1])[0];
146 | loginCredentials.Host = ip;
147 | }
148 | catch
149 | {
150 | Console.WriteLine("No valid host given!");
151 | }
152 | break;
153 | }
154 |
155 | case "-port":
156 | {
157 | int value;
158 | if (int.TryParse(args[i + 1], out value))
159 | {
160 | loginCredentials.Port = value;
161 | }
162 | else
163 | {
164 | Console.WriteLine("No valid port given!");
165 | }
166 | break;
167 | }
168 |
169 | case "-password":
170 | {
171 | if (args[i + 1] != "")
172 | {
173 | loginCredentials.Password = args[i + 1];
174 | }
175 | else
176 | {
177 | Console.WriteLine("No password given!");
178 | }
179 | break;
180 | }
181 | }
182 | }
183 |
184 | return loginCredentials;
185 | }
186 |
187 | private static BattlEyeLoginCredentials GetLoginCredentials()
188 | {
189 | IPAddress host = null;
190 | int port = 0;
191 | string password = "";
192 |
193 | do
194 | {
195 | string input;
196 | Console.Write("Enter IP address or hostname: ");
197 | input = Console.ReadLine();
198 |
199 | try
200 | {
201 | IPAddress ip = Dns.GetHostAddresses(input)[0];
202 | host = ip;
203 | }
204 | catch { /* try again */ }
205 | } while (host == null);
206 |
207 | do
208 | {
209 | int value;
210 | string input;
211 | Console.Write("Enter port number: ");
212 | input = Console.ReadLine();
213 |
214 | if (int.TryParse(input, out value))
215 | {
216 | port = value;
217 | }
218 | } while (port == 0);
219 |
220 | do
221 | {
222 | Console.Write("Enter RCon password: ");
223 | string input = Console.ReadLine();
224 |
225 | if (input != "")
226 | {
227 | password = input;
228 | }
229 | } while (password == "");
230 |
231 | var loginCredentials = new BattlEyeLoginCredentials
232 | {
233 | Host = host,
234 | Port = port,
235 | Password = password,
236 | };
237 |
238 | return loginCredentials;
239 | }
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/BattleNET client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region
2 |
3 | using System.Reflection;
4 | using System.Runtime.InteropServices;
5 |
6 | #endregion
7 |
8 | // General Information about an assembly is controlled through the following
9 | // set of attributes. Change these attribute values to modify the information
10 | // associated with an assembly.
11 |
12 | [assembly: AssemblyTitle("BattleNET client")]
13 | [assembly: AssemblyDescription("BattlEye Client")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("Marcel de Vries")]
16 | [assembly: AssemblyProduct("BattleNET client")]
17 | [assembly: AssemblyCopyright("Copyright © 2018")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 |
21 | // Setting ComVisible to false makes the types in this assembly not visible
22 | // to COM components. If you need to access a type in this assembly from
23 | // COM, set the ComVisible attribute to true on that type.
24 |
25 | [assembly: ComVisible(false)]
26 |
27 | // The following GUID is for the ID of the typelib if this project is exposed to COM
28 |
29 | [assembly: Guid("57d2997b-d6f2-4f8e-b9b0-c89487bdded4")]
30 |
31 | // Version information for an assembly consists of the following four values:
32 | //
33 | // Major Version
34 | // Minor Version
35 | // Build Number
36 | // Revision
37 | //
38 | // You can specify all the values or you can default the Build and Revision Numbers
39 | // by using the '*' as shown below:
40 | // [assembly: AssemblyVersion("1.0.*")]
41 |
42 | [assembly: AssemblyVersion("1.3.4")]
43 | [assembly: AssemblyFileVersion("1.3.4")]
--------------------------------------------------------------------------------
/BattleNET client/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/BattleNET.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BattleNET", "BattleNET\BattleNET.csproj", "{4FBB3734-215B-45B1-BDBC-0EFA156A6900}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BattleNET client", "BattleNET client\BattleNET client.csproj", "{F6671269-E70E-4502-A7F5-7B2AD6955900}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|Mixed Platforms = Debug|Mixed Platforms
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|Mixed Platforms = Release|Mixed Platforms
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
21 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
22 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Debug|x86.ActiveCfg = Debug|Any CPU
23 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
26 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Release|Mixed Platforms.Build.0 = Release|Any CPU
27 | {4FBB3734-215B-45B1-BDBC-0EFA156A6900}.Release|x86.ActiveCfg = Release|Any CPU
28 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Debug|Any CPU.ActiveCfg = Debug|x86
29 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
30 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Debug|Mixed Platforms.Build.0 = Debug|x86
31 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Debug|x86.ActiveCfg = Debug|x86
32 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Debug|x86.Build.0 = Debug|x86
33 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Release|Any CPU.ActiveCfg = Release|x86
34 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Release|Mixed Platforms.ActiveCfg = Release|x86
35 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Release|Mixed Platforms.Build.0 = Release|x86
36 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Release|x86.ActiveCfg = Release|x86
37 | {F6671269-E70E-4502-A7F5-7B2AD6955900}.Release|x86.Build.0 = Release|x86
38 | EndGlobalSection
39 | GlobalSection(SolutionProperties) = preSolution
40 | HideSolutionNode = FALSE
41 | EndGlobalSection
42 | EndGlobal
43 |
--------------------------------------------------------------------------------
/BattleNET/BattlEyeClient.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Globalization;
11 | using System.Linq;
12 | using System.Net;
13 | using System.Net.Sockets;
14 | using System.Text;
15 | using System.Threading.Tasks;
16 |
17 | namespace BattleNET
18 | {
19 | public class BattlEyeClient
20 | {
21 | private Socket _socket;
22 | private DateTime _packetSent;
23 | private DateTime _packetReceived;
24 | private BattlEyeDisconnectionType? _disconnectionType;
25 | private bool _keepRunning;
26 | private int _sequenceNumber;
27 | private int _currentPacket;
28 | private SortedDictionary _packetQueue;
29 | private BattlEyeLoginCredentials _loginCredentials;
30 |
31 | public bool Connected => _socket != null && _socket.Connected;
32 |
33 | public bool ReconnectOnPacketLoss
34 | {
35 | get;
36 | set;
37 | }
38 |
39 | public int CommandQueue => _packetQueue.Count;
40 |
41 | public BattlEyeClient(BattlEyeLoginCredentials loginCredentials)
42 | {
43 | _loginCredentials = loginCredentials;
44 | }
45 |
46 | public BattlEyeConnectionResult Connect()
47 | {
48 | return ConnectInternal(100);
49 | }
50 |
51 | private BattlEyeConnectionResult ConnectInternal(int counter)
52 | {
53 | _packetSent = DateTime.Now;
54 | _packetReceived = DateTime.Now;
55 |
56 | _sequenceNumber = 0;
57 | _currentPacket = -1;
58 | _packetQueue = new SortedDictionary();
59 | _keepRunning = true;
60 |
61 | var remoteEp = new IPEndPoint(_loginCredentials.Host, _loginCredentials.Port);
62 | _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
63 | {
64 | ReceiveBufferSize = int.MaxValue,
65 | ReceiveTimeout = 5000
66 | };
67 |
68 | try
69 | {
70 | _socket.Connect(remoteEp);
71 |
72 | if (SendLoginPacket(_loginCredentials.Password) == BattlEyeCommandResult.Error)
73 | return BattlEyeConnectionResult.ConnectionFailed;
74 |
75 | var bytesReceived = new Byte[4096];
76 |
77 | _socket.Receive(bytesReceived, bytesReceived.Length, 0);
78 |
79 | if (bytesReceived[7] == 0x00)
80 | {
81 | if (bytesReceived[8] == 0x01)
82 | {
83 | OnConnect(_loginCredentials, BattlEyeConnectionResult.Success);
84 |
85 | Receive();
86 | }
87 | else
88 | {
89 | OnConnect(_loginCredentials, BattlEyeConnectionResult.InvalidLogin);
90 | return BattlEyeConnectionResult.InvalidLogin;
91 | }
92 | }
93 | }
94 | catch
95 | {
96 | if (_disconnectionType == BattlEyeDisconnectionType.ConnectionLost)
97 | {
98 | Disconnect(BattlEyeDisconnectionType.ConnectionLost);
99 |
100 | if (counter > 0)
101 | {
102 | return ConnectInternal(counter - 1);
103 | }
104 |
105 | return BattlEyeConnectionResult.ConnectionFailed;
106 | }
107 | else
108 | {
109 | OnConnect(_loginCredentials, BattlEyeConnectionResult.ConnectionFailed);
110 | return BattlEyeConnectionResult.ConnectionFailed;
111 | }
112 | }
113 |
114 | return BattlEyeConnectionResult.Success;
115 | }
116 |
117 | private BattlEyeCommandResult SendLoginPacket(string command)
118 | {
119 | try
120 | {
121 | if (!_socket.Connected)
122 | return BattlEyeCommandResult.NotConnected;
123 |
124 | byte[] packet = ConstructPacket(BattlEyePacketType.Login, 0, command);
125 | _socket.Send(packet);
126 |
127 | _packetSent = DateTime.Now;
128 | }
129 | catch
130 | {
131 | return BattlEyeCommandResult.Error;
132 | }
133 |
134 | return BattlEyeCommandResult.Success;
135 | }
136 |
137 | private BattlEyeCommandResult SendAcknowledgePacket(string command)
138 | {
139 | try
140 | {
141 | if (!_socket.Connected) return BattlEyeCommandResult.NotConnected;
142 |
143 | byte[] packet = ConstructPacket(BattlEyePacketType.Acknowledge, 0, command);
144 | _socket.Send(packet);
145 |
146 | _packetSent = DateTime.Now;
147 | }
148 | catch
149 | {
150 | return BattlEyeCommandResult.Error;
151 | }
152 |
153 | return BattlEyeCommandResult.Success;
154 | }
155 |
156 | public int SendCommand(string command, bool log = true)
157 | {
158 | return SendCommandPacket(command, log);
159 | }
160 |
161 | private int SendCommandPacket(string command, bool log = true)
162 | {
163 | int packetID = _sequenceNumber;
164 | _sequenceNumber = (_sequenceNumber == 255) ? 0 : _sequenceNumber + 1;
165 |
166 | try
167 | {
168 | if (!_socket.Connected)
169 | return 256;
170 |
171 | var packet = ConstructPacket(BattlEyePacketType.Command, packetID, command);
172 |
173 | _packetSent = DateTime.Now;
174 |
175 | if (log)
176 | {
177 | _packetQueue.Add(packetID, new[] { command, _packetSent.ToString(CultureInfo.InvariantCulture) });
178 | }
179 | else
180 | {
181 | SendPacket(packet);
182 | }
183 | }
184 | catch
185 | {
186 | return 256;
187 | }
188 |
189 | return packetID;
190 | }
191 |
192 | public int SendCommand(BattlEyeCommand command, string parameters = "")
193 | {
194 | return SendCommandPacket(command, parameters);
195 | }
196 |
197 | private int SendCommandPacket(BattlEyeCommand command, string parameters = "")
198 | {
199 | int packetID = _sequenceNumber;
200 | _sequenceNumber = (_sequenceNumber == 255) ? 0 : _sequenceNumber + 1;
201 |
202 | try
203 | {
204 | if (!_socket.Connected)
205 | return 256;
206 |
207 | ConstructPacket(BattlEyePacketType.Command, packetID, Helpers.StringValueOf(command) + parameters);
208 |
209 | _packetSent = DateTime.Now;
210 |
211 | _packetQueue.Add(packetID, new[] { Helpers.StringValueOf(command) + parameters, _packetSent.ToString(CultureInfo.InvariantCulture) });
212 | }
213 | catch
214 | {
215 | return 256;
216 | }
217 |
218 | return packetID;
219 | }
220 |
221 | private void SendPacket(byte[] packet)
222 | {
223 | _socket.Send(packet);
224 | }
225 |
226 | private byte[] ConstructPacket(BattlEyePacketType packetType, int sequenceNumber, string command)
227 | {
228 | string type;
229 |
230 | switch (packetType)
231 | {
232 | case BattlEyePacketType.Login:
233 | type = Helpers.Hex2Ascii("FF00");
234 | break;
235 | case BattlEyePacketType.Command:
236 | type = Helpers.Hex2Ascii("FF01");
237 | break;
238 | case BattlEyePacketType.Acknowledge:
239 | type = Helpers.Hex2Ascii("FF02");
240 | break;
241 | default:
242 | return new byte[] { };
243 | }
244 |
245 | if (packetType != BattlEyePacketType.Acknowledge)
246 | {
247 | if (command != null) command = Encoding.GetEncoding(1252).GetString(Encoding.UTF8.GetBytes(command));
248 | }
249 |
250 | var count = Helpers.Bytes2String(new[] { (byte)sequenceNumber });
251 |
252 | var byteArray = new CRC32().ComputeHash(Helpers.String2Bytes(type + ((packetType != BattlEyePacketType.Command) ? "" : count) + command));
253 |
254 | var hash = new string(Helpers.Hex2Ascii(BitConverter.ToString(byteArray).Replace("-", "")).ToCharArray().Reverse().ToArray());
255 |
256 | var packet = "BE" + hash + type + ((packetType != BattlEyePacketType.Command) ? "" : count) + command;
257 |
258 | return Helpers.String2Bytes(packet);
259 | }
260 |
261 | public void Disconnect()
262 | {
263 | _keepRunning = false;
264 |
265 | if (_socket.Connected)
266 | {
267 | _socket.Shutdown(SocketShutdown.Both);
268 | _socket.Close();
269 | }
270 |
271 | OnDisconnect(_loginCredentials, BattlEyeDisconnectionType.Manual);
272 | }
273 |
274 | private void Disconnect(BattlEyeDisconnectionType? disconnectionType)
275 | {
276 | if (disconnectionType == BattlEyeDisconnectionType.ConnectionLost)
277 | _disconnectionType = BattlEyeDisconnectionType.ConnectionLost;
278 |
279 | _keepRunning = false;
280 |
281 | if (_socket.Connected)
282 | {
283 | _socket.Shutdown(SocketShutdown.Both);
284 | _socket.Close();
285 | }
286 |
287 | if (disconnectionType != null)
288 | OnDisconnect(_loginCredentials, disconnectionType);
289 | }
290 |
291 | private async void Receive()
292 | {
293 | var state = new StateObject { WorkSocket = _socket };
294 |
295 | _disconnectionType = null;
296 |
297 | _socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
298 |
299 | while (_socket.Connected && _keepRunning)
300 | {
301 | int timeoutClient = (int)(DateTime.Now - _packetSent).TotalSeconds;
302 | int timeoutServer = (int)(DateTime.Now - _packetReceived).TotalSeconds;
303 |
304 | if (timeoutClient >= 5)
305 | {
306 | if (timeoutServer >= 20)
307 | {
308 | Disconnect(BattlEyeDisconnectionType.ConnectionLost);
309 | _keepRunning = true;
310 | }
311 | else
312 | {
313 | if (_packetQueue.Count == 0)
314 | {
315 | SendCommandPacket(null, false);
316 | }
317 | }
318 | }
319 |
320 | if (_socket.Connected && _packetQueue.Count > 0 && _socket.Available == 0)
321 | {
322 | try
323 | {
324 | int key = _packetQueue.First().Key;
325 |
326 | if (_currentPacket == -1 || !_packetQueue.ContainsKey(_currentPacket))
327 | {
328 | _currentPacket = key;
329 | string value = _packetQueue[key][0];
330 | SendPacket(ConstructPacket(BattlEyePacketType.Command, key, value));
331 | }
332 | }
333 | catch
334 | {
335 | // Prevent possible crash when packet is received at the same moment it's trying to resend it.
336 | }
337 | }
338 |
339 | await Task.Delay(250);
340 | }
341 |
342 | if (!_socket.Connected)
343 | {
344 | if (ReconnectOnPacketLoss && _keepRunning)
345 | {
346 | Connect();
347 | }
348 | else if (!_keepRunning)
349 | {
350 | //let the thread finish without further action
351 | }
352 | else
353 | {
354 | OnDisconnect(_loginCredentials, BattlEyeDisconnectionType.ConnectionLost);
355 | }
356 | }
357 |
358 | }
359 |
360 | private void ReceiveCallback(IAsyncResult ar)
361 | {
362 | try
363 | {
364 | StateObject state = (StateObject)ar.AsyncState;
365 | Socket client = state.WorkSocket;
366 |
367 | // this method can be called from the middle of a .Disconnect() call
368 | // test with Debug > Exception > CLR exs on
369 | if (!client.Connected)
370 | {
371 | return;
372 | }
373 |
374 | int bytesRead = client.EndReceive(ar);
375 |
376 | if (state.Buffer[7] == 0x02)
377 | {
378 | SendAcknowledgePacket(Helpers.Bytes2String(new[] { state.Buffer[8] }));
379 | OnBattlEyeMessage(Helpers.Bytes2String(state.Buffer, 9, bytesRead - 9), 256);
380 | }
381 | else if (state.Buffer[7] == 0x01)
382 | {
383 | if (bytesRead > 9)
384 | {
385 | if (state.Buffer[7] == 0x01 && state.Buffer[9] == 0x00)
386 | {
387 | if (state.Buffer[11] == 0)
388 | {
389 | state.PacketsTodo = state.Buffer[10];
390 | }
391 |
392 | if (state.PacketsTodo > 0)
393 | {
394 | state.Message.Append(Helpers.Bytes2String(state.Buffer, 12, bytesRead - 12));
395 | state.PacketsTodo--;
396 | }
397 |
398 | if (state.PacketsTodo == 0)
399 | {
400 | OnBattlEyeMessage(state.Message.ToString(), state.Buffer[8]);
401 | state.Message = new StringBuilder();
402 | state.PacketsTodo = 0;
403 | }
404 | }
405 | else
406 | {
407 | // Temporary fix to avoid infinite loops with multi-packet server messages
408 | state.Message = new StringBuilder();
409 | state.PacketsTodo = 0;
410 |
411 | OnBattlEyeMessage(Helpers.Bytes2String(state.Buffer, 9, bytesRead - 9), state.Buffer[8]);
412 | }
413 | }
414 |
415 | if (_packetQueue.ContainsKey(state.Buffer[8]) && state.PacketsTodo == 0)
416 | {
417 | _packetQueue.Remove(state.Buffer[8]);
418 | }
419 | }
420 |
421 | _packetReceived = DateTime.Now;
422 |
423 | client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
424 | }
425 | catch
426 | {
427 | // do nothing
428 | }
429 | }
430 |
431 | private void OnBattlEyeMessage(string message, int id)
432 | {
433 | BattlEyeMessageReceived?.Invoke(new BattlEyeMessageEventArgs(message, id));
434 | }
435 |
436 | private void OnConnect(BattlEyeLoginCredentials loginDetails, BattlEyeConnectionResult connectionResult)
437 | {
438 | if (connectionResult == BattlEyeConnectionResult.ConnectionFailed || connectionResult == BattlEyeConnectionResult.InvalidLogin)
439 | Disconnect(null);
440 |
441 | BattlEyeConnected?.Invoke(new BattlEyeConnectEventArgs(loginDetails, connectionResult));
442 | }
443 |
444 | private void OnDisconnect(BattlEyeLoginCredentials loginDetails, BattlEyeDisconnectionType? disconnectionType)
445 | {
446 | BattlEyeDisconnected?.Invoke(new BattlEyeDisconnectEventArgs(loginDetails, disconnectionType));
447 | }
448 |
449 | public event BattlEyeMessageEventHandler BattlEyeMessageReceived;
450 | public event BattlEyeConnectEventHandler BattlEyeConnected;
451 | public event BattlEyeDisconnectEventHandler BattlEyeDisconnected;
452 | }
453 |
454 | public class StateObject
455 | {
456 | public Socket WorkSocket;
457 | public const int BufferSize = 2048;
458 | public byte[] Buffer = new byte[BufferSize];
459 | public StringBuilder Message = new StringBuilder();
460 | public int PacketsTodo;
461 | }
462 | }
463 |
--------------------------------------------------------------------------------
/BattleNET/BattlEyeCommand.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 | using System.ComponentModel;
10 |
11 | namespace BattleNET
12 | {
13 | public enum BattlEyeCommand
14 | {
15 | ///
16 | /// #init - Reload server config file loaded by –config option.
17 | ///
18 | [Description("#init")]
19 | Init,
20 |
21 | ///
22 | /// #shutdown - Shuts down the server.
23 | ///
24 | [Description("#shutdown")]
25 | Shutdown,
26 |
27 | ///
28 | /// #reassign - Start over and reassign roles.
29 | ///
30 | [Description("#reassign")]
31 | Reassign,
32 |
33 | ///
34 | /// #restart - Restart mission.
35 | ///
36 | [Description("#restart")]
37 | Restart,
38 |
39 | ///
40 | /// #restartserver - Restart server.
41 | ///
42 | [Description("#restartserver")]
43 | RestartServer,
44 |
45 | ///
46 | /// #lock - Locks the server, prevents new clients from joining.
47 | ///
48 | [Description("#lock")]
49 | Lock,
50 |
51 | ///
52 | /// #unlock - Unlocks the server, allows new clients to join.
53 | ///
54 | [Description("#unlock")]
55 | Unlock,
56 |
57 | ///
58 | /// #mission [missionName] - Loads the given mission on the server.
59 | ///
60 | [Description("#mission ")]
61 | Mission,
62 |
63 | ///
64 | /// missions - Returns a list of the available missions on the server.
65 | ///
66 | [Description("missions")]
67 | Missions,
68 |
69 | ///
70 | /// RConPassword [password] - Changes the RCon password.
71 | ///
72 | [Description("RConPassword ")]
73 | RConPassword,
74 |
75 | ///
76 | /// MaxPing [ping] - Changes the MaxPing value. If a player has a higher ping, he will be kicked from the server.
77 | ///
78 | [Description("MaxPing ")]
79 | MaxPing,
80 |
81 | ///
82 | /// kick [player#] - Kicks a player. His # can be found in the player list using the 'players' command.
83 | ///
84 | [Description("kick ")]
85 | Kick,
86 |
87 | ///
88 | /// players - Displays a list of the players on the server including BE GUIDs and pings.
89 | ///
90 | [Description("players")]
91 | Players,
92 |
93 | ///
94 | /// Say [player#] [msg] - Say something to player #. specially -1 equals all players on server (e.g. 'Say -1 Hello World').
95 | ///
96 | [Description("Say ")]
97 | Say,
98 |
99 | ///
100 | /// loadBans - (Re)load the BE ban list from bans.txt.
101 | ///
102 | [Description("loadBans")]
103 | LoadBans,
104 |
105 | ///
106 | /// loadScripts - Loads the scripts.txt file without the need to restart server.
107 | ///
108 | [Description("loadScripts")]
109 | LoadScripts,
110 |
111 | ///
112 | /// loadEvents - (Re)load createvehicle.txt, remoteexec.txt and publicvariable.txt
113 | ///
114 | [Description("loadEvents")]
115 | LoadEvents,
116 |
117 | ///
118 | /// loadEvents - (Re)load createvehicle.txt, remoteexec.txt and publicvariable.txt
119 | ///
120 | [Description("loadEvents")]
121 | [Obsolete("This member is obsolette and will be removed in future. Use LoadEvents instead")]
122 | loadEvents,
123 |
124 | ///
125 | /// bans - Show a list of all BE server bans.
126 | ///
127 | [Description("bans")]
128 | Bans,
129 |
130 | ///
131 | /// ban [player #] [time in minutes] [reason] - Ban a player's BE GUID from the server. If time is not specified or 0, the ban will be permanent; if reason is not specified the player will be kicked with "Banned".
132 | ///
133 | [Description("ban ")]
134 | Ban,
135 |
136 | ///
137 | /// addBan [GUID] [time in minutes] [reason] - Same as "ban", but allows to ban a player that is not currently on the server.
138 | ///
139 | [Description("addBan ")]
140 | AddBan,
141 |
142 | ///
143 | /// removeBan [ban #] - Remove ban (get the ban # from the bans command).
144 | ///
145 | [Description("removeBan ")]
146 | RemoveBan,
147 |
148 | ///
149 | /// writeBans - Removes expired bans from bans file.
150 | ///
151 | [Description("writeBans")]
152 | WriteBans,
153 |
154 | ///
155 | /// admins - Gets connected RCON clients.
156 | ///
157 | [Description("admins")]
158 | Admins,
159 |
160 | ///
161 | /// admins - Gets connected RCON clients.
162 | ///
163 | [Description("admins")]
164 | [Obsolete("This member is obsolette and will be removed in future. Use Admins instead")]
165 | admins,
166 | }
167 | }
--------------------------------------------------------------------------------
/BattleNET/BattlEyeCommandResult.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | namespace BattleNET
9 | {
10 | public enum BattlEyeCommandResult
11 | {
12 | Success,
13 | Error,
14 | NotConnected,
15 | }
16 | }
--------------------------------------------------------------------------------
/BattleNET/BattlEyeConnectionResult.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System.ComponentModel;
9 |
10 | namespace BattleNET
11 | {
12 | public enum BattlEyeConnectionResult
13 | {
14 | [Description("Connected!")]
15 | Success,
16 |
17 | [Description("Host unreachable!")]
18 | ConnectionFailed,
19 |
20 | [Description("Invalid login details!")]
21 | InvalidLogin
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/BattleNET/BattlEyeDisconnectEventArgs.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 |
10 | namespace BattleNET
11 | {
12 | public delegate void BattlEyeConnectEventHandler(BattlEyeConnectEventArgs args);
13 | public delegate void BattlEyeDisconnectEventHandler(BattlEyeDisconnectEventArgs args);
14 |
15 | public class BattlEyeConnectEventArgs : EventArgs
16 | {
17 | public BattlEyeConnectEventArgs(BattlEyeLoginCredentials loginDetails, BattlEyeConnectionResult connectionResult)
18 | {
19 | LoginDetails = loginDetails;
20 | ConnectionResult = connectionResult;
21 | Message = Helpers.StringValueOf(connectionResult);
22 | }
23 |
24 | public BattlEyeLoginCredentials LoginDetails { get; }
25 | public BattlEyeConnectionResult ConnectionResult { get; }
26 | public string Message { get; }
27 | }
28 |
29 | public class BattlEyeDisconnectEventArgs : EventArgs
30 | {
31 | public BattlEyeDisconnectEventArgs(BattlEyeLoginCredentials loginDetails, BattlEyeDisconnectionType? disconnectionType)
32 | {
33 | LoginDetails = loginDetails;
34 | DisconnectionType = disconnectionType;
35 | Message = Helpers.StringValueOf(disconnectionType);
36 | }
37 |
38 | public BattlEyeLoginCredentials LoginDetails { get; }
39 | public BattlEyeDisconnectionType? DisconnectionType { get; }
40 | public string Message { get; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/BattleNET/BattlEyeDisconnectionType.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System.ComponentModel;
9 |
10 | namespace BattleNET
11 | {
12 | public enum BattlEyeDisconnectionType
13 | {
14 | [Description("Disconnected!")]
15 | Manual,
16 |
17 | [Description("Disconnected! (Connection timeout)")]
18 | ConnectionLost,
19 |
20 | [Description("Disconnected! (Socket Exception)")]
21 | SocketException,
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/BattleNET/BattlEyeMessageEventArgs.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 |
10 | namespace BattleNET
11 | {
12 | public delegate void BattlEyeMessageEventHandler(BattlEyeMessageEventArgs args);
13 |
14 | public class BattlEyeMessageEventArgs : EventArgs
15 | {
16 | public BattlEyeMessageEventArgs(string message, int id)
17 | {
18 | Message = message;
19 | Id = id;
20 | }
21 |
22 | public string Message { get; }
23 | public int Id { get; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/BattleNET/BattlEyePacketType.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | namespace BattleNET
9 | {
10 | enum BattlEyePacketType
11 | {
12 | Login,
13 | Command,
14 | Acknowledge
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/BattleNET/BattleEyeLoginCredentials.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System.Net;
9 |
10 | namespace BattleNET
11 | {
12 | public struct BattlEyeLoginCredentials
13 | {
14 | public BattlEyeLoginCredentials(IPAddress host, int port, string password)
15 | : this()
16 | {
17 | Host = host;
18 | Port = port;
19 | Password = password;
20 | }
21 |
22 | public IPAddress Host { get; set; }
23 | public int Port { get; set; }
24 | public string Password { get; set; }
25 | }
26 | }
--------------------------------------------------------------------------------
/BattleNET/BattleNET.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | 1.3.4
6 | Marcel de Vries
7 | Copyright © 2018
8 | https://github.com/dddlazer/BattleNET/blob/master/license.txt
9 | true
10 | https://github.com/dddlazer/BattleNET
11 | battleye rcon arma server management
12 | 1.3.4.0
13 | 1.3.4.0
14 | https://github.com/dddlazer/BattleNET
15 | git
16 | false
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/BattleNET/BattleNET.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BattleNET
5 | 1.3.4.0
6 | BattleNET
7 | Marcel de Vries
8 | Marcel de Vries
9 | https://github.com/dddlazer/BattleNET/blob/master/license.txt
10 | https://github.com/dddlazer/BattleNET
11 | false
12 | BattlEye Library
13 | Initial NuGet release.
14 | Copyright 2018
15 | battleye rcon arma server management
16 |
17 |
18 |
--------------------------------------------------------------------------------
/BattleNET/CRC32.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 | using System.Security.Cryptography;
10 |
11 | namespace BattleNET
12 | {
13 | // ReSharper disable once InconsistentNaming
14 | internal class CRC32 : HashAlgorithm
15 | {
16 | public const UInt32 DefaultPolynomial = 0xedb88320;
17 | public const UInt32 DefaultSeed = 0xffffffff;
18 | private static UInt32[] _defaultTable;
19 |
20 | private readonly UInt32 _seed;
21 | private readonly UInt32[] _table;
22 | private UInt32 _hash;
23 |
24 | public CRC32()
25 | {
26 | _table = InitializeTable(DefaultPolynomial);
27 | _seed = DefaultSeed;
28 | Initialize();
29 | }
30 |
31 | public CRC32(UInt32 polynomial, UInt32 seed)
32 | {
33 | _table = InitializeTable(polynomial);
34 | _seed = seed;
35 | Initialize();
36 | }
37 |
38 | public override int HashSize
39 | {
40 | get { return 32; }
41 | }
42 |
43 | public override sealed void Initialize()
44 | {
45 | _hash = _seed;
46 | }
47 |
48 | protected override void HashCore(byte[] buffer, int start, int length)
49 | {
50 | _hash = CalculateHash(_table, _hash, buffer, start, length);
51 | }
52 |
53 | protected override byte[] HashFinal()
54 | {
55 | byte[] hashBuffer = UInt32ToBigEndianBytes(~_hash);
56 | HashValue = hashBuffer;
57 | return hashBuffer;
58 | }
59 |
60 | public static UInt32 Compute(byte[] buffer)
61 | {
62 | return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
63 | }
64 |
65 | public static UInt32 Compute(UInt32 seed, byte[] buffer)
66 | {
67 | return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
68 | }
69 |
70 | public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
71 | {
72 | return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
73 | }
74 |
75 | private static UInt32[] InitializeTable(UInt32 polynomial)
76 | {
77 | if (polynomial == DefaultPolynomial && _defaultTable != null)
78 | return _defaultTable;
79 |
80 | var createTable = new UInt32[256];
81 | for (int i = 0; i < 256; i++)
82 | {
83 | var entry = (UInt32)i;
84 | for (int j = 0; j < 8; j++)
85 | if ((entry & 1) == 1)
86 | entry = (entry >> 1) ^ polynomial;
87 | else
88 | entry = entry >> 1;
89 | createTable[i] = entry;
90 | }
91 |
92 | if (polynomial == DefaultPolynomial)
93 | _defaultTable = createTable;
94 |
95 | return createTable;
96 | }
97 |
98 | private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
99 | {
100 | UInt32 crc = seed;
101 | for (int i = start; i < size; i++)
102 | unchecked
103 | {
104 | crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
105 | }
106 | return crc;
107 | }
108 |
109 | private byte[] UInt32ToBigEndianBytes(UInt32 x)
110 | {
111 | return new[]
112 | {
113 | (byte) ((x >> 24) & 0xff),
114 | (byte) ((x >> 16) & 0xff),
115 | (byte) ((x >> 8) & 0xff),
116 | (byte) (x & 0xff)
117 | };
118 | }
119 | }
120 | }
--------------------------------------------------------------------------------
/BattleNET/Helpers.cs:
--------------------------------------------------------------------------------
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 | * BattleNET v1.3.4 - BattlEye Library and Client *
3 | * *
4 | * Copyright (C) 2018 by it's authors. *
5 | * Some rights reserved. See license.txt, authors.txt. *
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7 |
8 | using System;
9 | using System.ComponentModel;
10 | using System.Globalization;
11 | using System.Reflection;
12 | using System.Text;
13 |
14 | namespace BattleNET
15 | {
16 | internal class Helpers
17 | {
18 | public static string Hex2Ascii(string hexString)
19 | {
20 | var j = 0;
21 | var tmp = new byte[(hexString.Length) / 2];
22 | for (var i = 0; i <= hexString.Length - 2; i += 2)
23 | {
24 | tmp[j] = (byte)Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), NumberStyles.HexNumber));
25 |
26 | j++;
27 | }
28 | return Bytes2String(tmp);
29 | }
30 |
31 | public static byte[] String2Bytes(string s)
32 | {
33 | return Encoding.GetEncoding(1252).GetBytes(s);
34 | }
35 |
36 | public static string Bytes2String(byte[] bytes)
37 | {
38 | return Encoding.GetEncoding(1252).GetString(bytes);
39 | }
40 |
41 | public static string Bytes2String(byte[] bytes, int index, int count)
42 | {
43 | return Encoding.UTF8.GetString(bytes, index, count);
44 | }
45 |
46 | public static string StringValueOf(Enum value)
47 | {
48 | FieldInfo fi = value.GetType().GetField(value.ToString());
49 | var attributes =
50 | (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
51 | if (attributes.Length > 0)
52 | {
53 | return attributes[0].Description;
54 | }
55 | else
56 | {
57 | return value.ToString();
58 | }
59 | }
60 |
61 | public static object EnumValueOf(string value, Type enumType)
62 | {
63 | string[] names = Enum.GetNames(enumType);
64 | foreach (string name in names)
65 | {
66 | if (StringValueOf((Enum)Enum.Parse(enumType, name)).Equals(value))
67 | {
68 | return Enum.Parse(enumType, name);
69 | }
70 | }
71 |
72 | throw new ArgumentException("The string is not a description or value of the specified enum.");
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BattleNET [](https://www.nuget.org/packages/BattleNET/) #
2 |
3 | BattleNET is a C# (.NET) library and client for the BattlEye protocol.
4 |
5 | #### Source code content ####
6 |
7 | ```
8 | BattleNET - The library
9 | BattleNET client - The client
10 | authors.txt - BattleNET authors
11 | BattleNET.sln - BattleNET solution
12 | changelog.txt - Changes made to BattleNET
13 | license.txt - The LGPL license
14 | README.md - This file
15 | ```
16 |
17 | #### BattleNET client ####
18 |
19 | The BattleNET client basically replicates the official BE RCon client but uses the BattleNET library to do all of it's work.
20 |
21 | Usage:
22 |
23 | ```
24 | BattleNET client.exe -host [ipaddress] -port [portnumber] -password [password] -command [command]
25 | ```
26 | Command line options:
27 | ```
28 | -host [ipaddress] RCon ip address
29 | -port [portnumber] RCon port number
30 | -password [password] RCon password
31 | -command [command] Sends command to RCon server and exits again
32 | Note: If no arguments are specified the client will ask for the login details.
33 | ```
34 |
35 | Examples:
36 |
37 | ```
38 | BattleNET client.exe -host 127.0.0.1 -port 2302 -password 123456789
39 | BattleNET client.exe -host 127.0.0.1 -port 2302 -password 123456789 -command "say -1 Hello World!"
40 | ```
41 |
42 | #### BattleNET library ####
43 |
44 | Implementation sample:
45 | https://github.com/ziellos2k/BattleNET/blob/master/BattleNET%20client/Program.cs
46 |
--------------------------------------------------------------------------------
/authors.txt:
--------------------------------------------------------------------------------
1 | Marcel de Vries
2 | Robert van der Boorn
3 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
1 | v1.3.4
2 | * Convert thread to async method (https://github.com/tym32167)
3 | * Move to .NET Standard 2.0 (https://github.com/tym32167)
4 | * Limit connection attempts to 100 to get rid of the stack overflow issue (https://github.com/tym32167)
5 |
6 | v1.3.3
7 | * Improved command queuing system (Fixes #37)
8 |
9 | v1.3.2
10 | * Fixed an issue with banlists (Thank you DomiStyle)
11 | * Added "admins" command, which returns all connected RCon clients (Thank you maca134)
12 |
13 | v1.3.1
14 | * Fixed an issue where the (first) command would be sent twice
15 | * Fixed an issue where the library would lose connection after a long time, depending on server load (Thanks to EPM Cortez for finding the issue)
16 |
17 | v1.3
18 | * Client now has DNS support
19 | * BattlEyeLoginCredentials.Host changed from string to IPAddress
20 | * Increased timeout check sleep a bit (1 second)
21 | * Increased time before a packet gets resend (2 seconds)
22 | * Proper UTF8 support
23 | * The usual bugfixes and cleanups
24 |
25 | v1.2.1
26 | * Increased max socket receive buffer (fixes long ban lists)
27 |
28 | v1.2
29 | * Removed system messages (Connected, Disconnected, etc) from library
30 | * Changed ReconnectOnPacketLoss and IsConnected to properties
31 | * New connect event (success, invalid login, host unreachable)
32 | * SendCommandPacket() now returns an identifier which can be used in message filtering
33 | * Renamed SendCommandPacket() to SendCommand(), kinda...
34 | * Bugfixes and cleanups
35 |
36 | v1.1
37 | * Different method to construct packets
38 | * Some fixes and cleanups
39 | * Did licensing the right way
40 |
41 | v1.0.2
42 | * Fixed predefined commands, they now work actually. :)
43 |
44 | v1.0.1
45 | * Fixed a bug where the lib would send the 'say' command twice
46 |
47 | v1.0
48 | * Started using proper version numbers... :)
49 |
50 | 20121217.1
51 | * Library didn't reconnect on connection loss
52 |
53 | 20121217
54 | * Updated predifined commands
55 | * Timeout values decreased for faster connection drop detection
56 | * UTF8 support
57 | * Better handling of dropped packets (client -> server)
58 | * Packet receiving is now asynchronous
59 | * Some other fixes and cleanups
60 | * Client now accepts command line arguments
61 |
62 | 20120821
63 | * Hackish fix for not handling very long ban files
64 |
65 | 20120717
66 | * Decreased keep alive packet interval and timeout timer
67 | * Changed Encoding.Default to Encoding.GetEncoding(1252) as Default is variable across systems (also makes it compatible with Linux/mono)
68 |
69 | 20120706
70 | * Fixed autoreconnect not working
71 |
72 | 20120704
73 | * License added
74 |
75 | 20120628
76 | * Complete BattlEye protocol implementation
77 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------