Release
This commit is contained in:
parent
be85cc38af
commit
91adcda082
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
340
.gitignore
vendored
Normal file
340
.gitignore
vendored
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUNIT
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# JustCode is a .NET coding add-in
|
||||||
|
.JustCode
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- Backup*.rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
.idea/
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
168
BottlEye/BottlEye.vcxproj
Normal file
168
BottlEye/BottlEye.vcxproj
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>BottlEye</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<SpectreMitigation>false</SpectreMitigation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<IncludePath>D:\Sync\Programming\C++\Libraries\Include;$(IncludePath)</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;BOTTLEYE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;BOTTLEYE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;BOTTLEYE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;BOTTLEYE_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="D:\Sync\Programming\C++\Libraries\fmt\format.cc" />
|
||||||
|
<ClCompile Include="D:\Sync\Programming\C++\Libraries\fmt\posix.cc" />
|
||||||
|
<ClCompile Include="delegate.cpp" />
|
||||||
|
<ClCompile Include="emulator.cpp" />
|
||||||
|
<ClCompile Include="entry.cpp" />
|
||||||
|
<ClCompile Include="singleton.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="be_client.hpp" />
|
||||||
|
<ClInclude Include="be_packet.hpp" />
|
||||||
|
<ClInclude Include="delegate.hpp" />
|
||||||
|
<ClInclude Include="emulator.hpp" />
|
||||||
|
<ClInclude Include="loggr.hpp" />
|
||||||
|
<ClInclude Include="singleton.hpp" />
|
||||||
|
<ClInclude Include="spinner.hpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
68
BottlEye/BottlEye.vcxproj.filters
Normal file
68
BottlEye/BottlEye.vcxproj.filters
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files\fmt">
|
||||||
|
<UniqueIdentifier>{0c4a0d52-9a82-4d3f-9a16-c7500b15325c}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files\logging">
|
||||||
|
<UniqueIdentifier>{1c69057d-6d08-43b0-90f1-f14b1a42e09b}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files\battleye">
|
||||||
|
<UniqueIdentifier>{485f60e6-89b2-4606-8d47-d79821e828ba}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files\battleye">
|
||||||
|
<UniqueIdentifier>{16a4f5db-842f-48d4-ba43-77c6665893b9}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="entry.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="delegate.cpp">
|
||||||
|
<Filter>Source Files\battleye</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="emulator.cpp">
|
||||||
|
<Filter>Source Files\battleye</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="singleton.cpp">
|
||||||
|
<Filter>Source Files\battleye</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Sync\Programming\C++\Libraries\fmt\format.cc">
|
||||||
|
<Filter>Source Files\fmt</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Sync\Programming\C++\Libraries\fmt\posix.cc">
|
||||||
|
<Filter>Source Files\fmt</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="spinner.hpp">
|
||||||
|
<Filter>Header Files\logging</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="loggr.hpp">
|
||||||
|
<Filter>Header Files\logging</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="be_client.hpp">
|
||||||
|
<Filter>Header Files\battleye</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="delegate.hpp">
|
||||||
|
<Filter>Header Files\battleye</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="singleton.hpp">
|
||||||
|
<Filter>Header Files\battleye</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="be_packet.hpp">
|
||||||
|
<Filter>Header Files\battleye</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="emulator.hpp">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
58
BottlEye/be_client.hpp
Normal file
58
BottlEye/be_client.hpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace battleye
|
||||||
|
{
|
||||||
|
enum instance_status
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
NOT_INITIALIZED,
|
||||||
|
SUCCESSFULLY_INITIALIZED,
|
||||||
|
DESTROYING,
|
||||||
|
DESTROYED
|
||||||
|
};
|
||||||
|
|
||||||
|
struct becl_game_data
|
||||||
|
{
|
||||||
|
char* game_version;
|
||||||
|
std::uint32_t address;
|
||||||
|
std::uint16_t port;
|
||||||
|
|
||||||
|
// FUNCTIONS
|
||||||
|
using print_message_t = void(*)(char* message);
|
||||||
|
print_message_t print_message;
|
||||||
|
|
||||||
|
using request_restart_t = void(*)(std::uint32_t reason);
|
||||||
|
request_restart_t request_restart;
|
||||||
|
|
||||||
|
using send_packet_t = void(*)(void* packet, std::uint32_t length);
|
||||||
|
send_packet_t send_packet;
|
||||||
|
|
||||||
|
using disconnect_peer_t = void(*)(std::uint8_t* guid, std::uint32_t guid_length, char* reason);
|
||||||
|
disconnect_peer_t disconnect_peer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct becl_be_data
|
||||||
|
{
|
||||||
|
using exit_t = bool(*)();
|
||||||
|
exit_t exit;
|
||||||
|
|
||||||
|
using run_t = void(*)();
|
||||||
|
run_t run;
|
||||||
|
|
||||||
|
using command_t = void(*)(char* command);
|
||||||
|
command_t command;
|
||||||
|
|
||||||
|
using received_packet_t = void(*)(std::uint8_t* received_packet, std::uint32_t length);
|
||||||
|
received_packet_t received_packet;
|
||||||
|
|
||||||
|
using on_receive_auth_ticket_t = void(*)(std::uint8_t* ticket, std::uint32_t length);
|
||||||
|
on_receive_auth_ticket_t on_receive_auth_ticket;
|
||||||
|
|
||||||
|
using add_peer_t = void(*)(std::uint8_t* guid, std::uint32_t guid_length);
|
||||||
|
add_peer_t add_peer;
|
||||||
|
|
||||||
|
using remove_peer_t = void(*)(std::uint8_t* guid, std::uint32_t guid_length);
|
||||||
|
remove_peer_t remove_peer;
|
||||||
|
};
|
||||||
|
}
|
49
BottlEye/be_packet.hpp
Normal file
49
BottlEye/be_packet.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace battleye
|
||||||
|
{
|
||||||
|
enum packet_id : std::uint8_t
|
||||||
|
{
|
||||||
|
INIT = 0x00,
|
||||||
|
START = 0x02,
|
||||||
|
REQUEST = 0x04,
|
||||||
|
RESPONSE = 0x05,
|
||||||
|
HEARTBEAT = 0x09,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct be_fragment
|
||||||
|
{
|
||||||
|
std::uint8_t count;
|
||||||
|
std::uint8_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct be_packet_header
|
||||||
|
{
|
||||||
|
std::uint8_t id;
|
||||||
|
std::uint8_t sequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct be_packet : be_packet_header
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
be_fragment fragment;
|
||||||
|
|
||||||
|
// DATA STARTS AT body[1] IF PACKET IS FRAGMENTED
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
std::uint8_t no_fragmentation_flag;
|
||||||
|
std::uint8_t body[0];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool fragmented()
|
||||||
|
{
|
||||||
|
return this->fragment.count != 0x00;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
}
|
198
BottlEye/delegate.cpp
Normal file
198
BottlEye/delegate.cpp
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
#include "delegate.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
#include "be_packet.hpp"
|
||||||
|
#include <array>
|
||||||
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
battleye::becl_game_data::send_packet_t battleye::delegate::o_send_packet = nullptr;
|
||||||
|
|
||||||
|
bool battleye::delegate::exit()
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("BottlEye exiting.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::run()
|
||||||
|
{
|
||||||
|
//singleton::emulator.console().log("Executed 'run'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::command(char* command)
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("Executed 'command'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::received_packet(std::uint8_t* received_packet, std::uint32_t length)
|
||||||
|
{
|
||||||
|
auto header = reinterpret_cast<battleye::be_packet*>(received_packet);
|
||||||
|
|
||||||
|
switch (header->id)
|
||||||
|
{
|
||||||
|
case battleye::packet_id::INIT:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("INIT");
|
||||||
|
singleton::emulator.console().log_indented<1, true>("Size (bytes)", length);
|
||||||
|
|
||||||
|
auto info_packet = battleye::be_packet{};
|
||||||
|
info_packet.id = battleye::packet_id::INIT;
|
||||||
|
info_packet.sequence = 0x05;
|
||||||
|
|
||||||
|
battleye::delegate::o_send_packet(&info_packet, sizeof(info_packet));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case battleye::packet_id::START:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("START");
|
||||||
|
singleton::emulator.console().log_indented<1, true>("Size (bytes)", length);
|
||||||
|
|
||||||
|
battleye::delegate::o_send_packet(received_packet, sizeof(battleye::be_packet_header));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case battleye::packet_id::REQUEST:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log<true>("REQUEST", header->sequence);
|
||||||
|
|
||||||
|
// HANDLE PACKET FRAGMENTATION
|
||||||
|
if (header->fragmented())
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log_indented<1, true>("Fragment count", header->fragment.count);
|
||||||
|
singleton::emulator.console().log_indented<1, true>("Fragment index", header->fragment.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IF NOT FRAGMENTED RESPOND IMMEDIATELY, ELSE ONLY RESPOND TO THE LAST FRAGMENT
|
||||||
|
const auto respond = !header->fragmented() || (header->fragment.index == header->fragment.count - 1);
|
||||||
|
if (!respond)
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log_indented<1>("Ignoring!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEND BACK HEADER
|
||||||
|
battleye::delegate::o_send_packet(received_packet, sizeof(battleye::be_packet_header));
|
||||||
|
singleton::emulator.console().log_indented<1>("Sending back header...");
|
||||||
|
|
||||||
|
switch (header->sequence)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log_indented<1>("Replaying!");
|
||||||
|
|
||||||
|
battleye::delegate::respond(header->sequence,
|
||||||
|
{
|
||||||
|
// REDACTED
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x02:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log_indented<1>("Replaying!");
|
||||||
|
|
||||||
|
battleye::delegate::respond(header->sequence,
|
||||||
|
{
|
||||||
|
// REDACTED
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log_indented<1>("Replying!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case battleye::packet_id::RESPONSE:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log<true>("Acknowledgement of packet", header->sequence);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case battleye::packet_id::HEARTBEAT:
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("Heartbeat");
|
||||||
|
battleye::delegate::o_send_packet(received_packet, length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
//battleye::delegate::o_send_packet(received_packet, sizeof(battleye::be_packet));
|
||||||
|
|
||||||
|
singleton::emulator.console().log<true>("Unhandled packet", header->id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::on_receive_auth_ticket(std::uint8_t* ticket, std::uint32_t length)
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("Executed 'on_receive_auth_ticket'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::add_peer(std::uint8_t* guid, std::uint32_t guid_length)
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("Executed 'add_peer'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::remove_peer(std::uint8_t* guid, std::uint32_t guid_length)
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("Executed 'remove_peer'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::respond(std::uint8_t response_index, std::initializer_list<std::uint8_t> data)
|
||||||
|
{
|
||||||
|
// SETUP RESPONSE PACKET WITH TWO-BYTE HEADER + NO-FRAGMENTATION TOGGLE
|
||||||
|
|
||||||
|
const auto size = sizeof(battleye::be_packet_header) + sizeof(battleye::be_fragment::count) + data.size();
|
||||||
|
|
||||||
|
auto packet = std::make_unique<std::uint8_t[]>(size);
|
||||||
|
auto packet_buffer = packet.get();
|
||||||
|
|
||||||
|
packet_buffer[0] = (battleye::packet_id::RESPONSE); // PACKET ID
|
||||||
|
packet_buffer[1] = (response_index - 1); // RESPONSE INDEX
|
||||||
|
packet_buffer[2] = (0x00); // FRAGMENTATION DISABLED
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < data.size(); i++)
|
||||||
|
{
|
||||||
|
packet_buffer[3 + i] = data.begin()[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
battleye::delegate::o_send_packet(packet_buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void battleye::delegate::respond_fragmented(std::uint8_t response_index, battleye::be_fragment fragment, std::initializer_list<std::uint8_t> data)
|
||||||
|
{
|
||||||
|
// SETUP RESPONSE PACKET WITH TWO-BYTE HEADER + FRAGMENTATION HEADER
|
||||||
|
|
||||||
|
const auto size = sizeof(battleye::packet_id) + sizeof(response_index) + sizeof(fragment) + data.size();
|
||||||
|
|
||||||
|
if (size != 0x400 && fragment.index != fragment.count - 1) // ALL FRAGMENTS BUT THE LAST IS 0x400 LONG
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log_error("Sending too little fragment...");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet = std::make_unique<std::uint8_t[]>(size);
|
||||||
|
auto packet_buffer = packet.get();
|
||||||
|
|
||||||
|
packet_buffer[0] = battleye::packet_id::RESPONSE; // PACKET ID
|
||||||
|
packet_buffer[1] = response_index - 1; // RESPONSE INDEX
|
||||||
|
packet_buffer[2] = fragment.count; // FRAGMENTATION COUNT
|
||||||
|
packet_buffer[3] = fragment.index; // FRAGMENTATION INDEX
|
||||||
|
|
||||||
|
for (size_t i = 0; i < data.size(); i++)
|
||||||
|
{
|
||||||
|
packet_buffer[4 + i] = data.begin()[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG PRINT
|
||||||
|
battleye::delegate::o_send_packet(packet_buffer, size);
|
||||||
|
}
|
20
BottlEye/delegate.hpp
Normal file
20
BottlEye/delegate.hpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
#include "be_client.hpp"
|
||||||
|
#include "be_packet.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace battleye::delegate
|
||||||
|
{
|
||||||
|
extern battleye::becl_game_data::send_packet_t o_send_packet;
|
||||||
|
|
||||||
|
bool exit();
|
||||||
|
void run();
|
||||||
|
void command(char* command);
|
||||||
|
void received_packet(std::uint8_t* received_packet, std::uint32_t length);
|
||||||
|
void on_receive_auth_ticket(std::uint8_t* ticket, std::uint32_t length);
|
||||||
|
void add_peer(std::uint8_t* guid, std::uint32_t guid_length);
|
||||||
|
void remove_peer(std::uint8_t* guid, std::uint32_t guid_length);
|
||||||
|
|
||||||
|
void respond(std::uint8_t response_index, std::initializer_list<std::uint8_t> data);
|
||||||
|
void respond_fragmented(std::uint8_t response_index, battleye::be_fragment fragment, std::initializer_list<std::uint8_t> data);
|
||||||
|
}
|
25
BottlEye/emulator.cpp
Normal file
25
BottlEye/emulator.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include "emulator.hpp"
|
||||||
|
#include "delegate.hpp"
|
||||||
|
|
||||||
|
void battleye::emulator::setup_battleye(battleye::becl_game_data* game_data,
|
||||||
|
battleye::becl_be_data* client_data)
|
||||||
|
{
|
||||||
|
this->console().log("Setting up game_data...");
|
||||||
|
this->console().log_indented<1>("Game version", game_data->game_version);
|
||||||
|
this->console().log_indented<1, true>("Address", game_data->address);
|
||||||
|
this->console().log_indented<1, true>("Port", game_data->port);
|
||||||
|
|
||||||
|
// CACHE RELEVANT FUNCTIONS
|
||||||
|
battleye::delegate::o_send_packet = game_data->send_packet;
|
||||||
|
|
||||||
|
// SETUP CLIENT STRUCTURE
|
||||||
|
client_data->exit = battleye::delegate::exit;
|
||||||
|
client_data->run = battleye::delegate::run;
|
||||||
|
client_data->command = battleye::delegate::command;
|
||||||
|
client_data->received_packet = battleye::delegate::received_packet;
|
||||||
|
client_data->on_receive_auth_ticket = battleye::delegate::on_receive_auth_ticket;
|
||||||
|
client_data->add_peer = battleye::delegate::add_peer;
|
||||||
|
client_data->remove_peer = battleye::delegate::remove_peer;
|
||||||
|
|
||||||
|
this->console().log_indented<1>("Done!");
|
||||||
|
}
|
24
BottlEye/emulator.hpp
Normal file
24
BottlEye/emulator.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include "loggr.hpp"
|
||||||
|
#include "be_client.hpp"
|
||||||
|
|
||||||
|
namespace battleye
|
||||||
|
{
|
||||||
|
class emulator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
emulator() : m_logger() {}
|
||||||
|
|
||||||
|
void setup_battleye(battleye::becl_game_data* game_data,
|
||||||
|
battleye::becl_be_data* client_data);
|
||||||
|
|
||||||
|
inline loggr& console()
|
||||||
|
{
|
||||||
|
return this->m_logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
loggr m_logger;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
34
BottlEye/entry.cpp
Normal file
34
BottlEye/entry.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include "be_client.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
// BEClient_x64!Init
|
||||||
|
__declspec(dllexport)
|
||||||
|
battleye::instance_status Init(std::uint64_t integration_version,
|
||||||
|
battleye::becl_game_data* game_data,
|
||||||
|
battleye::becl_be_data* client_data)
|
||||||
|
{
|
||||||
|
singleton::emulator.console().log("Initialising BottlEye!");
|
||||||
|
singleton::emulator.console().log_indented<1>("Brought to you by: https://secret.club/");
|
||||||
|
singleton::emulator.setup_battleye(game_data, client_data);
|
||||||
|
|
||||||
|
return battleye::instance_status::SUCCESSFULLY_INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BEClient_x64!GetVer
|
||||||
|
__declspec(dllexport)
|
||||||
|
std::uint32_t GetVer()
|
||||||
|
{
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::uint32_t __stdcall DllMain(const void* mod_instance [[maybe_unused]],
|
||||||
|
const std::uint32_t call_reason [[maybe_unused]],
|
||||||
|
const void* reserved [[maybe_unused]])
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
130
BottlEye/loggr.hpp
Normal file
130
BottlEye/loggr.hpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
#pragma once
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <fmt\core.h>
|
||||||
|
|
||||||
|
class loggr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
loggr()
|
||||||
|
{
|
||||||
|
// SETUP CONSOLE IF NOT PRESENT
|
||||||
|
auto console_window = GetConsoleWindow();
|
||||||
|
if (console_window == 0x00)
|
||||||
|
{
|
||||||
|
if (!AllocConsole())
|
||||||
|
{
|
||||||
|
// ???? SHOULD NEVER HAPPEN
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::freopen("CONOUT$", "w", stdout);
|
||||||
|
|
||||||
|
m_did_allocate_console = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~loggr()
|
||||||
|
{
|
||||||
|
// FREE CONSOLE IF DYNAMICALLY ALLOCATED
|
||||||
|
if (m_did_allocate_console)
|
||||||
|
{
|
||||||
|
const auto freed = FreeConsole();
|
||||||
|
|
||||||
|
if (!freed)
|
||||||
|
{
|
||||||
|
// ??
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONSOLE LOGGING FUNCTIONS
|
||||||
|
template <class...T>
|
||||||
|
inline void log_raw(T... arguments) const
|
||||||
|
{
|
||||||
|
fmt::print(arguments...);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void log(std::string_view message) const
|
||||||
|
{
|
||||||
|
fmt::print("[+] {}\n", message);
|
||||||
|
}
|
||||||
|
inline void log_error(std::string_view message) const
|
||||||
|
{
|
||||||
|
fmt::print("[!] {}\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool hex = false, class T>
|
||||||
|
inline void log(std::string_view variable_name, const T& value) const
|
||||||
|
{
|
||||||
|
constexpr auto format_string = hex ?
|
||||||
|
"[=] {:<15} {:X}\n" :
|
||||||
|
"[=] {:<15} {}\n";
|
||||||
|
|
||||||
|
fmt::print(format_string, variable_name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t indentation>
|
||||||
|
inline void log_error_indented(std::string_view message) const
|
||||||
|
{
|
||||||
|
fmt::print("[!] {:<{}} {}\n", ' ', indentation, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t indentation>
|
||||||
|
inline void log_indented(std::string_view message) const
|
||||||
|
{
|
||||||
|
fmt::print("[+] {:<{}} {}\n", ' ', indentation, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t indentation, bool hex = false, class T>
|
||||||
|
inline void log_indented(std::string_view variable_name, const T& value) const
|
||||||
|
{
|
||||||
|
constexpr auto format_string = hex ?
|
||||||
|
"[=] {:<{}} {:.<15} {:02X}\n" :
|
||||||
|
"[=] {:<{}} {:.<15} {}\n";
|
||||||
|
|
||||||
|
fmt::print(format_string, ' ', indentation, variable_name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CONSOLE MODIFICATION FUNCTIONS
|
||||||
|
inline COORD get_position() const
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info))
|
||||||
|
{
|
||||||
|
this->log_error("Failed to get cursor position");
|
||||||
|
return { 0, 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.dwCursorPosition;
|
||||||
|
}
|
||||||
|
inline void set_position(const COORD cursor) const
|
||||||
|
{
|
||||||
|
if (!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cursor))
|
||||||
|
{
|
||||||
|
this->log_error("Failed to set cursor position");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void clear_line() const
|
||||||
|
{
|
||||||
|
// GET CURSOR POSITION
|
||||||
|
auto position = this->get_position();
|
||||||
|
|
||||||
|
|
||||||
|
position.X = 0;
|
||||||
|
|
||||||
|
// CLEAR LINE
|
||||||
|
DWORD count = 0;
|
||||||
|
const auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
auto result = FillConsoleOutputCharacter(handle, ' ', 150, position, &count);
|
||||||
|
|
||||||
|
// RESET POSITION
|
||||||
|
set_position(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_did_allocate_console = false;
|
||||||
|
|
||||||
|
};
|
3
BottlEye/singleton.cpp
Normal file
3
BottlEye/singleton.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "singleton.hpp"
|
||||||
|
|
||||||
|
battleye::emulator singleton::emulator = battleye::emulator();
|
7
BottlEye/singleton.hpp
Normal file
7
BottlEye/singleton.hpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
#include "emulator.hpp"
|
||||||
|
|
||||||
|
namespace singleton
|
||||||
|
{
|
||||||
|
extern battleye::emulator emulator;
|
||||||
|
}
|
77
BottlEye/spinner.hpp
Normal file
77
BottlEye/spinner.hpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#pragma once
|
||||||
|
#include "loggr.hpp"
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
class spinner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
spinner(loggr* new_logger) : m_logger(new_logger) { }
|
||||||
|
|
||||||
|
static constexpr std::uint8_t CHARACTER_SEQUENCE[] =
|
||||||
|
{
|
||||||
|
'|', '/', '-', '\\'
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void start()
|
||||||
|
{
|
||||||
|
if (this->m_active)
|
||||||
|
{
|
||||||
|
this->m_logger->log_error("Cannot initialise spinner object more than once!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void update()
|
||||||
|
{
|
||||||
|
if (!this->m_active)
|
||||||
|
{
|
||||||
|
this->m_logger->log_error("Cannot initialise spinner object without initialization!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GET TIME SINCE LAST UPDATE
|
||||||
|
using clock_t = std::chrono::high_resolution_clock;
|
||||||
|
const auto time = clock_t::now();
|
||||||
|
const auto time_delta = time - m_last_update_time;
|
||||||
|
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(time_delta);
|
||||||
|
|
||||||
|
|
||||||
|
// ONLY UPDATE SPINNER EVERY x MS
|
||||||
|
constexpr auto update_time = 150;
|
||||||
|
if (duration.count() <= update_time)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE THE SPINNER CHARACTER
|
||||||
|
this->m_logger->clear_line();
|
||||||
|
this->m_logger->log_raw("[{}]", static_cast<char>(spinner::CHARACTER_SEQUENCE[this->m_seq_index]));
|
||||||
|
|
||||||
|
// INCREMENT AND WRAP
|
||||||
|
this->m_seq_index++;
|
||||||
|
this->m_seq_index %= sizeof(spinner::CHARACTER_SEQUENCE);
|
||||||
|
|
||||||
|
this->m_last_update_time = time;
|
||||||
|
|
||||||
|
}
|
||||||
|
inline void stop()
|
||||||
|
{
|
||||||
|
if (!this->m_active)
|
||||||
|
{
|
||||||
|
this->m_logger->log_error("Spinner is not active!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_logger->clear_line();
|
||||||
|
this->m_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const loggr* m_logger;
|
||||||
|
bool m_active = false;
|
||||||
|
std::size_t m_seq_index = 0;
|
||||||
|
std::chrono::steady_clock::time_point m_last_update_time;
|
||||||
|
};
|
31
Bottleye.sln
Normal file
31
Bottleye.sln
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29609.76
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BottlEye", "BottlEye\BottlEye.vcxproj", "{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Release|x64.Build.0 = Release|x64
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{9A6F6F8A-15CB-4276-BD96-1BA5E91DEED6}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {1C8FC625-02F3-4B76-A958-B1AED03C2B75}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
4
README.md
Normal file
4
README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<img src="./bottleye_logo.png" width="500">
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
BottlEye is an usermode emulator for the commercial anti-cheat [BattlEye](battleye.com) that works by recreating the anti-cheat
|
BIN
bottleye_logo.png
Normal file
BIN
bottleye_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 216 KiB |
1
bottleye_logo.svg
Normal file
1
bottleye_logo.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 276.7 330.5"><path fill="#f3e0cd" d="M148.4 199.2s-3.3-5.4-14.4-10.9-12-4.4-30.2-11.5-41-15.6-41.8-18 3.5-7.7 16.5-15.6 15.9-11.4 34.1-14.8c11.6-2.2 20.7-2.3 29.7-2.4 4.8 0 9.7-.8 15-.7 14.5-3.4 16-7 13.8-10s-20.1.3-22.7-1.5 3.8-4.1 12.2-6.5 13.8-1 21.7-2.4 6.2-4 2.6-6-15.1-2-17-2.4-4.8-1.3-3.7-2.7 3.5-3.5 6-3.6 6.5 2.5 9.1 0-2.6-6.6-6-7.6-13.4 2.2-16 1.2 1.5-3.7 5.3-5 9.8-1.7 10.6-2.4c1.5-1.2 2.7-4.7 1.5-5.3s-10.4-2.7-23.3 3-28.3 19.7-28.3 19.7-3 4.7-29.4 15.2-50.4 14.6-74.1 26.2-23.5 29.5-12 42.3 12.5 14.3 37.4 29 52.2 34.7 78 33z"/><path fill="#feed00" d="M251.2 288.3V199s-31.7 1.6-44 0-64.4-11.4-68.3-7.4-25.7 36.8-38.8 60-16.4 36.7-16.4 36.7z"/><path fill="#f6dcc3" d="M152.9 215.8c-7-1.7-1.8-9.4-1.7-18.7 0 0 1.2-13.3-3.3-25.5-3.5-9.6-12.9-21-13.6-24.5a4.4 4.4 0 01.8-3.8c2.6-3.8 6.2-4 11.2-9.2 2.6-2.7 6.1-11 8.8-12.6 2-1.3 2-2.8 4-5.3 1.2-1.6 8.3-1.8 10.6-3.7 1-1 .6-2.6 1.8-4a59.6 59.6 0 0112.9-10.9c6.4-3.9 12.2-6.7 22-4.4s26.1 13 26.1 13l-17.3 69.1s-12.8 24.5-14.7 25.4c-1.7.8-36.9 15.2-46.3 15.2a5.5 5.5 0 01-1.3-.1z"/><g transform="rotate(12 1656 163.6)"><g fill="#fff"><path d="M208.4 581.5a22.2 22.2 0 01-22.4-22.4 22.2 22.2 0 016.6-15.8 20 20 0 0032.3.8 22.2 22.2 0 01-.7 30.9 22.2 22.2 0 01-15.8 6.5z"/><path fill="#313131" d="M208.4 580.5a21.3 21.3 0 0021.4-21.4c0-5-1.7-9.7-4.9-13.5a21 21 0 01-32.4-.8 21.3 21.3 0 00.8 29.5c4 4 9.4 6.2 15 6.2m0 2a23.2 23.2 0 01-23.3-23.4 23.2 23.2 0 017.8-17.4 19 19 0 0032 .7 23.2 23.2 0 01.1 33.3 23.2 23.2 0 01-16.5 6.8z"/></g><path fill="#313131" d="M208.4 573.1a13.5 13.5 0 01-9.8-4.3 15 15 0 01-4.1-10.4 15.3 15.3 0 014.1-10.4s6.1 4.1 10.2 4.1c3 0 9.8-3.6 10.3-3a14.7 14.7 0 013.2 9.3 15 15 0 01-4 10.4 13.5 13.5 0 01-10 4.3z"/><circle cx="2.5" cy="2.5" r="2.5" fill="#fff" transform="translate(212.8 553.5)"/><g fill="#fff"><path d="M213.1 588a6.2 6.2 0 01-6.2-6c0-.9.6-3.1 4.2-8.9l3.2-5c1.9 4 5 11.2 5 13.8 0 3.4-2.8 6.2-6.2 6.2z"/><path fill="#313131" d="M214.2 570.2l-2.3 3.5c-3.8 6-4 8-4 8.2a5.2 5.2 0 0010.4 0c0-.6-.3-2.7-2.8-8.5l-1.3-3.2m.3-4s5.8 11.8 5.8 15.7a7.2 7.2 0 01-14.4 0c0-4 8.6-15.7 8.6-15.7z"/></g></g><path fill="#f2f2f2" d="M71.6 32.2v-8.9L98 0l13.3 3.2L155 60.8v10.4l20.5 36.6-11.7 9.7-24.1-23-6-4.4h-9.3z"/><path fill="#feed01" d="M71.6 32.2l51.2-13.9 32 42.5v10.4l20.6 36.6-11.7 9.7-24.1-23-6-4.4h-9.3z" opacity=".7"/><path fill="#2e2e41" d="M199 92.3c1.2-1.4 8.9-4 16.6-1.6s12.2 3.5 22.8 12.4 11.4 10.8 17.8 23.9c5.2 10.4 4.4 28.4 4.6 35.4s2.8 8.8 4.9 11.5c2.5 4.2 2.7 11.9 5.9 19.9 5 12.7 2.9 12 4.1 25 .8 8.5-1 12-1.2 16.3-.1 2 2.5 6.2 2 11-.3 3.3.6 8 0 11.4-.6 3.7-.4 2-2 6.4s-3.6 9.5-4.6 11a115 115 0 01-9.8 12.3c-4.3 5-14.5 4.7-18.5 0s1.1-9.8 2.4-18.5 1.5-9.9 1.6-15.5 2-7.1-2.6-13.4-8.7-6.4-14.4-12.6-5.6-7.8-7.5-13-5.4-7.3-10.5-8.7-9-7.6-10.3-11.7 2.2-12.3 6-18.3 1.5-10.9 5.2-21.9 6.3-13.2 9.6-22 3.3-7.2 3.3-13.7.4-6.8-3.3-12.4-7.3-6.3-10.5-9.2-13-2.6-11.7-4z"/><path fill="#212121" d="M72.8 295.8a10.2 10.2 0 014.3.9 7 7 0 013 2.4 6.2 6.2 0 011 3.6 6.4 6.4 0 01-1 3.6 7.6 7.6 0 01-2.8 2.5 9.1 9.1 0 013.7 3 6.8 6.8 0 011.3 4 6.7 6.7 0 01-1.1 3.9 7.6 7.6 0 01-3.2 2.6 11.1 11.1 0 01-4.7 1H58.9v-27.5zm-1.5 11a4 4 0 002.7-.8 2.7 2.7 0 001-2.2 2.7 2.7 0 00-1-2.1 4 4 0 00-2.7-.9h-6.6v6zm1 11.4a4.4 4.4 0 002.8-.9 3 3 0 001.2-2.4 3 3 0 00-1.2-2.4 4.4 4.4 0 00-2.9-1h-7.5v6.7zm23.7 5.6a11.3 11.3 0 01-5.6-1.5 11 11 0 01-4.1-4 10.2 10.2 0 01-1.6-5.4 10.1 10.1 0 011.6-5.4 11.1 11.1 0 014-4 11.3 11.3 0 015.7-1.4 11.3 11.3 0 015.7 1.5 11.1 11.1 0 014 4 10.1 10.1 0 011.6 5.3 10.2 10.2 0 01-1.5 5.4 11 11 0 01-4.1 4 11.3 11.3 0 01-5.7 1.5zm0-5a5.4 5.4 0 002.9-.8 5.8 5.8 0 002-2.1 6 6 0 00.8-3 5.9 5.9 0 00-.8-3 5.8 5.8 0 00-2-2 5.4 5.4 0 00-2.9-.9 5.4 5.4 0 00-2.8.8A5.8 5.8 0 0091 310a5.9 5.9 0 00-.8 3 6 6 0 00.8 2.9 5.8 5.8 0 002 2.1 5.4 5.4 0 003 .8zm26.5 3.2a7.4 7.4 0 01-2.2 1.3 6.9 6.9 0 01-2.5.5 6 6 0 01-4.5-1.8 6.2 6.2 0 01-1.8-4.6v-10h-2.8v-4.8h2.8v-5.7h5.7v5.7h4.5v4.7h-4.5v9.2a2.5 2.5 0 00.5 1.7 1.8 1.8 0 001.4.6 3.4 3.4 0 001.2-.1 2.2 2.2 0 00.8-.5zm15.8 0a7.4 7.4 0 01-2.2 1.3 6.9 6.9 0 01-2.5.5 6 6 0 01-4.5-1.8 6.2 6.2 0 01-1.8-4.6v-10h-2.8v-4.8h2.8v-5.7h5.7v5.7h4.5v4.7H133v9.2a2.5 2.5 0 00.5 1.7 1.8 1.8 0 001.4.6 3.4 3.4 0 001.2-.1 2.2 2.2 0 00.8-.5zm3.5-26.7h5.9v28h-5.9zm32.3 5.8H159v5.5h13.8v5.3h-13.8v6h15.2v5.4H153v-27.5H174zm9.5 29.4a11 11 0 01-2.7-.4 10.8 10.8 0 01-2.4-.9l1.2-4a9.5 9.5 0 001.5.7 4 4 0 001.2.2 3.2 3.2 0 001.5-.3 2.6 2.6 0 001.1-1.1l.6-1.2-8.6-20.9h6l5.5 14.5 5-14.5h6l-8.4 21.7a11 11 0 01-3.1 4.6 6.7 6.7 0 01-4.4 1.6zm26.5-11.3a8.1 8.1 0 002.9-.5 7.6 7.6 0 002.5-1.5l3.2 3.4a9.6 9.6 0 01-3.7 2.3 13.5 13.5 0 01-4.7.9 11.4 11.4 0 01-5.6-1.4 10.5 10.5 0 01-4-4 10.7 10.7 0 01-1.5-5.5 10.8 10.8 0 011.4-5.5 10.3 10.3 0 014-3.9 10.8 10.8 0 015.4-1.4 10.2 10.2 0 015.5 1.5 9.4 9.4 0 013.6 4.3 16.2 16.2 0 011.3 6.6h-15.6a6 6 0 001.8 3.4 5 5 0 003.5 1.3zm0-12.6a5 5 0 00-3.4 1.2 5.8 5.8 0 00-1.9 3.2h10a5.6 5.6 0 00-1.6-3.2 4.4 4.4 0 00-3.2-1.2z"/></svg>
|
After Width: | Height: | Size: 4.8 KiB |
Loading…
Reference in New Issue
Block a user