mirror of
https://github.com/rehlds/rehlds.git
synced 2024-12-28 15:45:46 +03:00
commit
f48ddcfadd
@ -1,51 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<Filter Include="src">
|
||||
<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;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\blocksort.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\bzlib.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\compress.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\crctable.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\decompress.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\huffman.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\randtable.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.c">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\bzlib_private.h">
|
||||
<Filter>Source Files</Filter>
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -35,20 +35,32 @@ task publishPrepareFiles {
|
||||
}
|
||||
|
||||
pubRootDir.mkdirs()
|
||||
project.file('publish/publishRoot/bin/win32/valve/dlls').mkdirs()
|
||||
project.file('publish/publishRoot/bin/linux32/valve/dlls').mkdirs()
|
||||
|
||||
// bugfixed binaries
|
||||
_copyFileToDir('publish/releaseRehldsFixes/swds.dll', 'publish/publishRoot/bin/bugfixed/')
|
||||
_copyFileToDir('publish/releaseRehldsFixes/swds.pdb', 'publish/publishRoot/bin/bugfixed/')
|
||||
_copyFile('publish/releaseRehldsFixes/libengine_i486.so', 'publish/publishRoot/bin/bugfixed/engine_i486.so')
|
||||
|
||||
// pure binaries
|
||||
_copyFileToDir('publish/releaseRehldsNofixes/swds.dll', 'publish/publishRoot/bin/pure/')
|
||||
_copyFileToDir('publish/releaseRehldsNofixes/swds.pdb', 'publish/publishRoot/bin/pure/')
|
||||
_copyFile('publish/releaseRehldsNofixes/libengine_i486.so', 'publish/publishRoot/bin/pure/engine_i486.so')
|
||||
_copyFile('publish/releaseRehldsFixes/swds.dll', 'publish/publishRoot/bin/win32/swds.dll')
|
||||
_copyFile('publish/releaseRehldsFixes/libengine_i486.so', 'publish/publishRoot/bin/linux32/engine_i486.so')
|
||||
|
||||
// dedicated binaries
|
||||
_copyFile('publish/hlds.exe', 'publish/publishRoot/bin/hlds.exe')
|
||||
_copyFile('publish/hlds_linux', 'publish/publishRoot/bin/hlds_linux')
|
||||
_copyFile('publish/hlds.exe', 'publish/publishRoot/bin/win32/hlds.exe')
|
||||
_copyFile('publish/hlds_linux', 'publish/publishRoot/bin/linux32/hlds_linux')
|
||||
|
||||
// HLTV binaries
|
||||
_copyFile('publish/hltv.exe', 'publish/publishRoot/bin/win32/hltv.exe')
|
||||
_copyFile('publish/hltv', 'publish/publishRoot/bin/linux32/hltv')
|
||||
|
||||
_copyFile('publish/core.dll', 'publish/publishRoot/bin/win32/core.dll')
|
||||
_copyFile('publish/libcore.so', 'publish/publishRoot/bin/linux32/core.so')
|
||||
|
||||
_copyFile('publish/proxy.dll', 'publish/publishRoot/bin/win32/proxy.dll')
|
||||
_copyFile('publish/libproxy.so', 'publish/publishRoot/bin/linux32/proxy.so')
|
||||
|
||||
_copyFile('publish/demoplayer.dll', 'publish/publishRoot/bin/win32/demoplayer.dll')
|
||||
_copyFile('publish/libdemoplayer.so', 'publish/publishRoot/bin/linux32/demoplayer.so')
|
||||
|
||||
_copyFile('publish/director.dll', 'publish/publishRoot/bin/win32/valve/dlls/director.dll')
|
||||
_copyFile('publish/libdirector.so', 'publish/publishRoot/bin/linux32/valve/dlls/director.so')
|
||||
|
||||
// hlsdk
|
||||
project.file('publish/publishRoot/hlsdk').mkdirs()
|
||||
|
153
rehlds/HLTV/Console/build.gradle
Normal file
153
rehlds/HLTV/Console/build.gradle
Normal file
@ -0,0 +1,153 @@
|
||||
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
|
||||
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
|
||||
import org.doomedsociety.gradlecpp.GradleCppUtils
|
||||
import org.gradle.nativeplatform.NativeExecutableSpec
|
||||
import org.gradle.nativeplatform.NativeExecutableBinarySpec
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: 'windows-resources'
|
||||
apply plugin: IccCompilerPlugin
|
||||
apply plugin: GccCompilerPlugin
|
||||
|
||||
List<Task> getRcCompileTasks(NativeBinarySpec binary)
|
||||
{
|
||||
def linkTask = GradleCppUtils.getLinkTask(binary)
|
||||
def res = linkTask.taskDependencies.getDependencies(linkTask).findAll { Task t -> t instanceof WindowsResourceCompile }
|
||||
return res as List
|
||||
}
|
||||
|
||||
void setupToolchain(NativeBinarySpec b) {
|
||||
def cfg = rootProject.createToolchainConfig(b);
|
||||
cfg.projectInclude(project, '/..', '/../..', '/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds');
|
||||
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', '_CONSOLE'
|
||||
|
||||
if (cfg instanceof MsvcToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
|
||||
enabled: true,
|
||||
pchHeader: 'precompiled.h',
|
||||
pchSourceSet: 'hltv_pch'
|
||||
);
|
||||
|
||||
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
||||
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF', '/GR-'
|
||||
cfg.extraLibs "user32.lib"
|
||||
}
|
||||
else if (cfg instanceof GccToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'hltv_pch'
|
||||
);
|
||||
|
||||
cfg.compilerOptions.languageStandard = 'c++0x'
|
||||
cfg.defines([
|
||||
'_strdup': 'strdup',
|
||||
'_stricmp': 'strcasecmp',
|
||||
'_strnicmp': 'strncasecmp',
|
||||
'_vsnprintf': 'vsnprintf',
|
||||
'_snprintf': 'snprintf',
|
||||
]);
|
||||
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-fno-rtti', '-fno-exceptions'
|
||||
cfg.extraLibs 'dl'
|
||||
}
|
||||
|
||||
ToolchainConfigUtils.apply(project, cfg, b);
|
||||
}
|
||||
|
||||
model {
|
||||
buildTypes {
|
||||
release
|
||||
}
|
||||
|
||||
platforms {
|
||||
x86 {
|
||||
architecture "x86"
|
||||
}
|
||||
}
|
||||
|
||||
toolChains {
|
||||
visualCpp(VisualCpp) {
|
||||
}
|
||||
icc(Icc) {
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
hltv(NativeExecutableSpec) {
|
||||
targetPlatform 'x86'
|
||||
baseName 'hltv'
|
||||
|
||||
sources {
|
||||
hltv_main(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "**/*.cpp"
|
||||
exclude "precompiled.cpp"
|
||||
}
|
||||
}
|
||||
hltv_common(CppSourceSet) {
|
||||
source {
|
||||
srcDirs "../../common", "../common"
|
||||
|
||||
// common
|
||||
include "BaseSystemModule.cpp"
|
||||
include "ObjectList.cpp"
|
||||
include "TokenLine.cpp"
|
||||
include "textconsole.cpp"
|
||||
if (GradleCppUtils.windows) {
|
||||
include "TextConsoleWin32.cpp"
|
||||
}
|
||||
else {
|
||||
include "TextConsoleUnix.cpp"
|
||||
}
|
||||
|
||||
// HLTV common
|
||||
include "random.cpp"
|
||||
include "common.cpp"
|
||||
}
|
||||
}
|
||||
hltv_engine(CppSourceSet) {
|
||||
source {
|
||||
srcDir "../../engine"
|
||||
include "mem.cpp"
|
||||
}
|
||||
}
|
||||
hltv_pch(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "precompiled.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
rc {
|
||||
source {
|
||||
srcDir "msvc"
|
||||
include "hltv.rc"
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs "msvc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binaries.all {
|
||||
NativeExecutableBinarySpec b -> project.setupToolchain(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task buildFixes {
|
||||
dependsOn binaries.withType(NativeExecutableBinarySpec).matching { NativeExecutableBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
task buildRelease {
|
||||
dependsOn binaries.withType(NativeExecutableBinarySpec).matching { NativeExecutableBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
22
rehlds/HLTV/Console/msvc/Console.sln
Normal file
22
rehlds/HLTV/Console/msvc/Console.sln
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Console", "Console.vcxproj", "{D5CAB879-D54F-456F-8592-31D549CFD1D8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D5CAB879-D54F-456F-8592-31D549CFD1D8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D5CAB879-D54F-456F-8592-31D549CFD1D8}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D5CAB879-D54F-456F-8592-31D549CFD1D8}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D5CAB879-D54F-456F-8592-31D549CFD1D8}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
186
rehlds/HLTV/Console/msvc/Console.vcxproj
Normal file
186
rehlds/HLTV/Console/msvc/Console.vcxproj
Normal file
@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" 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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
||||
<ClInclude Include="..\..\..\common\textconsole.h" />
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
||||
<ClInclude Include="..\..\..\engine\mem.h" />
|
||||
<ClInclude Include="..\..\..\game_shared\bitvec.h" />
|
||||
<ClInclude Include="..\..\..\game_shared\perf_counter.h" />
|
||||
<ClInclude Include="..\..\..\game_shared\voice_common.h" />
|
||||
<ClInclude Include="..\..\common\common_hltv.h" />
|
||||
<ClInclude Include="..\..\common\random.h" />
|
||||
<ClInclude Include="..\src\precompiled.h" />
|
||||
<ClInclude Include="..\src\System.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\textconsole.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TextConsoleUnix.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TextConsoleWin32.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\random.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\System.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="hltv.rc" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D5CAB879-D54F-456F-8592-31D549CFD1D8}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Console</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Console</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>hltv</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hltv</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<FullProgramDatabaseFile>false</FullProgramDatabaseFile>
|
||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
106
rehlds/HLTV/Console/msvc/Console.vcxproj.filters
Normal file
106
rehlds/HLTV/Console/msvc/Console.vcxproj.filters
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{9111aa50-a4d2-45d9-8e74-ae8045065799}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="game_shared">
|
||||
<UniqueIdentifier>{753dfdd8-0143-4b2f-8da1-0d60981a1388}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV">
|
||||
<UniqueIdentifier>{2fbfe7d4-1a55-4e00-a1d0-7a0fea11bdc1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV\common">
|
||||
<UniqueIdentifier>{36d6fd93-a7f4-4f53-9a15-9983679abe00}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{26672827-46c9-4080-babb-f002c2e71cf8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="engine">
|
||||
<UniqueIdentifier>{6b303ee4-f4a5-4e82-8a4d-a374240de8d0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\precompiled.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\System.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game_shared\bitvec.h">
|
||||
<Filter>game_shared</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game_shared\perf_counter.h">
|
||||
<Filter>game_shared</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game_shared\voice_common.h">
|
||||
<Filter>game_shared</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\common_hltv.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="..\..\common\random.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\textconsole.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\engine\mem.h">
|
||||
<Filter>engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\System.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\random.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\textconsole.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TextConsoleUnix.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TextConsoleWin32.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp">
|
||||
<Filter>engine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="hltv.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
39
rehlds/HLTV/Console/msvc/PostBuild.bat
Normal file
39
rehlds/HLTV/Console/msvc/PostBuild.bat
Normal file
@ -0,0 +1,39 @@
|
||||
@echo OFF
|
||||
::
|
||||
:: Post-build auto-deploy script
|
||||
:: Create and fill PublishPath.txt file with path to deployment folder
|
||||
:: I.e. PublishPath.txt should contain one line with a folder path
|
||||
:: Call it so:
|
||||
:: IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")
|
||||
::
|
||||
|
||||
SET targetDir=%~1
|
||||
SET targetName=%~2
|
||||
SET targetExt=%~3
|
||||
SET projectDir=%~4
|
||||
SET destination=
|
||||
|
||||
IF NOT EXIST "%projectDir%\PublishPath.txt" (
|
||||
ECHO No deployment path specified. Create PublishPath.txt near PostBuild.bat with paths on separate lines for auto deployment.
|
||||
exit /B 0
|
||||
)
|
||||
|
||||
FOR /f "tokens=* delims= usebackq" %%a IN ("%projectDir%\PublishPath.txt") DO (
|
||||
ECHO Deploying to: %%a
|
||||
IF NOT "%%a" == "" (
|
||||
copy /Y "%targetDir%%targetName%%targetExt%" "%%a"
|
||||
IF NOT ERRORLEVEL 1 (
|
||||
IF EXIST "%targetDir%%targetName%.pdb" (
|
||||
copy /Y "%targetDir%%targetName%.pdb" "%%a"
|
||||
)
|
||||
) ELSE (
|
||||
ECHO PostBuild.bat ^(27^) : warning : Can't copy '%targetName%%targetExt%' to deploy path '%%a'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
IF "%%a" == "" (
|
||||
ECHO No deployment path specified.
|
||||
)
|
||||
|
||||
exit /B 0
|
BIN
rehlds/HLTV/Console/msvc/hltv.rc
Normal file
BIN
rehlds/HLTV/Console/msvc/hltv.rc
Normal file
Binary file not shown.
BIN
rehlds/HLTV/Console/msvc/icon.ico
Normal file
BIN
rehlds/HLTV/Console/msvc/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 118 KiB |
16
rehlds/HLTV/Console/msvc/resource.h
Normal file
16
rehlds/HLTV/Console/msvc/resource.h
Normal file
@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_ICON1 107
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 108
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
1147
rehlds/HLTV/Console/src/System.cpp
Normal file
1147
rehlds/HLTV/Console/src/System.cpp
Normal file
File diff suppressed because it is too large
Load Diff
188
rehlds/HLTV/Console/src/System.h
Normal file
188
rehlds/HLTV/Console/src/System.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "TokenLine.h"
|
||||
#include "interface.h"
|
||||
#include "textconsole.h"
|
||||
#include "BaseSystemModule.h"
|
||||
#include "ObjectList.h"
|
||||
|
||||
class Panel;
|
||||
class System: public IBaseSystem, public BaseSystemModule {
|
||||
public:
|
||||
System() {}
|
||||
~System() {}
|
||||
|
||||
double GetTime();
|
||||
unsigned int GetTick();
|
||||
void SetFPS(float fps);
|
||||
void Printf(char *fmt, ...);
|
||||
void DPrintf(char *fmt, ...);
|
||||
void RedirectOutput(char *buffer, int maxSize);
|
||||
IFileSystem *GetFileSystem();
|
||||
unsigned char *LoadFile(const char *name, int *length);
|
||||
void FreeFile(unsigned char *fileHandle);
|
||||
void SetTitle(char *pszTitle);
|
||||
void SetStatusLine(char *pszStatus);
|
||||
void ShowConsole(bool visible);
|
||||
void LogConsole(char *filename);
|
||||
bool InitVGUI(IVGuiModule *module);
|
||||
Panel *GetPanel();
|
||||
bool RegisterCommand(char *name, ISystemModule *module, int commandID);
|
||||
void GetCommandMatches(char *string, ObjectList *pMatchList);
|
||||
void ExecuteString(char *commands);
|
||||
void ExecuteFile(char *filename);
|
||||
void Errorf(char *fmt, ...);
|
||||
char *CheckParam(char *param);
|
||||
bool AddModule(ISystemModule *module, char *name);
|
||||
ISystemModule *GetModule(char *interfacename, char *library, char *instancename = nullptr);
|
||||
bool RemoveModule(ISystemModule *module);
|
||||
void Stop();
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
char *GetType();
|
||||
char *GetStatusLine();
|
||||
void ShutDown();
|
||||
char *GetBaseDir();
|
||||
|
||||
#ifdef _WIN32
|
||||
void BuildCommandLine(char *argv);
|
||||
#else
|
||||
void BuildCommandLine(int argc, char **argv);
|
||||
#endif // _WIN32
|
||||
void Sleep(int msec);
|
||||
|
||||
protected:
|
||||
struct command_t {
|
||||
char name[32];
|
||||
int commandID;
|
||||
ISystemModule *module;
|
||||
};
|
||||
|
||||
struct library_t {
|
||||
char name[MAX_PATH];
|
||||
CSysModule *handle;
|
||||
CreateInterfaceFn createInterfaceFn;
|
||||
};
|
||||
|
||||
library_t *GetLibrary(char *name);
|
||||
ISystemModule *FindModule(char *type, char *name = nullptr);
|
||||
bool InitTimer();
|
||||
bool InitFileSystem();
|
||||
void Error();
|
||||
void OpenLogFile(char *filename);
|
||||
void CloseLogFile();
|
||||
void Log(char *string);
|
||||
bool DispatchCommand(char *command);
|
||||
void ExecuteCommandLine();
|
||||
void UpdateTime();
|
||||
char *GetInput();
|
||||
bool StartVGUI();
|
||||
void StopVGUI();
|
||||
void SetName(char *newName);
|
||||
|
||||
protected:
|
||||
enum LocalCommandIDs {
|
||||
CMD_ID_DEVELOPER = 1,
|
||||
CMD_ID_EXEC,
|
||||
CMD_ID_MODULES,
|
||||
CMD_ID_CMDLIST,
|
||||
CMD_ID_LOGFILE,
|
||||
CMD_ID_QUIT,
|
||||
CMD_ID_LOADMODULE,
|
||||
CMD_ID_UNLOADMODULE,
|
||||
CMD_ID_TITLE,
|
||||
CMD_ID_SHOWCON,
|
||||
CMD_ID_ECHO
|
||||
};
|
||||
|
||||
void CMD_Developer(char *cmdLine);
|
||||
void CMD_Exec(char *cmdLine);
|
||||
void CMD_Title(char *cmdLine);
|
||||
void CMD_Modules(char *cmdLine);
|
||||
void CMD_CmdList(char *cmdLine);
|
||||
void CMD_ShowCon(char *cmdLine);
|
||||
void CMD_Logfile(char *cmdLine);
|
||||
void CMD_Quit(char *cmdLine);
|
||||
void CMD_UnloadModule(char *cmdLine);
|
||||
void CMD_LoadModule(char *cmdLine);
|
||||
void CMD_Echo(char *cmdLine);
|
||||
|
||||
struct LocalCommandID_s {
|
||||
char *name;
|
||||
LocalCommandIDs id;
|
||||
void (System::*pfnCmd)(char *cmdLine);
|
||||
};
|
||||
static LocalCommandID_s m_LocalCmdReg[];
|
||||
|
||||
private:
|
||||
double m_LastTime;
|
||||
|
||||
#ifdef _WIN32
|
||||
CTextConsoleWin32 m_Console;
|
||||
#else
|
||||
CTextConsoleUnix m_Console;
|
||||
#endif // _WIN32
|
||||
|
||||
CCounter m_Counter;
|
||||
CSysModule *m_FileSystemModule;
|
||||
IFileSystem *m_FileSystem;
|
||||
CSysModule *m_VGUIModule;
|
||||
TokenLine m_Parameters;
|
||||
|
||||
char m_BaseDir[MAX_PATH];
|
||||
char m_StatusLine[80];
|
||||
|
||||
FileHandle_t m_LogFile;
|
||||
char m_LogFileName[MAX_PATH];
|
||||
|
||||
ObjectList m_Modules;
|
||||
ObjectList m_Libraries;
|
||||
ObjectList m_Commands;
|
||||
|
||||
float m_MaxFPS;
|
||||
char *m_RedirectBuffer;
|
||||
unsigned int m_RedirectSize;
|
||||
bool m_Developer;
|
||||
|
||||
unsigned int m_SerialCounter;
|
||||
unsigned int m_Tick;
|
||||
unsigned int m_SleepMSecs;
|
||||
|
||||
CreateInterfaceFn m_Factorylist[3];
|
||||
|
||||
bool m_VGUIStarted;
|
||||
Panel *m_MainPanel;
|
||||
};
|
||||
|
||||
extern System gSystem;
|
||||
|
||||
void Sys_Printf(char *fmt, ...);
|
1
rehlds/HLTV/Console/src/precompiled.cpp
Normal file
1
rehlds/HLTV/Console/src/precompiled.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "precompiled.h"
|
19
rehlds/HLTV/Console/src/precompiled.h
Normal file
19
rehlds/HLTV/Console/src/precompiled.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "osconfig.h"
|
||||
#include "archtypes.h"
|
||||
#include "mathlib.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include <HLTV/IProxy.h>
|
||||
#include <game_shared/counter.h>
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
#include "mem.h"
|
||||
#include "common.h"
|
||||
#include "common/common_hltv.h"
|
||||
|
||||
// Console stuff
|
||||
#include "System.h"
|
||||
#include "common/random.h"
|
3
rehlds/HLTV/Console/src/public_amalgamation.cpp
Normal file
3
rehlds/HLTV/Console/src/public_amalgamation.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "interface.cpp"
|
154
rehlds/HLTV/Core/build.gradle
Normal file
154
rehlds/HLTV/Core/build.gradle
Normal file
@ -0,0 +1,154 @@
|
||||
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
|
||||
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
|
||||
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
|
||||
import org.gradle.nativeplatform.NativeBinarySpec
|
||||
import org.gradle.nativeplatform.NativeLibrarySpec
|
||||
import org.gradle.nativeplatform.toolchain.VisualCpp
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: IccCompilerPlugin
|
||||
apply plugin: GccCompilerPlugin
|
||||
|
||||
project.ext.dep_bzip2 = project(':dep/bzip2')
|
||||
|
||||
void setupToolchain(NativeBinarySpec b) {
|
||||
def cfg = rootProject.createToolchainConfig(b);
|
||||
cfg.projectInclude(project, '/..', '/../..', '/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared');
|
||||
cfg.projectInclude(dep_bzip2, '/include')
|
||||
|
||||
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'CORE_MODULE'
|
||||
|
||||
if (cfg instanceof MsvcToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
|
||||
enabled: true,
|
||||
pchHeader: 'precompiled.h',
|
||||
pchSourceSet: 'core_pch'
|
||||
);
|
||||
|
||||
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
||||
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF'
|
||||
cfg.extraLibs "ws2_32.lib", "psapi.lib"
|
||||
}
|
||||
else if (cfg instanceof GccToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'core_pch'
|
||||
);
|
||||
|
||||
cfg.compilerOptions.languageStandard = 'c++0x'
|
||||
cfg.defines([
|
||||
'_strdup': 'strdup',
|
||||
'_stricmp': 'strcasecmp',
|
||||
'_strnicmp': 'strncasecmp',
|
||||
'_vsnprintf': 'vsnprintf',
|
||||
'_snprintf': 'snprintf',
|
||||
]);
|
||||
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-fno-exceptions'
|
||||
}
|
||||
|
||||
ToolchainConfigUtils.apply(project, cfg, b);
|
||||
}
|
||||
|
||||
model {
|
||||
buildTypes {
|
||||
release
|
||||
}
|
||||
|
||||
platforms {
|
||||
x86 {
|
||||
architecture "x86"
|
||||
}
|
||||
}
|
||||
|
||||
toolChains {
|
||||
visualCpp(VisualCpp) {
|
||||
}
|
||||
icc(Icc) {
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
core(NativeLibrarySpec) {
|
||||
targetPlatform 'x86'
|
||||
baseName 'core'
|
||||
|
||||
sources {
|
||||
core_main(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "**/*.cpp"
|
||||
exclude "precompiled.cpp"
|
||||
}
|
||||
|
||||
lib project: ':dep/bzip2', library: 'bzip2', linkage: 'static'
|
||||
}
|
||||
|
||||
core_common(CppSourceSet) {
|
||||
source {
|
||||
srcDirs "../../common", "../common"
|
||||
|
||||
// common
|
||||
include "BaseSystemModule.cpp"
|
||||
include "ObjectDictionary.cpp"
|
||||
include "ObjectList.cpp"
|
||||
include "TokenLine.cpp"
|
||||
|
||||
// HLTV common
|
||||
include "BitBuffer.cpp"
|
||||
include "byteorder.cpp"
|
||||
include "common.cpp"
|
||||
include "DemoFile.cpp"
|
||||
include "DirectorCmd.cpp"
|
||||
include "InfoString.cpp"
|
||||
include "mathlib.cpp"
|
||||
include "md5.cpp"
|
||||
include "munge.cpp"
|
||||
include "NetAddress.cpp"
|
||||
include "NetChannel.cpp"
|
||||
include "random.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
core_engine(CppSourceSet) {
|
||||
source {
|
||||
srcDir "../../engine"
|
||||
include "mem.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
core_pch(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "precompiled.cpp"
|
||||
|
||||
lib project: ':dep/bzip2', library: 'bzip2', linkage: 'static'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binaries.all {
|
||||
NativeBinarySpec b -> project.setupToolchain(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task buildFixes {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
task buildRelease {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
// prevent static lib building
|
||||
binaries.withType(StaticLibraryBinarySpec) { binary ->
|
||||
buildable = false
|
||||
}
|
28
rehlds/HLTV/Core/msvc/Core.sln
Normal file
28
rehlds/HLTV/Core/msvc/Core.sln
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core.vcxproj", "{52F752EA-73D1-422D-B805-17EF1FB20E09}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "..\..\..\..\dep\bzip2\msvc\bzip2.vcxproj", "{792DF067-9904-4579-99B9-46C17277ADE3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{52F752EA-73D1-422D-B805-17EF1FB20E09}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{52F752EA-73D1-422D-B805-17EF1FB20E09}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{52F752EA-73D1-422D-B805-17EF1FB20E09}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{52F752EA-73D1-422D-B805-17EF1FB20E09}.Release|Win32.Build.0 = Release|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
251
rehlds/HLTV/Core/msvc/Core.vcxproj
Normal file
251
rehlds/HLTV/Core/msvc/Core.vcxproj
Normal file
@ -0,0 +1,251 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" 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>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{52F752EA-73D1-422D-B805-17EF1FB20E09}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Core</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>core</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;CORE_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>
|
||||
</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>psapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;CORE_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>
|
||||
</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>psapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp" />
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp" />
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp" />
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp" />
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Core\DeltaEx.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Core\hooklist.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Core\main.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp" />
|
||||
<ClCompile Include="..\..\common\byteorder.cpp" />
|
||||
<ClCompile Include="..\..\common\common.cpp" />
|
||||
<ClCompile Include="..\..\common\DemoFile.cpp" />
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp" />
|
||||
<ClCompile Include="..\..\common\InfoString.cpp" />
|
||||
<ClCompile Include="..\..\common\mathlib.cpp" />
|
||||
<ClCompile Include="..\..\common\md5.cpp" />
|
||||
<ClCompile Include="..\..\common\munge.cpp" />
|
||||
<ClCompile Include="..\..\common\NetAddress.cpp" />
|
||||
<ClCompile Include="..\..\common\NetChannel.cpp" />
|
||||
<ClCompile Include="..\..\common\random.cpp" />
|
||||
<ClCompile Include="..\src\BSPModel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Delta.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\NetSocket.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Network.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp" />
|
||||
<ClCompile Include="..\src\Server.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\World.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
||||
<ClInclude Include="..\..\..\engine\mem.h" />
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\Core\DeltaEx.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\Core\hooklist.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BitBuffer.h" />
|
||||
<ClInclude Include="..\..\common\byteorder.h" />
|
||||
<ClInclude Include="..\..\common\common_hltv.h" />
|
||||
<ClInclude Include="..\..\common\DemoFile.h" />
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h" />
|
||||
<ClInclude Include="..\..\common\InfoString.h" />
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h" />
|
||||
<ClInclude Include="..\..\common\md5.h" />
|
||||
<ClInclude Include="..\..\common\munge.h" />
|
||||
<ClInclude Include="..\..\common\NetAddress.h" />
|
||||
<ClInclude Include="..\..\common\NetChannel.h" />
|
||||
<ClInclude Include="..\..\common\net_internal.h" />
|
||||
<ClInclude Include="..\..\common\random.h" />
|
||||
<ClInclude Include="..\src\BSPModel.h" />
|
||||
<ClInclude Include="..\src\Delta.h" />
|
||||
<ClInclude Include="..\src\NetSocket.h" />
|
||||
<ClInclude Include="..\src\Network.h" />
|
||||
<ClInclude Include="..\src\precompiled.h" />
|
||||
<ClInclude Include="..\src\Server.h" />
|
||||
<ClInclude Include="..\src\World.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\dep\bzip2\msvc\bzip2.vcxproj">
|
||||
<Project>{792df067-9904-4579-99b9-46c17277ade3}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
192
rehlds/HLTV/Core/msvc/Core.vcxproj.filters
Normal file
192
rehlds/HLTV/Core/msvc/Core.vcxproj.filters
Normal file
@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{a2b59fb8-08c7-4528-89af-ade37c2610c8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV">
|
||||
<UniqueIdentifier>{2c80c58c-56fb-4bd9-b106-8ed08029173e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV\common">
|
||||
<UniqueIdentifier>{664fe3c6-46ae-4fa5-bf0c-f70873228f5e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\hookers">
|
||||
<UniqueIdentifier>{fb482bcd-a131-4e66-be87-c7b0ffe6a4cf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="engine">
|
||||
<UniqueIdentifier>{0997bc0d-a67f-47eb-abc1-3c7ebb128beb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{3a1d44ef-34e6-4921-a2b7-ff9808b3cfad}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\BSPModel.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Delta.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\NetSocket.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Network.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Server.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\World.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\byteorder.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DemoFile.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\InfoString.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\mathlib.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\munge.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\NetAddress.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\NetChannel.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\random.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Core\hooklist.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Core\main.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\md5.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Core\DeltaEx.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp">
|
||||
<Filter>engine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\Network.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Server.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\World.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\precompiled.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BitBuffer.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\byteorder.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\common_hltv.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DemoFile.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\InfoString.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\munge.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\NetAddress.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\NetChannel.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\random.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\net_internal.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\BSPModel.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\NetSocket.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Delta.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\Core\hooklist.h">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\md5.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\Core\DeltaEx.h">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\engine\mem.h">
|
||||
<Filter>engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
39
rehlds/HLTV/Core/msvc/PostBuild.bat
Normal file
39
rehlds/HLTV/Core/msvc/PostBuild.bat
Normal file
@ -0,0 +1,39 @@
|
||||
@echo OFF
|
||||
::
|
||||
:: Post-build auto-deploy script
|
||||
:: Create and fill PublishPath.txt file with path to deployment folder
|
||||
:: I.e. PublishPath.txt should contain one line with a folder path
|
||||
:: Call it so:
|
||||
:: IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")
|
||||
::
|
||||
|
||||
SET targetDir=%~1
|
||||
SET targetName=%~2
|
||||
SET targetExt=%~3
|
||||
SET projectDir=%~4
|
||||
SET destination=
|
||||
|
||||
IF NOT EXIST "%projectDir%\PublishPath.txt" (
|
||||
ECHO No deployment path specified. Create PublishPath.txt near PostBuild.bat with paths on separate lines for auto deployment.
|
||||
exit /B 0
|
||||
)
|
||||
|
||||
FOR /f "tokens=* delims= usebackq" %%a IN ("%projectDir%\PublishPath.txt") DO (
|
||||
ECHO Deploying to: %%a
|
||||
IF NOT "%%a" == "" (
|
||||
copy /Y "%targetDir%%targetName%%targetExt%" "%%a"
|
||||
IF NOT ERRORLEVEL 1 (
|
||||
IF EXIST "%targetDir%%targetName%.pdb" (
|
||||
copy /Y "%targetDir%%targetName%.pdb" "%%a"
|
||||
)
|
||||
) ELSE (
|
||||
ECHO PostBuild.bat ^(27^) : warning : Can't copy '%targetName%%targetExt%' to deploy path '%%a'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
IF "%%a" == "" (
|
||||
ECHO No deployment path specified.
|
||||
)
|
||||
|
||||
exit /B 0
|
1163
rehlds/HLTV/Core/src/BSPModel.cpp
Normal file
1163
rehlds/HLTV/Core/src/BSPModel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
99
rehlds/HLTV/Core/src/BSPModel.h
Normal file
99
rehlds/HLTV/Core/src/BSPModel.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IBSPModel.h>
|
||||
|
||||
#include "l_studio.h"
|
||||
#include "edict.h"
|
||||
|
||||
// values for model_t's needload
|
||||
#define NL_PRESENT 0
|
||||
#define NL_NEEDS_LOADED 1
|
||||
#define NL_UNREFERENCED 2
|
||||
|
||||
const int MAX_WORLD_SIZE = 32000;
|
||||
|
||||
class IBaseSystem;
|
||||
class BSPModel: public IBSPModel {
|
||||
public:
|
||||
BSPModel() {}
|
||||
virtual ~BSPModel() {}
|
||||
|
||||
void Init(IBaseSystem *system);
|
||||
void Clear();
|
||||
bool Load(const char *name, bool minimal);
|
||||
bool IsValid();
|
||||
bool IsMinimal();
|
||||
void SetPVS(vec_t *point);
|
||||
bool InPVS(vec_t *point);
|
||||
bool TraceLine(vec_t *start, vec_t *end, vec_t *impact);
|
||||
int TruePointContents(vec_t *point);
|
||||
|
||||
private:
|
||||
void LoadTextures(lump_t *l);
|
||||
void LoadEdges(lump_t *l);
|
||||
bool LoadFromBuffer(unsigned int *buffer, int length, const char *name);
|
||||
void LoadLeafs(lump_t *l);
|
||||
void LoadNodes(lump_t *l);
|
||||
void LoadVisibility(lump_t *l);
|
||||
void LoadPlanes(lump_t *l);
|
||||
void LoadVertexes(lump_t *l);
|
||||
void LoadTexinfo(lump_t *l);
|
||||
void LoadClipnodes(lump_t *l);
|
||||
void LoadMarksurfaces(lump_t *l);
|
||||
void LoadFaces(lump_t *l);
|
||||
void LoadLighting(lump_t *l);
|
||||
void LoadEntities(lump_t *l);
|
||||
void LoadSurfedges(lump_t *l);
|
||||
int HullPointContents(hull_t *hull, int num, const vec_t *point);
|
||||
bool RecursiveHullCheck(hull_t *hull, int num, float p1f, float p2f, vec_t *p1, vec_t *p2, trace_t *trace);
|
||||
void MakeHull0();
|
||||
mleaf_t *PointInLeaf(vec_t *point);
|
||||
void GetDimension(vec_t *min, vec_t *max);
|
||||
mnode_t *PVSNode(mnode_t *node, vec_t *emins, vec_t *emaxs);
|
||||
void PVSMark(unsigned char *ppvs);
|
||||
unsigned char *LeafPVS(mleaf_t *leaf);
|
||||
void DecompressPVS(unsigned char *in, unsigned char *decompressed, int byteCount);
|
||||
unsigned char *DecompressVis(unsigned char *in);
|
||||
void SetParent(mnode_t *node, mnode_t *parent);
|
||||
|
||||
protected:
|
||||
model_t m_model;
|
||||
|
||||
enum { MODEL_MAX_PVS = 1024 };
|
||||
byte m_novis[MODEL_MAX_PVS];
|
||||
byte *m_base;
|
||||
|
||||
int m_visframecount;
|
||||
mleaf_t *m_currentLeaf;
|
||||
bool m_IsMinimal;
|
||||
char *m_wadpath;
|
||||
IBaseSystem *m_System;
|
||||
};
|
1514
rehlds/HLTV/Core/src/Delta.cpp
Normal file
1514
rehlds/HLTV/Core/src/Delta.cpp
Normal file
File diff suppressed because it is too large
Load Diff
208
rehlds/HLTV/Core/src/Delta.h
Normal file
208
rehlds/HLTV/Core/src/Delta.h
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "event_args.h"
|
||||
#include "BaseSystemModule.h"
|
||||
|
||||
#define DELTA_MAX_FIELDS 56 // 7*8
|
||||
|
||||
#define DT_BYTE BIT(0) // A byte
|
||||
#define DT_SHORT BIT(1) // 2 byte field
|
||||
#define DT_FLOAT BIT(2) // A floating point field
|
||||
#define DT_INTEGER BIT(3) // 4 byte integer
|
||||
#define DT_ANGLE BIT(4) // A floating point angle
|
||||
#define DT_TIMEWINDOW_8 BIT(5) // A floating point timestamp relative to server time
|
||||
#define DT_TIMEWINDOW_BIG BIT(6) // A floating point timestamp relative to server time (with more precision and custom multiplier)
|
||||
#define DT_STRING BIT(7) // A null terminated string, sent as 8 byte chars
|
||||
#define DT_SIGNED BIT(31) // sign modificator
|
||||
|
||||
#define FDT_MARK BIT(0) // Delta mark for sending
|
||||
|
||||
typedef void (*encoder_t)(struct delta_s *, const unsigned char *, const unsigned char *);
|
||||
|
||||
typedef struct delta_encoder_s
|
||||
{
|
||||
struct delta_encoder_s *next;
|
||||
char *name;
|
||||
encoder_t conditionalencode;
|
||||
} delta_encoder_t;
|
||||
|
||||
typedef struct delta_stats_s
|
||||
{
|
||||
int sendcount;
|
||||
int receivedcount;
|
||||
} delta_stats_t;
|
||||
|
||||
typedef struct delta_description_s
|
||||
{
|
||||
int fieldType;
|
||||
char fieldName[32];
|
||||
int fieldOffset;
|
||||
short int fieldSize;
|
||||
int significant_bits;
|
||||
float premultiply;
|
||||
float postmultiply;
|
||||
short int flags;
|
||||
delta_stats_t stats;
|
||||
} delta_description_t;
|
||||
|
||||
typedef struct deltacallback_s
|
||||
{
|
||||
int numbase;
|
||||
int num;
|
||||
bool remove;
|
||||
bool custom;
|
||||
bool newbl;
|
||||
int newblindex;
|
||||
bool full;
|
||||
int offset;
|
||||
bool instanced_baseline;
|
||||
} deltacallback_t;
|
||||
|
||||
typedef struct delta_s
|
||||
{
|
||||
int dynamic;
|
||||
int fieldCount;
|
||||
char conditionalencodename[32];
|
||||
encoder_t conditionalencode;
|
||||
delta_description_t *pdd;
|
||||
} delta_t;
|
||||
|
||||
#include "hookers/HLTV/Core/DeltaEx.h"
|
||||
|
||||
#ifndef HOOK_HLTV
|
||||
|
||||
class Delta {
|
||||
public:
|
||||
void Init(IBaseSystem *system);
|
||||
void Shutdown();
|
||||
void UpdateDescriptions();
|
||||
void WriteHeader(BitBuffer *stream, deltacallback_t *header);
|
||||
bool WriteDelta(BitBuffer *stream, unsigned char *from, unsigned char *to, bool force, delta_t *pFields, deltacallback_t *header = nullptr);
|
||||
int ParseDelta(BitBuffer *stream, unsigned char *from, unsigned char *to, delta_t *pFields);
|
||||
void SetTime(double time);
|
||||
void SetLargeTimeBufferSize(bool bigBuffers);
|
||||
int TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields);
|
||||
delta_t **LookupRegistration(char *name);
|
||||
void FreeDescription(delta_t **ppdesc);
|
||||
|
||||
private:
|
||||
typedef struct delta_link_s
|
||||
{
|
||||
struct delta_link_s *next;
|
||||
delta_description_t *delta;
|
||||
} delta_link_t;
|
||||
|
||||
typedef struct delta_definition_s
|
||||
{
|
||||
char *fieldName;
|
||||
size_t fieldOffset;
|
||||
} delta_definition_t;
|
||||
|
||||
typedef struct delta_definition_list_s
|
||||
{
|
||||
struct delta_definition_list_s *next;
|
||||
char *ptypename;
|
||||
int numelements;
|
||||
delta_definition_t *pdefinition;
|
||||
} delta_definition_list_t;
|
||||
|
||||
typedef struct delta_registry_s
|
||||
{
|
||||
struct delta_registry_s *next;
|
||||
char *name;
|
||||
delta_t *pdesc;
|
||||
} delta_registry_t;
|
||||
|
||||
delta_registry_t *GetRegistry() const { return m_DeltaRegistry; }
|
||||
delta_description_t *FindField(delta_t *pFields, const char *pszField);
|
||||
int FindFieldIndex(delta_t *pFields, const char *fieldname);
|
||||
void SetField(delta_t *pFields, const char *fieldname);
|
||||
void UnsetField(delta_t *pFields, const char *fieldname);
|
||||
void SetFieldByIndex(delta_t *pFields, int fieldNumber);
|
||||
void UnsetFieldByIndex(delta_t *pFields, int fieldNumber);
|
||||
void ClearFlags(delta_t *pFields);
|
||||
int CountSendFields(delta_t *pFields);
|
||||
void MarkSendFields(unsigned char *from, unsigned char *to, delta_t *pFields);
|
||||
void SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount);
|
||||
void WriteMarkedFields(BitBuffer *stream, unsigned char *from, unsigned char *to, delta_t *pFields);
|
||||
bool CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFields);
|
||||
void AddEncoder(char *name, encoder_t conditionalencode);
|
||||
void ClearEncoders();
|
||||
encoder_t LookupEncoder(char *name);
|
||||
int CountLinks(delta_link_t *plinks);
|
||||
void ReverseLinks(delta_link_t **plinks);
|
||||
void ClearLinks(delta_link_t **plinks);
|
||||
delta_t *BuildFromLinks(delta_link_t **pplinks);
|
||||
int FindOffset(int count, delta_definition_t *pdef, char *fieldname);
|
||||
bool ParseType(delta_description_t *pdelta, char **pstream);
|
||||
bool ParseField(int count, delta_definition_t *pdefinition, delta_link_t *pField, char **pstream);
|
||||
void AddDefinition(char *name, delta_definition_t *pdef, int numelements);
|
||||
void ClearDefinitions();
|
||||
delta_definition_t *FindDefinition(char *name, int *count);
|
||||
void SkipDescription(char **pstream);
|
||||
bool ParseOneField(char **ppstream, delta_link_t **pplist, int count, delta_definition_t *pdefinition);
|
||||
bool ParseDescription(char *name, delta_t **ppdesc, char *pstream);
|
||||
bool Load(char *name, delta_t **ppdesc, char *pszFile);
|
||||
void RegisterDescription(char *name);
|
||||
void ClearRegistrations();
|
||||
void ClearStats(delta_t *p);
|
||||
|
||||
public:
|
||||
static delta_t m_MetaDelta[];
|
||||
static delta_description_t m_MetaDescription[];
|
||||
static delta_definition_t m_DeltaDataDefinition[];
|
||||
static delta_definition_t m_EventDataDefinition[];
|
||||
static delta_definition_t m_EntityDataDefinition[];
|
||||
static delta_definition_t m_UsercmdDataDefinition[];
|
||||
static delta_definition_t m_WeaponDataDefinition[];
|
||||
static delta_definition_t m_ClientDataDefinition[];
|
||||
|
||||
static delta_t *m_EntityDelta;
|
||||
static delta_t *m_PlayerDelta;
|
||||
static delta_t *m_CustomentityDelta;
|
||||
|
||||
static delta_t *m_ClientDelta;
|
||||
static delta_t *m_WeaponDelta;
|
||||
static delta_t *m_EventDelta;
|
||||
|
||||
private:
|
||||
friend class World;
|
||||
IBaseSystem *m_System;
|
||||
|
||||
delta_definition_list_t *m_Defs;
|
||||
delta_encoder_t *m_Encoders;
|
||||
delta_registry_t *m_DeltaRegistry;
|
||||
|
||||
double m_Time;
|
||||
bool m_LargeTime_Buffers;
|
||||
};
|
||||
|
||||
#endif // HOOK_HLTV
|
555
rehlds/HLTV/Core/src/NetSocket.cpp
Normal file
555
rehlds/HLTV/Core/src/NetSocket.cpp
Normal file
@ -0,0 +1,555 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
bool NetSocket::AddChannel(INetChannel *channel)
|
||||
{
|
||||
return m_Channels.AddTail(channel);
|
||||
}
|
||||
|
||||
bool NetSocket::RemoveChannel(INetChannel *channel)
|
||||
{
|
||||
return m_Channels.Remove(channel);
|
||||
}
|
||||
|
||||
int NetSocket::DispatchIncoming()
|
||||
{
|
||||
int length = 0;
|
||||
int count = 0;
|
||||
|
||||
NetAddress from;
|
||||
while ((length = ReceivePacketIntern(&from)))
|
||||
{
|
||||
if (length == -1)
|
||||
break;
|
||||
|
||||
INetChannel *channel = (INetChannel *)m_Channels.GetFirst();
|
||||
while (channel)
|
||||
{
|
||||
if (from.Equal(channel->GetTargetAddress())) {
|
||||
channel->ProcessIncoming(m_Buffer, length);
|
||||
break;
|
||||
}
|
||||
|
||||
channel = (INetChannel *)m_Channels.GetNext();
|
||||
}
|
||||
|
||||
// not found an existing channel for this address.
|
||||
// create a new channel
|
||||
if (!channel)
|
||||
{
|
||||
// do accept only connectionless (\xFF\xFF\xFF\xFF) incoming packet.
|
||||
if (*(int *)m_Buffer == CONNECTIONLESS_HEADER)
|
||||
{
|
||||
NetPacket *p = new NetPacket;
|
||||
p->time = m_System->GetTime();
|
||||
p->address.FromNetAddress(&from);
|
||||
p->connectionless = true;
|
||||
p->seqnr = -1;
|
||||
|
||||
// cut connectionless data
|
||||
p->data.Resize(length - 4);
|
||||
p->data.WriteBuf(&m_Buffer[4], length - 4);
|
||||
p->data.Reset();
|
||||
m_IncomingPackets.AddHead(p);
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool NetSocket::SendPacket(NetPacket *packet)
|
||||
{
|
||||
return SendPacket(&packet->address, packet->data.GetData(), packet->data.CurrentSize());
|
||||
}
|
||||
|
||||
bool NetSocket::SendPacket(NetAddress *to, const void *data, int length)
|
||||
{
|
||||
struct sockaddr addr;
|
||||
int ret;
|
||||
|
||||
if (m_Network->m_FakeLoss && RandomFloat(0, 1) < m_Network->m_FakeLoss) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (length <= 0 || !data || !to) {
|
||||
return true;
|
||||
}
|
||||
|
||||
to->ToSockadr(&addr);
|
||||
|
||||
if (length > MAX_ROUTEABLE_PACKET)
|
||||
{
|
||||
ret = SendLong((const char *)data, length, 0, &addr, sizeof(addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (length < sizeof(addr))
|
||||
ret = SendShort((const char *)data, length, 0, &addr, sizeof(addr));
|
||||
else
|
||||
ret = sendto(m_Socket, (const char *)data, length, 0, &addr, sizeof(addr));
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
int err = m_Network->GetLastErrorCode();
|
||||
|
||||
// wouldblock is silent
|
||||
if (err == WSAEWOULDBLOCK)
|
||||
return true;
|
||||
|
||||
if (err == WSAECONNREFUSED || err == WSAECONNRESET)
|
||||
return true;
|
||||
|
||||
// some PPP links dont allow broadcasts
|
||||
if (err == WSAEADDRNOTAVAIL)
|
||||
return true;
|
||||
|
||||
m_System->Printf("WARNING! NetSocket::SendPacket: %s\n", m_Network->GetErrorText(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_BytesOut += ret + UDP_HEADER_SIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
INetwork *NetSocket::GetNetwork()
|
||||
{
|
||||
return m_Network;
|
||||
}
|
||||
|
||||
int NetSocket::ReceivePacketIntern(NetAddress *fromHost)
|
||||
{
|
||||
sockaddr from;
|
||||
socklen_t fromlen = sizeof(from);
|
||||
int size = recvfrom(m_Socket, (char *)m_Buffer, sizeof(m_Buffer), 0, &from, &fromlen);
|
||||
if (size == -1)
|
||||
{
|
||||
int err = m_Network->GetLastErrorCode();
|
||||
if (err != WSAEWOULDBLOCK && err != WSAECONNRESET && err != WSAECONNREFUSED)
|
||||
{
|
||||
if (err == WSAEMSGSIZE)
|
||||
{
|
||||
m_System->DPrintf("WARNING! NetSocket::ReceivePacket: Ignoring oversized network message\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_System->DPrintf("WARNING! NetSocket::ReceivePacket: %s %d %i\n", m_Network->GetErrorText(err), err, errno);
|
||||
perror("err");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size == 0 || RandomFloat(0, 1) < m_Network->m_FakeLoss) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > 0 && size < 4) {
|
||||
m_System->DPrintf("WARNING! NetSocket::ReceivePacket: Ignoring undersized network message\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size >= MAX_UDP_PACKET) {
|
||||
m_System->DPrintf("WARNING! NetSocket::ReceivePacket: Oversize packet from %s\n", fromHost->ToString());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*(uint32 *)m_Buffer == NET_HEADER_FLAG_SPLITPACKET)
|
||||
{
|
||||
if (size < sizeof(SPLITPACKET))
|
||||
{
|
||||
m_System->Printf("Invalid split packet length %i\n", size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = GetLong(m_Buffer, size);
|
||||
}
|
||||
|
||||
fromHost->FromSockadr(&from);
|
||||
m_BytesIn += size + UDP_HEADER_SIZE;
|
||||
return size;
|
||||
}
|
||||
|
||||
void NetSocket::Close()
|
||||
{
|
||||
INetChannel *channel;
|
||||
while ((channel = (INetChannel *)m_Channels.RemoveHead())) {
|
||||
channel->Close();
|
||||
}
|
||||
|
||||
Flush();
|
||||
m_Network->RemoveSocket(this);
|
||||
|
||||
shutdown(m_Socket, 2);
|
||||
SOCKET_CLOSE(m_Socket);
|
||||
}
|
||||
|
||||
bool NetSocket::JoinGroup(NetAddress *group)
|
||||
{
|
||||
ip_mreq mreq;
|
||||
SIN_SET_ADDR(&mreq.imr_multiaddr, *(unsigned int *)&group->m_IP[0]);
|
||||
SIN_SET_ADDR(&mreq.imr_interface, 0);
|
||||
|
||||
if (setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) == SOCKET_ERROR)
|
||||
{
|
||||
int err = m_Network->GetLastErrorCode();
|
||||
if (err != WSAEAFNOSUPPORT) {
|
||||
m_System->DPrintf("WARNING! NetSocket::JoinGroup: IP_ADD_MEMBERSHIP: %s\n", m_Network->GetErrorText(err));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetSocket::LeaveGroup(NetAddress *group)
|
||||
{
|
||||
ip_mreq mreq;
|
||||
SIN_SET_ADDR(&mreq.imr_multiaddr, *(unsigned int *)&group->m_IP[0]);
|
||||
SIN_SET_ADDR(&mreq.imr_interface, 0);
|
||||
|
||||
if (setsockopt(m_Socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) == SOCKET_ERROR)
|
||||
{
|
||||
int err = m_Network->GetLastErrorCode();
|
||||
if (err != WSAEAFNOSUPPORT) {
|
||||
m_System->DPrintf("WARNING! NetSocket::LeaveGroup: IP_DROP_MEMBERSHIP: %s\n", m_Network->GetErrorText(err));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int NetSocket::DrainChannels()
|
||||
{
|
||||
int count = 0;
|
||||
INetChannel *channel = (INetChannel *)m_Channels.GetFirst();
|
||||
while (channel)
|
||||
{
|
||||
if (channel->IsReadyToSend()
|
||||
&& channel->KeepAlive()
|
||||
&& channel->IsConnected())
|
||||
{
|
||||
count++;
|
||||
channel->TransmitOutgoing();
|
||||
}
|
||||
|
||||
channel = (INetChannel *)m_Channels.GetNext();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int NetSocket::GetLong(unsigned char *pData, int size)
|
||||
{
|
||||
unsigned int packetNumber;
|
||||
unsigned int packetCount;
|
||||
int sequenceNumber;
|
||||
unsigned char packetID;
|
||||
static int netSplitFlags[MAX_SPLIT_FRAGMENTS] = { -1, -1, -1, -1, -1 };
|
||||
SPLITPACKET *pHeader = (SPLITPACKET *)pData;
|
||||
|
||||
sequenceNumber = pHeader->sequenceNumber;
|
||||
packetID = pHeader->packetID;
|
||||
packetCount = packetID & 0xF;
|
||||
packetNumber = (unsigned int)packetID >> 4;
|
||||
|
||||
if (packetNumber >= MAX_SPLIT_FRAGMENTS || packetCount > MAX_SPLIT_FRAGMENTS)
|
||||
{
|
||||
m_System->Printf("Malformed packet number (%i)\n", packetNumber);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_NetSplitPacket.currentSequence == -1 || sequenceNumber != m_NetSplitPacket.currentSequence)
|
||||
{
|
||||
m_NetSplitPacket.currentSequence = sequenceNumber;
|
||||
m_NetSplitPacket.splitCount = packetCount;
|
||||
}
|
||||
|
||||
unsigned int packetPayloadSize = size - sizeof(SPLITPACKET);
|
||||
if (netSplitFlags[packetNumber] == sequenceNumber)
|
||||
{
|
||||
m_System->DPrintf("NetSocket::GetLong: Ignoring duplicated split packet %i of %i ( %i bytes )\n", packetNumber + 1, packetCount, packetPayloadSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (packetNumber == packetCount - 1) {
|
||||
m_NetSplitPacket.totalSize = packetPayloadSize + SPLIT_SIZE * (packetCount - 1);
|
||||
}
|
||||
|
||||
--m_NetSplitPacket.splitCount;
|
||||
netSplitFlags[packetNumber] = sequenceNumber;
|
||||
}
|
||||
|
||||
memcpy(&m_NetSplitPacket.buffer[SPLIT_SIZE * packetNumber], pHeader + 1, packetPayloadSize);
|
||||
|
||||
if (m_NetSplitPacket.splitCount > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_NetSplitPacket.currentSequence = -1;
|
||||
if (m_NetSplitPacket.totalSize > MAX_UDP_PACKET)
|
||||
{
|
||||
m_System->DPrintf("WARNING! NetSocket::GetLong: Split packet too large! %d bytes\n", m_NetSplitPacket.totalSize);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
memcpy(pData, m_NetSplitPacket.buffer, m_NetSplitPacket.totalSize);
|
||||
return m_NetSplitPacket.totalSize;
|
||||
}
|
||||
|
||||
void NetSocket::OutOfBandPrintf(NetAddress *to, const char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[NET_MAX_MESSAGE];
|
||||
|
||||
*(int *)string = CONNECTIONLESS_HEADER;
|
||||
|
||||
va_start(argptr, format);
|
||||
_vsnprintf(&string[4], sizeof(string) - 4, format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SendPacket(to, string, strlen(string) + 1);
|
||||
}
|
||||
|
||||
void NetSocket::GetFlowStats(float *avgInKBSec, float *avgOutKBSec)
|
||||
{
|
||||
*avgInKBSec = m_AvgBytesIn / 1024;
|
||||
*avgOutKBSec = m_AvgBytesOut / 1024;
|
||||
}
|
||||
|
||||
NetPacket *NetSocket::ReceivePacket()
|
||||
{
|
||||
return (NetPacket *)m_IncomingPackets.RemoveTail();
|
||||
}
|
||||
|
||||
void NetSocket::FreePacket(NetPacket *packet)
|
||||
{
|
||||
if (packet) {
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
|
||||
void NetSocket::AddPacket(NetPacket *packet)
|
||||
{
|
||||
if (!packet->connectionless) {
|
||||
m_System->DPrintf("WARNING! NetSocket::AddPacket: only connectionless packets accepted.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
NetPacket *newpacket = new NetPacket;
|
||||
|
||||
newpacket->time = packet->time;
|
||||
newpacket->address.FromNetAddress(&packet->address);
|
||||
newpacket->connectionless = true;
|
||||
newpacket->seqnr = -1;
|
||||
|
||||
newpacket->data.Resize(packet->data.GetMaxSize());
|
||||
newpacket->data.WriteBuf(packet->data.GetData(), packet->data.GetMaxSize());
|
||||
newpacket->data.Reset();
|
||||
|
||||
m_IncomingPackets.AddHead(newpacket);
|
||||
}
|
||||
|
||||
void NetSocket::Flush()
|
||||
{
|
||||
NetPacket *in;
|
||||
while ((in = (NetPacket *)m_IncomingPackets.RemoveTail())) {
|
||||
FreePacket(in);
|
||||
}
|
||||
|
||||
if (m_Socket != INVALID_SOCKET)
|
||||
{
|
||||
sockaddr from;
|
||||
socklen_t fromlen = sizeof(from);
|
||||
while (recvfrom(m_Socket, (char *)m_Buffer, sizeof(m_Buffer), 0, &from, &fromlen) > 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetSocket::Create(Network *network, int port, bool reuse, bool loopback)
|
||||
{
|
||||
sockaddr_in address;
|
||||
char _true = 1;
|
||||
uint32 i = 1;
|
||||
|
||||
m_Network = network;
|
||||
m_System = network->GetSystem();
|
||||
|
||||
m_Channels.Init();
|
||||
|
||||
memset(m_Buffer, 0, sizeof(m_Buffer));
|
||||
memset(&m_NetSplitPacket, 0, sizeof(m_NetSplitPacket));
|
||||
|
||||
if ((m_Socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SOCKET_FIONBIO(m_Socket, i) == SOCKET_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setsockopt(m_Socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == SOCKET_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// resue
|
||||
if (reuse && setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &_true, sizeof(_true)) == SOCKET_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_Network->m_IsMultihomed)
|
||||
{
|
||||
m_Network->GetLocalAddress()->ToSockadr((sockaddr *)&address);
|
||||
}
|
||||
else
|
||||
{
|
||||
address.sin_addr.s_addr = 0;
|
||||
}
|
||||
|
||||
m_Port = port;
|
||||
address.sin_port = htons(port);
|
||||
address.sin_family = AF_INET;
|
||||
|
||||
if (bind(m_Socket, (struct sockaddr *)&address, sizeof(address)) == SOCKET_ERROR) {
|
||||
SOCKET_CLOSE(m_Socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Time-To-Live (TTL) for Multicast Packets
|
||||
// As the values of the TTL field increase, routers will expand the number of hops they will forward a multicast packet.
|
||||
// To provide meaningful scope control, multicast routers enforce the following
|
||||
// "thresholds" on forwarding based on the TTL field:
|
||||
//
|
||||
// 0: restricted to the same host
|
||||
// 1: restricted to the same subnet
|
||||
// 32: restricted to the same site
|
||||
// 64: restricted to the same region
|
||||
// 128: restricted to the same continent
|
||||
// 255: unrestricted
|
||||
|
||||
uint32 ttl = 32;
|
||||
char *ttlparam = m_System->CheckParam("-multicastttl");
|
||||
if (ttlparam) {
|
||||
ttl = atoi(ttlparam);
|
||||
}
|
||||
|
||||
if (setsockopt(m_Socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == SOCKET_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_BytesOut = 0;
|
||||
m_BytesIn = 0;
|
||||
m_LastUpdateTime = 0;
|
||||
|
||||
m_AvgBytesOut = 0;
|
||||
m_AvgBytesIn = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int NetSocket::GetPort()
|
||||
{
|
||||
return m_Port;
|
||||
}
|
||||
|
||||
void NetSocket::UpdateStats(double time)
|
||||
{
|
||||
float timeDiff = time - m_LastUpdateTime;
|
||||
if (timeDiff > 0)
|
||||
{
|
||||
m_AvgBytesIn = m_BytesIn / timeDiff * 0.3 + m_AvgBytesIn * 0.6;
|
||||
m_AvgBytesOut = m_BytesOut / timeDiff * 0.3 + m_AvgBytesOut * 0.6;
|
||||
|
||||
m_BytesIn = 0;
|
||||
m_BytesOut = 0;
|
||||
m_LastUpdateTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
int NetSocket::SendLong(const char *pData, int len, int flags, const sockaddr *to, int tolen)
|
||||
{
|
||||
char packet[MAX_ROUTEABLE_PACKET];
|
||||
int totalSent, ret, size, packetCount, packetNumber;
|
||||
SPLITPACKET *pPacket;
|
||||
|
||||
if (++m_netSplitSequenceNumber < 0) {
|
||||
m_netSplitSequenceNumber = 1;
|
||||
}
|
||||
|
||||
pPacket = (SPLITPACKET *)packet;
|
||||
pPacket->netID = -2;
|
||||
pPacket->sequenceNumber = m_netSplitSequenceNumber;
|
||||
packetNumber = 0;
|
||||
totalSent = 0;
|
||||
packetCount = (len + SPLIT_SIZE - 1) / SPLIT_SIZE;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
size = min(SPLIT_SIZE, (unsigned)len);
|
||||
pPacket->packetID = (packetNumber << 4) + packetCount;
|
||||
memcpy(packet + sizeof(SPLITPACKET), pData + (packetNumber * SPLIT_SIZE), size);
|
||||
|
||||
ret = sendto(m_Socket, packet, size + sizeof(SPLITPACKET), flags, to, tolen);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret >= size) {
|
||||
totalSent += size;
|
||||
}
|
||||
|
||||
len -= size;
|
||||
packetNumber++;
|
||||
}
|
||||
|
||||
return totalSent;
|
||||
}
|
||||
|
||||
int NetSocket::SendShort(const char *pData, int len, int flags, const sockaddr *to, int tolen)
|
||||
{
|
||||
if (len > MIN_ROUTEABLE_PACKET) {
|
||||
m_System->DPrintf("WARNING! NetSocket::SendShort: length > MIN_ROUTEABLE_PACKET.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char packet[MAX_ROUTEABLE_PACKET];
|
||||
memcpy(packet, pData, len);
|
||||
memset(&packet[len], 0, sizeof(packet) - len);
|
||||
|
||||
return sendto(m_Socket, packet, sizeof(packet), flags, to, tolen);
|
||||
}
|
108
rehlds/HLTV/Core/src/NetSocket.h
Normal file
108
rehlds/HLTV/Core/src/NetSocket.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/INetSocket.h>
|
||||
|
||||
class Network;
|
||||
class IBaseSytem;
|
||||
|
||||
class NetSocket: public INetSocket {
|
||||
public:
|
||||
NetSocket() : m_netSplitSequenceNumber(0) {}
|
||||
virtual ~NetSocket() {}
|
||||
|
||||
NetPacket *ReceivePacket();
|
||||
void FreePacket(NetPacket *packet);
|
||||
bool SendPacket(NetPacket *packet);
|
||||
bool SendPacket(NetAddress *packet, const void *data, int length);
|
||||
void AddPacket(NetPacket *packet);
|
||||
bool AddChannel(INetChannel *channel);
|
||||
bool RemoveChannel(INetChannel *channel);
|
||||
INetwork *GetNetwork();
|
||||
void OutOfBandPrintf(NetAddress *to, const char *format, ...);
|
||||
void Flush();
|
||||
void GetFlowStats(float *avgInKBSec, float *avgOutKBSec);
|
||||
bool LeaveGroup(NetAddress *group);
|
||||
bool JoinGroup(NetAddress *group);
|
||||
void Close();
|
||||
int GetPort();
|
||||
|
||||
bool Create(Network *network, int port, bool reuse, bool loopback);
|
||||
void UpdateStats(double time);
|
||||
int DrainChannels();
|
||||
int DispatchIncoming();
|
||||
|
||||
private:
|
||||
int ReceivePacketIntern(NetAddress *fromHost);
|
||||
int SendLong(const char *pData, int len, int flags, const sockaddr *to, int tolen);
|
||||
int SendShort(const char *pData, int len, int flags, const sockaddr *to, int tolen);
|
||||
int GetLong(unsigned char *pData, int size);
|
||||
|
||||
protected:
|
||||
int m_Port;
|
||||
unsigned char m_Buffer[MAX_UDP_PACKET];
|
||||
|
||||
ObjectList m_IncomingPackets;
|
||||
ObjectList m_Channels;
|
||||
SOCKET m_Socket;
|
||||
Network *m_Network;
|
||||
IBaseSystem *m_System;
|
||||
|
||||
enum { MAX_SPLIT_FRAGMENTS = 5 };
|
||||
// Use this to pick apart the network stream, must be packed
|
||||
#pragma pack(push, 1)
|
||||
typedef struct SPLITPACKET_t
|
||||
{
|
||||
int netID;
|
||||
int sequenceNumber;
|
||||
unsigned char packetID;
|
||||
} SPLITPACKET;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Split long packets. Anything over 1460 is failing on some routers.
|
||||
typedef struct LONGPACKET_t
|
||||
{
|
||||
int currentSequence;
|
||||
int splitCount;
|
||||
int totalSize;
|
||||
// TODO: It should be NET_MAX_MESSAGE, but value differs
|
||||
char buffer[MAX_UDP_PACKET]; // This has to be big enough to hold the largest message
|
||||
} LONGPACKET;
|
||||
|
||||
LONGPACKET m_NetSplitPacket;
|
||||
|
||||
int m_netSplitSequenceNumber;
|
||||
int m_netSplitFlags[MAX_SPLIT_FRAGMENTS];
|
||||
int m_BytesIn;
|
||||
int m_BytesOut;
|
||||
double m_LastUpdateTime;
|
||||
float m_AvgBytesIn;
|
||||
float m_AvgBytesOut;
|
||||
};
|
445
rehlds/HLTV/Core/src/Network.cpp
Normal file
445
rehlds/HLTV/Core/src/Network.cpp
Normal file
@ -0,0 +1,445 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
bool Network::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseSystemModule::Init(system, serial, name);
|
||||
|
||||
if (!name) {
|
||||
SetName(NETWORK_INTERFACE_VERSION);
|
||||
}
|
||||
|
||||
m_FakeLoss = 0;
|
||||
m_IsMultihomed = false;
|
||||
m_NoDNS = false;
|
||||
|
||||
m_Sockets.Init();
|
||||
m_System->RegisterCommand("fakeloss", this, CMD_ID_FAKELOSS);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Startup winock
|
||||
WORD version = MAKEWORD(2, 2); // for use Winsock 2.2, version should be 514
|
||||
WSADATA wsaData;
|
||||
int err = WSAStartup(version, &wsaData);
|
||||
if (err != NO_ERROR)
|
||||
{
|
||||
m_System->Printf("Network Error WSAStartup:%s\n", GetErrorText(GetLastErrorCode()));
|
||||
return false;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
if (m_System->CheckParam("-nodns")) {
|
||||
m_NoDNS = true;
|
||||
}
|
||||
|
||||
if (ResolveAddress(m_System->CheckParam("-ip"), &m_LocalAddress))
|
||||
{
|
||||
m_IsMultihomed = true;
|
||||
m_System->Printf("Network uses %s as host IP.\n", m_LocalAddress.ToBaseString());
|
||||
}
|
||||
else
|
||||
{
|
||||
char hostname[512];
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
ResolveAddress(hostname, &m_LocalAddress);
|
||||
}
|
||||
|
||||
char *portparam = m_System->CheckParam("-port");
|
||||
if (!portparam) {
|
||||
portparam = "27020";
|
||||
}
|
||||
|
||||
m_LocalAddress.m_Port = htons(atoi(portparam));
|
||||
m_LastStatsUpdateTime = 0;
|
||||
|
||||
m_State = MODULE_RUNNING;
|
||||
m_System->Printf("Network initialized.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void Network::ExecuteCommand(int commandID, char *commandLine)
|
||||
{
|
||||
if (commandID == CMD_ID_FAKELOSS) {
|
||||
CMD_FakeLoss(commandLine);
|
||||
return;
|
||||
}
|
||||
|
||||
m_System->Printf("ERROR! Network::ExecuteCommand: unknown command ID %i.\n", commandID);
|
||||
}
|
||||
|
||||
void Network::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
NetSocket *sock;
|
||||
while ((sock = (NetSocket *)m_Sockets.RemoveTail()))
|
||||
{
|
||||
sock->Close();
|
||||
delete sock;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (WSACleanup() == SOCKET_ERROR) {
|
||||
m_System->Printf("Network Error WSACleanup:%s\n", GetErrorText(GetLastErrorCode()));
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
m_System->Printf("Network module shutdown.\n");
|
||||
BaseSystemModule::ShutDown();
|
||||
}
|
||||
|
||||
INetSocket *Network::CreateSocket(int port, bool reuse, bool loopback)
|
||||
{
|
||||
NetSocket *socket = GetSocket(port);
|
||||
if (socket) {
|
||||
return socket;
|
||||
}
|
||||
|
||||
socket = new NetSocket;
|
||||
if (!socket) {
|
||||
m_System->Printf("ERROR! Network::CreateSocket: out of memory.\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!socket->Create(this, port, reuse, loopback))
|
||||
{
|
||||
m_System->Printf("ERROR! Network::CreateSocket: %s.\n", GetErrorText(GetLastErrorCode()));
|
||||
|
||||
delete socket;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_Sockets.Add(socket);
|
||||
return socket;
|
||||
}
|
||||
|
||||
bool Network::RemoveSocket(INetSocket *netsocket)
|
||||
{
|
||||
return m_Sockets.Remove(netsocket);
|
||||
}
|
||||
|
||||
char *Network::GetType()
|
||||
{
|
||||
return NETWORK_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
int Network::ReceiveData()
|
||||
{
|
||||
int countPackets = 0;
|
||||
NetSocket *sock = (NetSocket *)m_Sockets.GetFirst();
|
||||
while (sock)
|
||||
{
|
||||
countPackets += sock->DispatchIncoming();
|
||||
sock = (NetSocket *)m_Sockets.GetNext();
|
||||
}
|
||||
|
||||
return countPackets;
|
||||
}
|
||||
|
||||
int Network::SendData()
|
||||
{
|
||||
int countPackets = 0;
|
||||
NetSocket *sock = (NetSocket *)m_Sockets.GetFirst();
|
||||
while (sock)
|
||||
{
|
||||
countPackets += sock->DrainChannels();
|
||||
sock = (NetSocket *)m_Sockets.GetNext();
|
||||
}
|
||||
|
||||
return countPackets;
|
||||
}
|
||||
|
||||
NetSocket *Network::GetSocket(int port)
|
||||
{
|
||||
NetSocket *sock = (NetSocket *)m_Sockets.GetFirst();
|
||||
if (!sock) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
while (sock)
|
||||
{
|
||||
if (sock->GetPort() == port || !port) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
sock = (NetSocket *)m_Sockets.GetNext();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Network::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
SendData();
|
||||
ReceiveData();
|
||||
UpdateStats();
|
||||
}
|
||||
|
||||
NetAddress *Network::GetLocalAddress()
|
||||
{
|
||||
return &m_LocalAddress;
|
||||
}
|
||||
|
||||
char *Network::GetStatusLine()
|
||||
{
|
||||
static char string[256];
|
||||
float in, out;
|
||||
|
||||
GetFlowStats(&in, &out);
|
||||
_snprintf(string, sizeof(string), "Local IP %s, Sockets %i, In %.2f, Out %.2f.\n", m_LocalAddress.ToBaseString(), m_Sockets.CountElements(), in, out);
|
||||
return string;
|
||||
}
|
||||
|
||||
void Network::GetFlowStats(float *totalIn, float *totalOut)
|
||||
{
|
||||
*totalIn = 0;
|
||||
*totalOut = 0;
|
||||
|
||||
NetSocket *sock = (NetSocket *)m_Sockets.GetFirst();
|
||||
while (sock)
|
||||
{
|
||||
float in, out;
|
||||
sock->GetFlowStats(&in, &out);
|
||||
|
||||
*totalIn += in;
|
||||
*totalOut += out;
|
||||
|
||||
sock = (NetSocket *)m_Sockets.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void Network::CMD_FakeLoss(char *cmdLine)
|
||||
{
|
||||
TokenLine params(cmdLine);
|
||||
if (params.CountToken() != 2) {
|
||||
m_System->Printf("Syntax: fakeloss <float>\n");
|
||||
m_System->Printf("Current fakeloss is %.2f\n", m_FakeLoss);
|
||||
return;
|
||||
}
|
||||
|
||||
m_FakeLoss = atof(params.GetToken(1));
|
||||
}
|
||||
|
||||
int Network::GetLastErrorCode()
|
||||
{
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
bool Network::ResolveAddress(char *string, NetAddress *address)
|
||||
{
|
||||
sockaddr sadr;
|
||||
hostent *h;
|
||||
char copy[128];
|
||||
|
||||
address->Clear();
|
||||
|
||||
if (!string || !strlen(string)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&sadr, 0, sizeof(sadr));
|
||||
((sockaddr_in *)&sadr)->sin_family = AF_INET;
|
||||
((sockaddr_in *)&sadr)->sin_port = 0;
|
||||
|
||||
strcopy(copy, string);
|
||||
|
||||
// Parse port
|
||||
char *colon = copy;
|
||||
while (*colon != '\0')
|
||||
{
|
||||
if (*colon == ':')
|
||||
{
|
||||
*colon = '\0';
|
||||
int val = atoi(colon + 1);
|
||||
((sockaddr_in *)&sadr)->sin_port = htons(val);
|
||||
}
|
||||
colon++;
|
||||
}
|
||||
|
||||
// Parse address
|
||||
// Validate IPv4
|
||||
if (copy[0] >= '0' && copy[0] <= '9' && strstr(copy, "."))
|
||||
{
|
||||
uint32 ret = inet_addr(copy);
|
||||
if (ret == INADDR_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
((sockaddr_in *)&sadr)->sin_addr.s_addr = ret;
|
||||
}
|
||||
else if (m_NoDNS)
|
||||
{
|
||||
// do not resolve address via DNS.
|
||||
return false;
|
||||
}
|
||||
// If we allow the use of DNS,
|
||||
// let's get the address by the hostname.
|
||||
else
|
||||
{
|
||||
h = gethostbyname(copy);
|
||||
if (!h || !h->h_addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
((sockaddr_in *)&sadr)->sin_addr.s_addr = *(uint32 *)h->h_addr;
|
||||
}
|
||||
|
||||
return address->FromSockadr(&sadr);
|
||||
}
|
||||
|
||||
char *Network::GetErrorText(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case WSAEINTR: return "WSAEINTR";
|
||||
case WSAEBADF: return "WSAEBADF";
|
||||
case WSAEACCES: return "WSAEACCES";
|
||||
case WSAEFAULT: return "WSAEFAULT";
|
||||
case WSAEINVAL: return "WSAEINVAL";
|
||||
case WSAEMFILE: return "WSAEMFILE";
|
||||
case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK";
|
||||
case WSAEINPROGRESS: return "WSAEINPROGRESS";
|
||||
case WSAEALREADY: return "WSAEALREADY";
|
||||
case WSAENOTSOCK: return "WSAENOTSOCK";
|
||||
case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ";
|
||||
case WSAEMSGSIZE: return "WSAEMSGSIZE";
|
||||
case WSAEPROTOTYPE: return "WSAEPROTOTYPE";
|
||||
case WSAENOPROTOOPT: return "WSAENOPROTOOPT";
|
||||
case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT";
|
||||
case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT";
|
||||
case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP";
|
||||
case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT";
|
||||
case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT";
|
||||
case WSAEADDRINUSE: return "WSAEADDRINUSE";
|
||||
case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL";
|
||||
case WSAENETDOWN: return "WSAENETDOWN";
|
||||
case WSAENETUNREACH: return "WSAENETUNREACH";
|
||||
case WSAENETRESET: return "WSAENETRESET";
|
||||
case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR";
|
||||
case WSAECONNRESET: return "WSAECONNRESET";
|
||||
case WSAENOBUFS: return "WSAENOBUFS";
|
||||
case WSAEISCONN: return "WSAEISCONN";
|
||||
case WSAENOTCONN: return "WSAENOTCONN";
|
||||
case WSAESHUTDOWN: return "WSAESHUTDOWN";
|
||||
case WSAETOOMANYREFS: return "WSAETOOMANYREFS";
|
||||
case WSAETIMEDOUT: return "WSAETIMEDOUT";
|
||||
case WSAECONNREFUSED: return "WSAECONNREFUSED";
|
||||
case WSAELOOP: return "WSAELOOP";
|
||||
case WSAENAMETOOLONG: return "WSAENAMETOOLONG";
|
||||
case WSAEHOSTDOWN: return "WSAEHOSTDOWN";
|
||||
default: return "UNKNOWN ERROR";
|
||||
|
||||
#ifdef _WIN32
|
||||
case WSASYSNOTREADY: return "WSASYSNOTREADY";
|
||||
case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED";
|
||||
case WSANOTINITIALISED: return "WSANOTINITIALISED";
|
||||
case WSAEDISCON: return "WSAEDISCON";
|
||||
case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND";
|
||||
case WSATRY_AGAIN: return "WSATRY_AGAIN";
|
||||
case WSANO_RECOVERY: return "WSANO_RECOVERY";
|
||||
case WSANO_DATA: return "WSANO_DATA";
|
||||
#endif // _WIN32
|
||||
}
|
||||
}
|
||||
|
||||
void Network::SetName(char *newName)
|
||||
{
|
||||
strcopy(m_Name, newName);
|
||||
}
|
||||
|
||||
void Network::UpdateStats()
|
||||
{
|
||||
if (m_LastStatsUpdateTime + 0.5 > m_SystemTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
NetSocket *sock = (NetSocket *)m_Sockets.GetFirst();
|
||||
while (sock)
|
||||
{
|
||||
sock->UpdateStats(m_SystemTime);
|
||||
sock = (NetSocket *)m_Sockets.GetNext();
|
||||
}
|
||||
|
||||
m_LastStatsUpdateTime = m_SystemTime;
|
||||
}
|
||||
|
||||
void Network::ReceiveSignal(ISystemModule *module, unsigned int signal, void *data)
|
||||
{
|
||||
BaseSystemModule::ReceiveSignal(module, signal, data);
|
||||
}
|
||||
|
||||
void Network::RegisterListener(ISystemModule *module)
|
||||
{
|
||||
BaseSystemModule::RegisterListener(module);
|
||||
}
|
||||
|
||||
void Network::RemoveListener(ISystemModule *module)
|
||||
{
|
||||
BaseSystemModule::RemoveListener(module);
|
||||
}
|
||||
|
||||
IBaseSystem *Network::GetSystem()
|
||||
{
|
||||
return BaseSystemModule::GetSystem();
|
||||
}
|
||||
|
||||
int Network::GetSerial()
|
||||
{
|
||||
return BaseSystemModule::GetSerial();
|
||||
}
|
||||
|
||||
char *Network::GetName()
|
||||
{
|
||||
return BaseSystemModule::GetName();
|
||||
}
|
||||
|
||||
int Network::GetState()
|
||||
{
|
||||
return BaseSystemModule::GetState();
|
||||
}
|
||||
|
||||
int Network::GetVersion()
|
||||
{
|
||||
return BaseSystemModule::GetVersion();
|
||||
}
|
||||
|
||||
IBaseInterface *CreateNetwork()
|
||||
{
|
||||
INetwork *pNetwork = new Network;
|
||||
return (IBaseInterface *)pNetwork;
|
||||
}
|
||||
|
||||
#ifndef HOOK_HLTV
|
||||
EXPOSE_INTERFACE_FN(CreateNetwork, Network, NETWORK_INTERFACE_VERSION);
|
||||
#endif // HOOK_HLTV
|
130
rehlds/HLTV/Core/src/Network.h
Normal file
130
rehlds/HLTV/Core/src/Network.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/INetwork.h>
|
||||
#include "BaseSystemModule.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#define WSAEWOULDBLOCK EWOULDBLOCK // Operation would block EAGAIN (11)
|
||||
#define WSAEMSGSIZE EMSGSIZE // Message too long (90)
|
||||
#define WSAEADDRNOTAVAIL EADDRNOTAVAIL // Cannot assign requested address (99)
|
||||
#define WSAEAFNOSUPPORT EAFNOSUPPORT // Address family not supported by protocol (97)
|
||||
#define WSAECONNRESET ECONNRESET // Connection reset by peer (104)
|
||||
#define WSAECONNREFUSED ECONNREFUSED // Connection refused (111)
|
||||
#define WSAEADDRINUSE EADDRINUSE // Address already in use (98)
|
||||
#define WSAENOBUFS ENOBUFS // No buffer space available (105)
|
||||
|
||||
#define WSAEINTR EINTR // Interrupted system call
|
||||
#define WSAEBADF EBADF // Bad file number
|
||||
#define WSAEACCES EACCES // Permission denied
|
||||
#define WSAEFAULT EFAULT // Bad address
|
||||
#define WSAEINVAL EINVAL // Invalid argument
|
||||
#define WSAEMFILE EMFILE // Too many open files
|
||||
#define WSAEWOULDBLOCK EWOULDBLOCK // Operation would block
|
||||
#define WSAEINPROGRESS EINPROGRESS // Operation now in progress
|
||||
#define WSAEALREADY EALREADY // Operation already in progress
|
||||
#define WSAENOTSOCK ENOTSOCK // Socket operation on non-socket
|
||||
#define WSAEDESTADDRREQ EDESTADDRREQ // Destination address required
|
||||
#define WSAEMSGSIZE EMSGSIZE // Message too long
|
||||
#define WSAEPROTOTYPE EPROTOTYPE // Protocol wrong type for socket
|
||||
#define WSAENOPROTOOPT ENOPROTOOPT // Protocol not available
|
||||
#define WSAEPROTONOSUPPORT EPROTONOSUPPORT // Protocol not supported
|
||||
#define WSAESOCKTNOSUPPORT ESOCKTNOSUPPORT // Socket type not supported
|
||||
#define WSAEOPNOTSUPP EOPNOTSUPP // Operation not supported on transport endpoint
|
||||
#define WSAEPFNOSUPPORT EPFNOSUPPORT // Protocol family not supported
|
||||
#define WSAEAFNOSUPPORT EAFNOSUPPORT // Address family not supported by protocol
|
||||
#define WSAEADDRINUSE EADDRINUSE // Address already in use
|
||||
#define WSAEADDRNOTAVAIL EADDRNOTAVAIL // Cannot assign requested address
|
||||
#define WSAENETDOWN ENETDOWN // Network is down
|
||||
#define WSAENETUNREACH ENETUNREACH // Network is unreachable
|
||||
#define WSAENETRESET ENETRESET // Network dropped connection because of reset
|
||||
#define WSAECONNABORTED ECONNABORTED // Software caused connection abort
|
||||
#define WSAECONNRESET ECONNRESET // Connection reset by peer
|
||||
#define WSAENOBUFS ENOBUFS // No buffer space available
|
||||
#define WSAEISCONN EISCONN // Transport endpoint is already connected
|
||||
#define WSAENOTCONN ENOTCONN // Transport endpoint is not connected
|
||||
#define WSAESHUTDOWN ESHUTDOWN // Cannot send after transport endpoint shutdown
|
||||
#define WSAETOOMANYREFS ETOOMANYREFS // Too many references: cannot splice
|
||||
#define WSAETIMEDOUT ETIMEDOUT // Connection timed out
|
||||
#define WSAECONNREFUSED ECONNREFUSED // Connection refused
|
||||
#define WSAELOOP ELOOP // Too many symbolic links encountered
|
||||
#define WSAENAMETOOLONG ENAMETOOLONG // File name too long
|
||||
#define WSAEHOSTDOWN EHOSTDOWN // Host is down
|
||||
#endif // _WIN32
|
||||
|
||||
class NetSocket;
|
||||
class Network: public BaseSystemModule, public INetwork {
|
||||
public:
|
||||
Network() {}
|
||||
virtual ~Network() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
void RegisterListener(ISystemModule *module);
|
||||
void RemoveListener(ISystemModule *module);
|
||||
IBaseSystem *GetSystem();
|
||||
int GetSerial();
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
char *GetName();
|
||||
int GetState();
|
||||
int GetVersion();
|
||||
void ShutDown();
|
||||
|
||||
INetSocket *CreateSocket(int port, bool reuse, bool loopback);
|
||||
bool RemoveSocket(INetSocket *netsocket);
|
||||
NetAddress *GetLocalAddress();
|
||||
bool ResolveAddress(char *string, NetAddress *address);
|
||||
void GetFlowStats(float *totalIn, float *totalOut);
|
||||
int GetLastErrorCode();
|
||||
char *GetErrorText(int code);
|
||||
|
||||
protected:
|
||||
enum LocalCommandIDs { CMD_ID_FAKELOSS = 1 };
|
||||
void CMD_FakeLoss(char *cmdLine);
|
||||
|
||||
void SetName(char *newName);
|
||||
void UpdateStats();
|
||||
NetSocket *GetSocket(int port);
|
||||
int SendData();
|
||||
int ReceiveData();
|
||||
|
||||
protected:
|
||||
friend class NetSocket;
|
||||
|
||||
float m_FakeLoss;
|
||||
NetAddress m_LocalAddress;
|
||||
bool m_IsMultihomed;
|
||||
bool m_NoDNS;
|
||||
double m_LastStatsUpdateTime;
|
||||
ObjectList m_Sockets;
|
||||
};
|
2388
rehlds/HLTV/Core/src/Server.cpp
Normal file
2388
rehlds/HLTV/Core/src/Server.cpp
Normal file
File diff suppressed because it is too large
Load Diff
266
rehlds/HLTV/Core/src/Server.h
Normal file
266
rehlds/HLTV/Core/src/Server.h
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IServer.h>
|
||||
#include "BaseSystemModule.h"
|
||||
#include "TokenLine.h"
|
||||
|
||||
class IWorld;
|
||||
class IProxy;
|
||||
class IDirector;
|
||||
class IFileSystem;
|
||||
class NetPacket;
|
||||
class INetSocket;
|
||||
|
||||
#define MAX_SERVER_RATE 20000
|
||||
#define MAX_SERVER_UPDATERATE 100
|
||||
|
||||
#define TE_MAX 128
|
||||
|
||||
// Sound flags
|
||||
enum
|
||||
{
|
||||
SND_FL_VOLUME = BIT(0), // send volume
|
||||
SND_FL_ATTENUATION = BIT(1), // send attenuation
|
||||
SND_FL_LARGE_INDEX = BIT(2), // send sound number as short instead of byte
|
||||
SND_FL_PITCH = BIT(3), // send pitch
|
||||
SND_FL_SENTENCE = BIT(4), // set if sound num is actually a sentence num
|
||||
SND_FL_STOP = BIT(5), // stop the sound
|
||||
SND_FL_CHANGE_VOL = BIT(6), // change sound vol
|
||||
SND_FL_CHANGE_PITCH = BIT(7), // change sound pitch
|
||||
SND_FL_SPAWNING = BIT(8) // we're spawning, used in some cases for ambients (not sent across network)
|
||||
};
|
||||
|
||||
class Server: public IServer, public BaseSystemModule {
|
||||
public:
|
||||
Server() {}
|
||||
virtual ~Server() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
void RegisterListener(ISystemModule *module);
|
||||
void RemoveListener(ISystemModule *module);
|
||||
IBaseSystem *GetSystem();
|
||||
int GetSerial();
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
char *GetName();
|
||||
int GetState();
|
||||
int GetVersion();
|
||||
void ShutDown();
|
||||
|
||||
bool Connect(IWorld *world, NetAddress *address, INetSocket *socket);
|
||||
bool LoadDemo(IWorld *world, char *filename, bool forceHLTV, bool continuous);
|
||||
void Reconnect();
|
||||
void Disconnect();
|
||||
void Retry();
|
||||
void StopRetry();
|
||||
void SendStringCommand(char *command);
|
||||
void SendHLTVCommand(BitBuffer *msg);
|
||||
void SetPlayerName(char *newName);
|
||||
void SetProxy(IProxy *proxy);
|
||||
void SetDirector(IDirector *director);
|
||||
void SetDelayReconnect(bool state);
|
||||
void SetAutoRetry(bool state);
|
||||
void SetVoiceBlocking(bool state);
|
||||
void SetRate(int rate);
|
||||
void SetUpdateRate(int updaterate);
|
||||
void SetUserInfo(char *key, char *value);
|
||||
bool SetProtocol(int version);
|
||||
void SetGameDirectory(const char *defaultDir, const char *gameDir);
|
||||
bool IsConnected();
|
||||
bool IsDemoFile();
|
||||
bool IsGameServer();
|
||||
bool IsRelayProxy();
|
||||
bool IsVoiceBlocking();
|
||||
int GetRate();
|
||||
int GetUpdateRate();
|
||||
char *GetPlayerName();
|
||||
InfoString *GetServerInfoString();
|
||||
|
||||
float GetTime();
|
||||
IWorld *GetWorld();
|
||||
char *GetDemoFileName();
|
||||
NetAddress *GetAddress();
|
||||
bool GetAutoRetry();
|
||||
char *GetHostName();
|
||||
float GetPacketLoss();
|
||||
int GetProtocol();
|
||||
|
||||
private:
|
||||
public:
|
||||
void CheckAutoRetry();
|
||||
void CheckConnection();
|
||||
void ScheduleAutoRetry();
|
||||
void AcceptConnection();
|
||||
void AcceptBadPassword();
|
||||
void AcceptRejection(char *reason);
|
||||
void AcceptRedirect(char *toAddress);
|
||||
void SendConnectPacket();
|
||||
void SendServerCommands();
|
||||
|
||||
enum ServerState {
|
||||
SERVER_UNDEFINED,
|
||||
SERVER_INITIALIZING,
|
||||
SERVER_DISCONNECTED,
|
||||
SERVER_CHALLENGING,
|
||||
SERVER_AUTHENTICATING,
|
||||
SERVER_CONNECTING,
|
||||
SERVER_CONNECTED,
|
||||
SERVER_RUNNING,
|
||||
SERVER_INTERMISSION,
|
||||
};
|
||||
|
||||
void SetState(ServerState newState);
|
||||
void Challenge();
|
||||
void Reset();
|
||||
void AcceptChallenge(char *cmdLine);
|
||||
void SendUserVar(char *key, char *value);
|
||||
char *GetCmdName(int cmd);
|
||||
void SetName(char *newName);
|
||||
void ProcessMessage(unsigned int seqNr);
|
||||
void ProcessEntityUpdate();
|
||||
bool ProcessConnectionlessMessage(NetAddress *from, BitBuffer *stream);
|
||||
void ClearFrame(bool completely);
|
||||
void ParseHLTV();
|
||||
void ParseDirector();
|
||||
void ParseFileTransferFailed();
|
||||
void ParseInfo(BitBuffer *stream, bool detailed);
|
||||
void ParseParticle();
|
||||
void ParseRoomType();
|
||||
void ParseSpawnStaticSound();
|
||||
void ParseEventReliable();
|
||||
void ParsePings();
|
||||
void ParseStopSound();
|
||||
void ParseEvent();
|
||||
void ParseSound();
|
||||
void ParseDeltaPacketEntities();
|
||||
void ParsePacketEntities();
|
||||
bool ParseUserMessage(int cmd);
|
||||
void ParseCustomization();
|
||||
void ParseCrosshairAngle();
|
||||
void ParseSoundFade();
|
||||
void ParseSignonNum();
|
||||
void ParseDisconnect();
|
||||
void ParseChoke();
|
||||
void ParseSetAngle();
|
||||
void ParseAddAngle();
|
||||
void ParseLightStyle();
|
||||
void ParseTime();
|
||||
void ParseVersion();
|
||||
void ParseBaseline();
|
||||
void ParseTempEntity();
|
||||
void ParseResourceList();
|
||||
void ParseUpdateUserInfo();
|
||||
void ParseStuffText();
|
||||
void ParseNewUserMsg();
|
||||
void ParseResourceRequest();
|
||||
void ParseSetView();
|
||||
void ParseCDTrack();
|
||||
void ParseRestore();
|
||||
void ParseMoveVars();
|
||||
void ParseDeltaDescription();
|
||||
void ParseServerinfo();
|
||||
void ParseBad();
|
||||
void ParseNop();
|
||||
void ParsePrint();
|
||||
void ParseVoiceInit();
|
||||
void ParseVoiceData();
|
||||
void ParseTimeScale();
|
||||
void ParseSendExtraInfo();
|
||||
void ParseCenterPrint();
|
||||
void ParseSetPause();
|
||||
void ParseCutscene();
|
||||
void ParseWeaponAnim();
|
||||
void ParseDecalName();
|
||||
void ParseFinale();
|
||||
void ParseIntermission();
|
||||
void ParseClientData();
|
||||
void ParseResourceLocation();
|
||||
void ParseSendCvarValue();
|
||||
void ParseSendCvarValue2();
|
||||
|
||||
protected:
|
||||
struct svc_func_s {
|
||||
svc_commands_e opcode;
|
||||
char *pszname;
|
||||
void (Server::*func)();
|
||||
};
|
||||
static svc_func_s m_ClientFuncs[];
|
||||
|
||||
IWorld *m_World;
|
||||
IProxy *m_Proxy;
|
||||
IDirector *m_Director;
|
||||
IFileSystem *m_FileSystem;
|
||||
int m_ChallengeNumber;
|
||||
|
||||
INetSocket *m_ServerSocket;
|
||||
NetChannel m_ServerChannel;
|
||||
NetAddress m_ServerAddress;
|
||||
|
||||
int m_ServerState;
|
||||
char m_HostName[MAX_PATH];
|
||||
int m_CurrentRetry;
|
||||
InfoString m_UserInfo;
|
||||
char m_CDKey[32];
|
||||
int m_AuthProtocol;
|
||||
frame_t m_Frame;
|
||||
unsigned char m_EntityBuffer[87040];
|
||||
int m_Rate;
|
||||
int m_UpdateRate;
|
||||
float m_Time;
|
||||
BitBuffer m_ReliableData;
|
||||
BitBuffer m_UnreliableData;
|
||||
BitBuffer m_VoiceData;
|
||||
BitBuffer m_UserMessages;
|
||||
BitBuffer m_ClientData;
|
||||
BitBuffer *m_Instream;
|
||||
int m_validSequence;
|
||||
bool m_AutoRetry;
|
||||
double m_NextAutoRetry;
|
||||
bool m_IsHLTV;
|
||||
bool m_ForceHLTV;
|
||||
bool m_IsGameServer;
|
||||
bool m_IsPaused;
|
||||
bool m_IsVoiceBlocking;
|
||||
DemoFile m_DemoFile;
|
||||
demo_info_t m_DemoInfo;
|
||||
BitBuffer m_DemoData;
|
||||
CRC32_t m_ServerCRC;
|
||||
int m_ServerCount;
|
||||
int m_ClientPlayerNum;
|
||||
int m_Protocol;
|
||||
clientdata_t m_ClientDataStruct;
|
||||
InfoString m_ServerInfo;
|
||||
bool m_DelayReconnect;
|
||||
unsigned int m_SeqNrMap[256];
|
||||
};
|
2380
rehlds/HLTV/Core/src/World.cpp
Normal file
2380
rehlds/HLTV/Core/src/World.cpp
Normal file
File diff suppressed because it is too large
Load Diff
310
rehlds/HLTV/Core/src/World.h
Normal file
310
rehlds/HLTV/Core/src/World.h
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "info.h" // MAX_INFO_STRING
|
||||
#include "qlimits.h" // MAX_PACKET_ENTITIES
|
||||
|
||||
#include "Delta.h"
|
||||
#include "ObjectDictionary.h"
|
||||
#include "BSPModel.h"
|
||||
|
||||
// TODO: move to qlimits.h
|
||||
#define RESOURCE_INDEX_BITS 12
|
||||
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
|
||||
|
||||
class World: public IWorld, public BaseSystemModule {
|
||||
public:
|
||||
World() {}
|
||||
virtual ~World() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
void RegisterListener(ISystemModule *module);
|
||||
void RemoveListener(ISystemModule *module);
|
||||
IBaseSystem *GetSystem();
|
||||
int GetSerial();
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
char *GetName();
|
||||
int GetState();
|
||||
int GetVersion();
|
||||
void ShutDown();
|
||||
|
||||
double GetTime();
|
||||
NetAddress *GetGameServerAddress();
|
||||
char *GetLevelName();
|
||||
char *GetGameDir();
|
||||
frame_t *GetFrameByTime(double time);
|
||||
frame_t *GetFrameBySeqNr(unsigned int seqnr);
|
||||
frame_t *GetLastFrame();
|
||||
frame_t *GetFirstFrame();
|
||||
int GetServerCount();
|
||||
int GetSlotNumber();
|
||||
int GetMaxClients();
|
||||
int GetNumPlayers();
|
||||
IBSPModel *GetWorldModel();
|
||||
InfoString *GetServerInfoString();
|
||||
bool GetPlayerInfoString(int playerNum, InfoString *infoString);
|
||||
UserMsg *GetUserMsg(int msgNumber);
|
||||
char *GetHostName();
|
||||
serverinfo_t *GetServerInfo();
|
||||
|
||||
bool IsPlayerIndex(int index);
|
||||
bool IsVoiceEnabled();
|
||||
bool IsActive();
|
||||
bool IsPaused();
|
||||
bool IsComplete();
|
||||
bool IsHLTV();
|
||||
void Reset();
|
||||
|
||||
void SetServerInfo(int protocol, CRC32_t nserverCRC, unsigned char *nclientdllmd5, int nmaxclients, int nplayernum, int ngametype, char *ngamedir, char *nservername, char *nlevelname);
|
||||
void SetServerInfoString(char *infostring);
|
||||
void SetServerInfo(serverinfo_t *serverinfo);
|
||||
|
||||
void UpdateServerInfo();
|
||||
void SetPaused(bool state);
|
||||
void SetTime(double newTime);
|
||||
void SetBufferSize(float seconds);
|
||||
void SetVoiceEnabled(bool state);
|
||||
void SetMoveVars(movevars_t *nmovevars);
|
||||
void SetCDInfo(int ncdtrack, int nlooptrack);
|
||||
void SetHLTV(bool state);
|
||||
void SetExtraInfo(char *nclientfallback, int nallowCheats);
|
||||
void SetViewEntity(int nviewentity);
|
||||
void SetGameServerAddress(NetAddress *address);
|
||||
void SetHostName(char *name);
|
||||
void NewGame(int newServerCount);
|
||||
void FinishGame();
|
||||
bool SaveAsDemo(char *filename, IDirector *director);
|
||||
void StopGame();
|
||||
int FindUserMsgByName(char *name);
|
||||
void ParseDeltaDescription(BitBuffer *stream);
|
||||
void ParseBaseline(BitBuffer *stream);
|
||||
void ParseEvent(BitBuffer *stream);
|
||||
void ParseClientData(BitBuffer *stream, unsigned int deltaSeqNr, BitBuffer *to, clientdata_t *clientData);
|
||||
bool GetUncompressedFrame(unsigned int seqNr, frame_t *frame);
|
||||
bool UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream);
|
||||
bool UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsigned int from);
|
||||
bool GetClientData(unsigned int SeqNr, clientdata_t *clientData);
|
||||
bool GetClientData(frame_t *frame, clientdata_t *clientData);
|
||||
int AddFrame(frame_t *newFrame);
|
||||
bool AddResource(resource_t *resource);
|
||||
void AddLightStyle(int index, char *style);
|
||||
bool AddSignonData(unsigned char type, unsigned char *data, int size);
|
||||
bool AddUserMessage(int msgNumber, int size, char *name);
|
||||
void AddBaselineEntity(int index, entity_state_t *ent);
|
||||
void AddInstancedBaselineEntity(int index, entity_state_t *ent);
|
||||
void UpdatePlayer(int playerNum, int userId, char *infostring, char *hashedcdkey);
|
||||
|
||||
void WriteFrame(frame_t *frame, unsigned int lastFrameSeqnr, BitBuffer *reliableStream, BitBuffer *unreliableStream, unsigned int deltaSeqNr, unsigned int clientDelta, bool addVoice);
|
||||
void WriteNewData(BitBuffer *stream);
|
||||
void WriteClientUpdate(BitBuffer *stream, int playerIndex);
|
||||
void WriteMovevars(BitBuffer *stream);
|
||||
void WriteSigonData(BitBuffer *stream);
|
||||
void WriteLightStyles(BitBuffer *stream);
|
||||
|
||||
int RemoveFrames(unsigned int startSeqNr, unsigned int endSeqNr);
|
||||
int DuplicateFrames(unsigned int startSeqNr, unsigned int endSeqNr);
|
||||
int MoveFrames(unsigned int startSeqNr, unsigned int endSeqNr, double destSeqnr);
|
||||
int RevertFrames(unsigned int startSeqNr, unsigned int endSeqNr);
|
||||
|
||||
private:
|
||||
int CompressFrame(frame_t *from, BitBuffer *stream);
|
||||
int ParseDeltaHeader(BitBuffer *stream, bool *remove, bool *custom, int *numbase, bool *newbl, int *newblindex, bool full, int *offset);
|
||||
void SetDirector(IDirector *director);
|
||||
void SetTimeScale(float scale);
|
||||
void SetGameGroupAddress(NetAddress *addr);
|
||||
bool SetMaxClients(int max);
|
||||
void SetName(char *newName);
|
||||
IDirector *GetDirector();
|
||||
float GetBufferedGameTime();
|
||||
void ConnectionComplete();
|
||||
|
||||
void WriteResources(BitBuffer *stream);
|
||||
void WriteDeltaDescriptions(BitBuffer *stream);
|
||||
void WriteRegisteredUserMessages(BitBuffer *stream);
|
||||
void WriteBaseline(BitBuffer *stream);
|
||||
void WriteServerinfo(BitBuffer *stream);
|
||||
void WriteCustomDecals(BitBuffer *stream);
|
||||
void WritePacketEntities(BitBuffer *stream, frame_t *frame, frame_t *deltaframe);
|
||||
bool WriteDeltaEntities(BitBuffer *stream, frame_t *fullFrame, unsigned int deltaSeqNr, unsigned int clientDelta);
|
||||
|
||||
enum WorldState {
|
||||
WORLD_UNDEFINED,
|
||||
WORLD_INITIALIZING,
|
||||
WORLD_DISCONNECTED,
|
||||
WORLD_CONNECTING,
|
||||
WORLD_RUNNING,
|
||||
WORLD_COMPLETE
|
||||
};
|
||||
|
||||
void SetState(WorldState newState);
|
||||
void ClearUserMessages();
|
||||
void ClearServerInfo();
|
||||
void ClearResources();
|
||||
void ClearInstancedBaseline();
|
||||
void ClearBaseline();
|
||||
void ClearLightStyles();
|
||||
void ClearPlayers();
|
||||
void ClearFrames();
|
||||
void ClearEntityCache();
|
||||
bool GetFrameFromCache(unsigned int seqNr, entity_state_t **entities);
|
||||
bool GetUncompressedFrame(frame_t *deltaFrame, frame_t *frame);
|
||||
bool GetDeltaFromCache(unsigned int seqNr, unsigned int deltaNr, BitBuffer **buffer);
|
||||
void CheckFrameBufferSize();
|
||||
void ReorderFrameTimes(float newLastTime);
|
||||
int FindBestBaseline(int index, entity_state_t **baseline, entity_state_t *to, int num, bool custom);
|
||||
void RearrangeFrame(frame_t *frame, int seqNrOffset, float timeOffset);
|
||||
|
||||
delta_t *GetEventDelta() const;
|
||||
delta_t *GetClientDelta() const;
|
||||
delta_t *GetEntityDelta() const;
|
||||
delta_t *GetWeaponDelta() const;
|
||||
delta_t *GetDeltaEncoder(int index, bool custom);
|
||||
bool IsDeltaEncoder() const;
|
||||
|
||||
protected:
|
||||
bool m_IsPaused;
|
||||
int m_WorldState;
|
||||
int m_Protocol;
|
||||
int m_ServerCount;
|
||||
CRC32_t m_ServerCRC;
|
||||
unsigned char m_ClientdllMD5[16];
|
||||
int m_Maxclients;
|
||||
int m_PlayerNum;
|
||||
int m_GameType;
|
||||
char m_GameDir[MAX_PATH];
|
||||
char m_LevelName[40];
|
||||
char m_ServerName[255];
|
||||
|
||||
int m_ViewEntity;
|
||||
serverinfo_t m_DetailedServerInfo;
|
||||
|
||||
enum {
|
||||
MAX_ENTITIES = 1380,
|
||||
MAX_INSTANCED_BASELINES = 64,
|
||||
MAX_FRAME_CACHE = 32,
|
||||
MAX_SCOREBOARDNAME = 32,
|
||||
|
||||
MAX_SERVERINFO_STRING = 512,
|
||||
MAX_BUFFER_SIGNONDATA = 32768
|
||||
};
|
||||
|
||||
// Defined in client.h differently
|
||||
typedef struct player_info_s
|
||||
{
|
||||
int userid; // User id on server
|
||||
|
||||
// User info string
|
||||
char userinfo[MAX_INFO_STRING]; // User info string
|
||||
char name[MAX_SCOREBOARDNAME]; // Name
|
||||
int spectator; // Spectator or not, unused
|
||||
int ping;
|
||||
int packet_loss;
|
||||
|
||||
// skin information
|
||||
char model[MAX_PATH];
|
||||
int topcolor;
|
||||
int bottomcolor;
|
||||
|
||||
bool active;
|
||||
char hashedcdkey[16];
|
||||
|
||||
int trackerID;
|
||||
|
||||
} player_info_t;
|
||||
|
||||
player_info_t m_Players[MAX_CLIENTS];
|
||||
unsigned char m_EntityBuffer[87040];
|
||||
|
||||
entity_state_t m_BaseLines[MAX_ENTITIES];
|
||||
int m_MaxBaseLines;
|
||||
entity_state_t m_Instanced_BaseLines[MAX_INSTANCED_BASELINES];
|
||||
|
||||
int m_MaxInstanced_BaseLine;
|
||||
char m_Lightstyles[MAX_LIGHTSTYLES][65];
|
||||
|
||||
movevars_t m_MoveVars;
|
||||
BSPModel m_WorldModel;
|
||||
InfoString m_ServerInfo;
|
||||
UserMsg *m_ClientUserMsgs;
|
||||
resource_t *m_ResourcesList;
|
||||
int m_ResourcesNum;
|
||||
|
||||
BitBuffer m_SignonData;
|
||||
int m_CDTrack;
|
||||
int m_LoopTrack;
|
||||
|
||||
ObjectDictionary m_Frames;
|
||||
ObjectDictionary m_FramesByTime;
|
||||
ObjectDictionary m_CamCommands;
|
||||
|
||||
unsigned int m_SequenceNr;
|
||||
float m_MaxBufferLength;
|
||||
|
||||
typedef struct frameCache_s {
|
||||
unsigned int seqNr;
|
||||
entity_state_t entities[MAX_PACKET_ENTITIES];
|
||||
} frameCache_t;
|
||||
|
||||
typedef struct deltaCache_s {
|
||||
unsigned int seqNr;
|
||||
unsigned int deltaNr;
|
||||
BitBuffer buffer;
|
||||
} deltaCache_t;
|
||||
|
||||
int m_MaxCacheIndex;
|
||||
frameCache_t *m_FrameCache;
|
||||
deltaCache_t *m_DeltaCache;
|
||||
int m_CacheHits;
|
||||
int m_CacheFaults;
|
||||
|
||||
double m_WorldTime;
|
||||
double m_StartTime;
|
||||
|
||||
bool m_VoiceEnabled;
|
||||
char m_ClientFallback[MAX_PATH];
|
||||
bool m_AllowCheats;
|
||||
bool m_IsHLTV;
|
||||
char m_HostName[255];
|
||||
|
||||
NetAddress m_GameServerAddress;
|
||||
|
||||
#ifdef HOOK_HLTV
|
||||
static DeltaWrapper m_Delta;
|
||||
#else
|
||||
Delta m_Delta;
|
||||
#endif // HOOK_HLTV
|
||||
|
||||
};
|
||||
|
||||
extern char g_DownloadURL[128];
|
1
rehlds/HLTV/Core/src/precompiled.cpp
Normal file
1
rehlds/HLTV/Core/src/precompiled.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "precompiled.h"
|
44
rehlds/HLTV/Core/src/precompiled.h
Normal file
44
rehlds/HLTV/Core/src/precompiled.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "archtypes.h"
|
||||
#include "mathlib.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include "interface.h"
|
||||
#include "IBaseSystem.h"
|
||||
|
||||
#include "mem.h"
|
||||
#include "common.h"
|
||||
|
||||
// Hooks stuff
|
||||
#include "hookers/HLTV/Core/hooklist.h"
|
||||
|
||||
#include "common/md5.h"
|
||||
#include "common/random.h"
|
||||
#include "common/byteorder.h"
|
||||
#include "common/ServerInfo.h"
|
||||
#include "common/common_hltv.h"
|
||||
#include "common/net_internal.h"
|
||||
#include "common/mathlib_internal.h"
|
||||
|
||||
#include "common/DirectorCmd.h"
|
||||
#include "common/NetAddress.h"
|
||||
#include "common/NetChannel.h"
|
||||
#include "common/BaseClient.h"
|
||||
|
||||
#include "common/DemoFile.h"
|
||||
#include "common/munge.h"
|
||||
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <HLTV/IProxy.h>
|
||||
#include <HLTV/IServer.h>
|
||||
#include <HLTV/IClient.h>
|
||||
#include <HLTV/INetChannel.h>
|
||||
#include <HLTV/INetwork.h>
|
||||
|
||||
// Core module stuff
|
||||
#include "World.h"
|
||||
#include "Network.h"
|
||||
#include "NetSocket.h"
|
||||
#include "Server.h"
|
3
rehlds/HLTV/Core/src/public_amalgamation.cpp
Normal file
3
rehlds/HLTV/Core/src/public_amalgamation.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "interface.cpp"
|
139
rehlds/HLTV/DemoPlayer/build.gradle
Normal file
139
rehlds/HLTV/DemoPlayer/build.gradle
Normal file
@ -0,0 +1,139 @@
|
||||
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
|
||||
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
|
||||
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
|
||||
import org.gradle.nativeplatform.NativeBinarySpec
|
||||
import org.gradle.nativeplatform.NativeLibrarySpec
|
||||
import org.gradle.nativeplatform.toolchain.VisualCpp
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: IccCompilerPlugin
|
||||
apply plugin: GccCompilerPlugin
|
||||
|
||||
void setupToolchain(NativeBinarySpec b) {
|
||||
def cfg = rootProject.createToolchainConfig(b);
|
||||
cfg.projectInclude(project, '/..', '/../..', '/src', '/../common', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared');
|
||||
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'DEMOPLAYER_MODULE'
|
||||
|
||||
if (cfg instanceof MsvcToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
|
||||
enabled: true,
|
||||
pchHeader: 'precompiled.h',
|
||||
pchSourceSet: 'demoplayer_pch'
|
||||
);
|
||||
|
||||
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
||||
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF'
|
||||
cfg.extraLibs "psapi.lib"
|
||||
}
|
||||
else if (cfg instanceof GccToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'demoplayer_pch'
|
||||
);
|
||||
|
||||
cfg.compilerOptions.languageStandard = 'c++0x'
|
||||
cfg.defines([
|
||||
'_strdup': 'strdup',
|
||||
'_stricmp': 'strcasecmp',
|
||||
'_strnicmp': 'strncasecmp',
|
||||
'_vsnprintf': 'vsnprintf',
|
||||
'_snprintf': 'snprintf',
|
||||
]);
|
||||
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-fno-exceptions'
|
||||
}
|
||||
|
||||
ToolchainConfigUtils.apply(project, cfg, b);
|
||||
}
|
||||
|
||||
model {
|
||||
buildTypes {
|
||||
release
|
||||
}
|
||||
|
||||
platforms {
|
||||
x86 {
|
||||
architecture "x86"
|
||||
}
|
||||
}
|
||||
|
||||
toolChains {
|
||||
visualCpp(VisualCpp) {
|
||||
}
|
||||
icc(Icc) {
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
demoplayer(NativeLibrarySpec) {
|
||||
targetPlatform 'x86'
|
||||
baseName 'demoplayer'
|
||||
|
||||
sources {
|
||||
demoplayer_main(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "**/*.cpp"
|
||||
exclude "precompiled.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
demoplayer_common(CppSourceSet) {
|
||||
source {
|
||||
srcDirs "/../../common", "/../common"
|
||||
|
||||
// common
|
||||
include "BaseSystemModule.cpp"
|
||||
include "ObjectDictionary.cpp"
|
||||
include "ObjectList.cpp"
|
||||
include "TokenLine.cpp"
|
||||
|
||||
// HLTV common
|
||||
include "BitBuffer.cpp"
|
||||
include "byteorder.cpp"
|
||||
include "common.cpp"
|
||||
include "DirectorCmd.cpp"
|
||||
include "mathlib.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
demoplayer_engine(CppSourceSet) {
|
||||
source {
|
||||
srcDir "../../engine"
|
||||
include "mem.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
demoplayer_pch(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "precompiled.cpp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binaries.all {
|
||||
NativeBinarySpec b -> project.setupToolchain(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task buildFixes {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
task buildRelease {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
// prevent static lib building
|
||||
binaries.withType(StaticLibraryBinarySpec) { binary ->
|
||||
buildable = false
|
||||
}
|
22
rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.sln
Normal file
22
rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.sln
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoPlayer", "DemoPlayer.vcxproj", "{05292761-0847-4A68-BA10-9D384DC0D3EE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{05292761-0847-4A68-BA10-9D384DC0D3EE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{05292761-0847-4A68-BA10-9D384DC0D3EE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{05292761-0847-4A68-BA10-9D384DC0D3EE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{05292761-0847-4A68-BA10-9D384DC0D3EE}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
175
rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj
Normal file
175
rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj
Normal file
@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" 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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp" />
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp" />
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp" />
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp" />
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\DemoPlayer\hooklist.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\DemoPlayer\main.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp" />
|
||||
<ClCompile Include="..\..\common\byteorder.cpp" />
|
||||
<ClCompile Include="..\..\common\common.cpp" />
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp" />
|
||||
<ClCompile Include="..\..\common\mathlib.cpp" />
|
||||
<ClCompile Include="..\src\DemoPlayer.cpp" />
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
||||
<ClInclude Include="..\..\..\engine\mem.h" />
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\DemoPlayer\hooklist.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BitBuffer.h" />
|
||||
<ClInclude Include="..\..\common\byteorder.h" />
|
||||
<ClInclude Include="..\..\common\common_hltv.h" />
|
||||
<ClInclude Include="..\..\common\DemoFile.h" />
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h" />
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h" />
|
||||
<ClInclude Include="..\src\DemoPlayer.h" />
|
||||
<ClInclude Include="..\src\precompiled.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{05292761-0847-4A68-BA10-9D384DC0D3EE}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>DemoPlayer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;DEMOPLAYER_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\game_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HOOK_HLTV;HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;DEMOPLAYER_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitiHOOons)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<FullProgramDatabaseFile>false</FullProgramDatabaseFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
114
rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj.filters
Normal file
114
rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj.filters
Normal file
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{4d99bbd6-4658-4bed-a29e-9322ec16db5a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV">
|
||||
<UniqueIdentifier>{c58ccefe-767c-4f0a-b075-c55e24d15263}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV\common">
|
||||
<UniqueIdentifier>{ca1c7722-8e65-480d-9e3c-34f7f2524372}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\hookers">
|
||||
<UniqueIdentifier>{1f62aa80-c3f7-4f97-a93e-5b67b153a751}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="engine">
|
||||
<UniqueIdentifier>{8712d29d-6fec-42fb-9f6e-5618302f3203}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{fab89dcf-8536-490e-81b3-d9bb29fce8c6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\DemoPlayer.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\byteorder.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\mathlib.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\DemoPlayer\hooklist.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\DemoPlayer\main.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp">
|
||||
<Filter>engine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\DemoPlayer.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\precompiled.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\common_hltv.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BitBuffer.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\byteorder.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\DemoPlayer\hooklist.h">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\engine\mem.h">
|
||||
<Filter>engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DemoFile.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
39
rehlds/HLTV/DemoPlayer/msvc/PostBuild.bat
Normal file
39
rehlds/HLTV/DemoPlayer/msvc/PostBuild.bat
Normal file
@ -0,0 +1,39 @@
|
||||
@echo OFF
|
||||
::
|
||||
:: Post-build auto-deploy script
|
||||
:: Create and fill PublishPath.txt file with path to deployment folder
|
||||
:: I.e. PublishPath.txt should contain one line with a folder path
|
||||
:: Call it so:
|
||||
:: IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")
|
||||
::
|
||||
|
||||
SET targetDir=%~1
|
||||
SET targetName=%~2
|
||||
SET targetExt=%~3
|
||||
SET projectDir=%~4
|
||||
SET destination=
|
||||
|
||||
IF NOT EXIST "%projectDir%\PublishPath.txt" (
|
||||
ECHO No deployment path specified. Create PublishPath.txt near PostBuild.bat with paths on separate lines for auto deployment.
|
||||
exit /B 0
|
||||
)
|
||||
|
||||
FOR /f "tokens=* delims= usebackq" %%a IN ("%projectDir%\PublishPath.txt") DO (
|
||||
ECHO Deploying to: %%a
|
||||
IF NOT "%%a" == "" (
|
||||
copy /Y "%targetDir%%targetName%%targetExt%" "%%a"
|
||||
IF NOT ERRORLEVEL 1 (
|
||||
IF EXIST "%targetDir%%targetName%.pdb" (
|
||||
copy /Y "%targetDir%%targetName%.pdb" "%%a"
|
||||
)
|
||||
) ELSE (
|
||||
ECHO PostBuild.bat ^(27^) : warning : Can't copy '%targetName%%targetExt%' to deploy path '%%a'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
IF "%%a" == "" (
|
||||
ECHO No deployment path specified.
|
||||
)
|
||||
|
||||
exit /B 0
|
1060
rehlds/HLTV/DemoPlayer/src/DemoPlayer.cpp
Normal file
1060
rehlds/HLTV/DemoPlayer/src/DemoPlayer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
193
rehlds/HLTV/DemoPlayer/src/DemoPlayer.h
Normal file
193
rehlds/HLTV/DemoPlayer/src/DemoPlayer.h
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <HLTV/IServer.h>
|
||||
#include <HLTV/IDirector.h>
|
||||
|
||||
#include "vmodes.h"
|
||||
#include "cdll_int.h"
|
||||
#include "IDemoPlayer.h"
|
||||
#include "IEngineWrapper.h"
|
||||
|
||||
#include "BaseSystemModule.h"
|
||||
#include "ObjectDictionary.h"
|
||||
|
||||
class IProxy;
|
||||
class DirectorCmd;
|
||||
class IBaseSystem;
|
||||
class IObjectContainer;
|
||||
|
||||
class DemoPlayer: public IDemoPlayer, public BaseSystemModule, public IDirector {
|
||||
public:
|
||||
DemoPlayer();
|
||||
virtual ~DemoPlayer() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
void RegisterListener(ISystemModule *module);
|
||||
void RemoveListener(ISystemModule *module);
|
||||
IBaseSystem *GetSystem();
|
||||
int GetSerial();
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
char *GetName();
|
||||
int GetState();
|
||||
int GetVersion();
|
||||
void ShutDown();
|
||||
|
||||
void NewGame(IWorld *world, IProxy *proxy = nullptr);
|
||||
char *GetModName();
|
||||
void WriteCommands(BitBuffer *stream, float startTime, float endTime);
|
||||
int AddCommand(DirectorCmd *cmd);
|
||||
bool RemoveCommand(int index);
|
||||
DirectorCmd *GetLastCommand();
|
||||
IObjectContainer *GetCommands();
|
||||
IDirector *GetDirector();
|
||||
void SetWorldTime(double time, bool relative);
|
||||
void SetTimeScale(float scale);
|
||||
void SetPaused(bool state);
|
||||
void SetEditMode(bool state);
|
||||
void SetMasterMode(bool state);
|
||||
bool IsPaused();
|
||||
bool IsLoading();
|
||||
bool IsActive();
|
||||
bool IsEditMode();
|
||||
bool IsMasterMode();
|
||||
void RemoveFrames(double starttime, double endtime);
|
||||
void ExecuteDirectorCmd(DirectorCmd *cmd);
|
||||
double GetWorldTime();
|
||||
double GetStartTime();
|
||||
double GetEndTime();
|
||||
float GetTimeScale();
|
||||
IWorld *GetWorld();
|
||||
char *GetFileName();
|
||||
bool SaveGame(char *filename);
|
||||
bool LoadGame(char *filename);
|
||||
void Stop();
|
||||
void ForceHLTV(bool state);
|
||||
void GetDemoViewInfo(ref_params_t *rp, float *view, int *viewmodel);
|
||||
int ReadDemoMessage(unsigned char *buffer, int size);
|
||||
void ReadNetchanState(int *incoming_sequence, int *incoming_acknowledged, int *incoming_reliable_acknowledged, int *incoming_reliable_sequence, int *outgoing_sequence, int *reliable_sequence, int *last_reliable_sequence);
|
||||
void SetName(char *newName);
|
||||
|
||||
private:
|
||||
enum LocalCommandIDs {
|
||||
CMD_ID_JUMP = 1,
|
||||
CMD_ID_FORCEHLTV,
|
||||
CMD_ID_PAUSE,
|
||||
CMD_ID_SPEED,
|
||||
CMD_ID_START,
|
||||
CMD_ID_SAVE,
|
||||
};
|
||||
|
||||
void CMD_Jump(char *cmdLine);
|
||||
void CMD_ForceHLTV(char *cmdLine);
|
||||
void CMD_Pause(char *cmdLine);
|
||||
void CMD_Speed(char *cmdLine);
|
||||
void CMD_Start(char *cmdLine);
|
||||
void CMD_Save(char *cmdLine);
|
||||
|
||||
struct LocalCommandID_s {
|
||||
char *name;
|
||||
LocalCommandIDs id;
|
||||
void (DemoPlayer::*pfnCmd)(char *cmdLine);
|
||||
};
|
||||
static LocalCommandID_s m_LocalCmdReg[];
|
||||
|
||||
protected:
|
||||
double GetPlayerTime();
|
||||
char *FormatTime(float time);
|
||||
|
||||
void RunClocks();
|
||||
void WriteDatagram(BitBuffer *stream);
|
||||
void WriteSpawn(BitBuffer *stream);
|
||||
void ReindexCommands();
|
||||
void WriteCameraPath(DirectorCmd *, BitBuffer *stream);
|
||||
|
||||
enum DemoCmds {
|
||||
DEMO_STRINCMD = 3,
|
||||
DEMO_CLIENTDATA = 4,
|
||||
DEMO_EVENT = 6,
|
||||
DEMO_WEAPONANIM = 7,
|
||||
DEMO_PLAYSOUND = 8,
|
||||
DEMO_DATA = 9
|
||||
};
|
||||
|
||||
void ExecuteDemoFileCommands(BitBuffer *stream);
|
||||
|
||||
private:
|
||||
IEngineWrapper *m_Engine;
|
||||
IWorld *m_World;
|
||||
IServer *m_Server;
|
||||
ObjectDictionary m_Commands;
|
||||
DirectorCmd *m_LastCmd;
|
||||
unsigned int m_CommandCounter;
|
||||
char m_DemoFileName[MAX_PATH];
|
||||
|
||||
enum PlayerState {
|
||||
DEMOPLAYER_UNDEFINED,
|
||||
DEMOPLAYER_INITIALIZING,
|
||||
DEMOPLAYER_CONNECTING,
|
||||
DEMOPLAYER_CONNECTED,
|
||||
DEMOPLAYER_RUNNING
|
||||
};
|
||||
|
||||
int m_PlayerState;
|
||||
BitBuffer m_DemoStream;
|
||||
bool m_EditorMode;
|
||||
bool m_MasterMode;
|
||||
bool m_ForceHLTV;
|
||||
bool m_IsSaving;
|
||||
float m_TimeScale;
|
||||
double m_WorldTime;
|
||||
double m_PlayerTime;
|
||||
double m_StartTime;
|
||||
|
||||
double m_LastFrameTime;
|
||||
bool m_IsPaused;
|
||||
double m_LastClockUpdateTime;
|
||||
|
||||
unsigned int m_LastFrameSeqNr;
|
||||
unsigned int m_DeltaFrameSeqNr;
|
||||
unsigned int m_Outgoing_sequence;
|
||||
};
|
||||
|
||||
#ifndef HOOK_HLTV
|
||||
// Use this to expose a singleton interface. This creates the global variable for you automatically.
|
||||
#define EXPOSE_SINGLE_INTERFACE2(className, interfaceName, versionName) \
|
||||
static className __g_##className##_singleton;\
|
||||
static IBaseInterface *__Create##className##interfaceName##_interface() {return (IBaseInterface *)((interfaceName *)&__g_##className##_singleton);}\
|
||||
static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName);
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE2(DemoPlayer, IDemoPlayer, DEMOPLAYER_INTERFACE_VERSION);
|
||||
#endif // HOOK_HLTV
|
1
rehlds/HLTV/DemoPlayer/src/precompiled.cpp
Normal file
1
rehlds/HLTV/DemoPlayer/src/precompiled.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "precompiled.h"
|
23
rehlds/HLTV/DemoPlayer/src/precompiled.h
Normal file
23
rehlds/HLTV/DemoPlayer/src/precompiled.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "archtypes.h"
|
||||
#include "maintypes.h"
|
||||
|
||||
#include "TokenLine.h"
|
||||
#include "interface.h"
|
||||
|
||||
#include "mem.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "common/common_hltv.h"
|
||||
#include "common/net_internal.h"
|
||||
#include "common/mathlib_internal.h"
|
||||
#include "common/byteorder.h"
|
||||
#include "common/BitBuffer.h"
|
||||
#include "common/DirectorCmd.h"
|
||||
#include "common/DemoFile.h"
|
||||
|
||||
#include "DemoPlayer.h"
|
||||
|
||||
// Hooks stuff
|
||||
#include "hookers/HLTV/DemoPlayer/hooklist.h"
|
3
rehlds/HLTV/DemoPlayer/src/public_amalgamation.cpp
Normal file
3
rehlds/HLTV/DemoPlayer/src/public_amalgamation.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "interface.cpp"
|
139
rehlds/HLTV/Director/build.gradle
Normal file
139
rehlds/HLTV/Director/build.gradle
Normal file
@ -0,0 +1,139 @@
|
||||
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
|
||||
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
|
||||
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
|
||||
import org.gradle.nativeplatform.NativeBinarySpec
|
||||
import org.gradle.nativeplatform.NativeLibrarySpec
|
||||
import org.gradle.nativeplatform.toolchain.VisualCpp
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: IccCompilerPlugin
|
||||
apply plugin: GccCompilerPlugin
|
||||
|
||||
void setupToolchain(NativeBinarySpec b) {
|
||||
def cfg = rootProject.createToolchainConfig(b);
|
||||
cfg.projectInclude(project, '/..', '/../..', '/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared');
|
||||
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'DIRECTOR_MODULE'
|
||||
|
||||
if (cfg instanceof MsvcToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
|
||||
enabled: true,
|
||||
pchHeader: 'precompiled.h',
|
||||
pchSourceSet: 'director_pch'
|
||||
);
|
||||
|
||||
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
||||
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF'
|
||||
}
|
||||
else if (cfg instanceof GccToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'director_pch'
|
||||
);
|
||||
|
||||
cfg.compilerOptions.languageStandard = 'c++0x'
|
||||
cfg.defines([
|
||||
'_strdup': 'strdup',
|
||||
'_stricmp': 'strcasecmp',
|
||||
'_strnicmp': 'strncasecmp',
|
||||
'_vsnprintf': 'vsnprintf',
|
||||
'_snprintf': 'snprintf',
|
||||
]);
|
||||
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-fno-exceptions'
|
||||
}
|
||||
|
||||
ToolchainConfigUtils.apply(project, cfg, b);
|
||||
}
|
||||
|
||||
model {
|
||||
buildTypes {
|
||||
release
|
||||
}
|
||||
|
||||
platforms {
|
||||
x86 {
|
||||
architecture "x86"
|
||||
}
|
||||
}
|
||||
|
||||
toolChains {
|
||||
visualCpp(VisualCpp) {
|
||||
}
|
||||
icc(Icc) {
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
director(NativeLibrarySpec) {
|
||||
targetPlatform 'x86'
|
||||
baseName 'director'
|
||||
|
||||
sources {
|
||||
director_main(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "**/*.cpp"
|
||||
exclude "precompiled.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
director_common(CppSourceSet) {
|
||||
source {
|
||||
srcDirs "../../common", "../common"
|
||||
|
||||
// common
|
||||
include "BaseSystemModule.cpp"
|
||||
include "ObjectDictionary.cpp"
|
||||
include "ObjectList.cpp"
|
||||
include "TokenLine.cpp"
|
||||
|
||||
// HLTV common
|
||||
include "BitBuffer.cpp"
|
||||
include "byteorder.cpp"
|
||||
include "common.cpp"
|
||||
include "DirectorCmd.cpp"
|
||||
include "mathlib.cpp"
|
||||
include "random.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
director_engine(CppSourceSet) {
|
||||
source {
|
||||
srcDir "../../engine"
|
||||
include "mem.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
director_pch(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "precompiled.cpp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binaries.all {
|
||||
NativeBinarySpec b -> project.setupToolchain(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task buildFixes {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
task buildRelease {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
// prevent static lib building
|
||||
binaries.withType(StaticLibraryBinarySpec) { binary ->
|
||||
buildable = false
|
||||
}
|
22
rehlds/HLTV/Director/msvc/Director.sln
Normal file
22
rehlds/HLTV/Director/msvc/Director.sln
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Director", "Director.vcxproj", "{04D0594C-57F5-4277-AF1B-EAE90AED0C3C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{04D0594C-57F5-4277-AF1B-EAE90AED0C3C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{04D0594C-57F5-4277-AF1B-EAE90AED0C3C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{04D0594C-57F5-4277-AF1B-EAE90AED0C3C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{04D0594C-57F5-4277-AF1B-EAE90AED0C3C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
157
rehlds/HLTV/Director/msvc/Director.vcxproj
Normal file
157
rehlds/HLTV/Director/msvc/Director.vcxproj
Normal file
@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" 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>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{04D0594C-57F5-4277-AF1B-EAE90AED0C3C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Director</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;DIRECTOR_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\..\;$(ProjectDir)\..\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;DIRECTOR_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\..\;$(ProjectDir)\..\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp" />
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp" />
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp" />
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp" />
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp" />
|
||||
<ClCompile Include="..\..\common\byteorder.cpp" />
|
||||
<ClCompile Include="..\..\common\common.cpp" />
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp" />
|
||||
<ClCompile Include="..\..\common\mathlib.cpp" />
|
||||
<ClCompile Include="..\..\common\random.cpp" />
|
||||
<ClCompile Include="..\src\Director.cpp" />
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
||||
<ClInclude Include="..\..\..\engine\mem.h" />
|
||||
<ClInclude Include="..\..\common\BitBuffer.h" />
|
||||
<ClInclude Include="..\..\common\byteorder.h" />
|
||||
<ClInclude Include="..\..\common\common_hltv.h" />
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h" />
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h" />
|
||||
<ClInclude Include="..\..\common\random.h" />
|
||||
<ClInclude Include="..\src\Director.h" />
|
||||
<ClInclude Include="..\src\DirectorNull.h" />
|
||||
<ClInclude Include="..\src\precompiled.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
108
rehlds/HLTV/Director/msvc/Director.vcxproj.filters
Normal file
108
rehlds/HLTV/Director/msvc/Director.vcxproj.filters
Normal file
@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{e86d9738-6b9c-4a2d-ba74-454526be3b1c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV">
|
||||
<UniqueIdentifier>{b2fdbdd6-d164-4470-97e9-b454d0dc7b0f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV\common">
|
||||
<UniqueIdentifier>{722c9b02-95dc-410f-a5b4-955878646049}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="engine">
|
||||
<UniqueIdentifier>{33779299-5f45-402f-a52f-888505614cbe}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{188c9b98-4976-4512-9313-8c3ffe3d0249}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\Director.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\random.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\byteorder.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\mathlib.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp">
|
||||
<Filter>engine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\Director.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\DirectorNull.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\precompiled.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\common_hltv.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\random.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BitBuffer.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\byteorder.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\engine\mem.h">
|
||||
<Filter>engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
39
rehlds/HLTV/Director/msvc/PostBuild.bat
Normal file
39
rehlds/HLTV/Director/msvc/PostBuild.bat
Normal file
@ -0,0 +1,39 @@
|
||||
@echo OFF
|
||||
::
|
||||
:: Post-build auto-deploy script
|
||||
:: Create and fill PublishPath.txt file with path to deployment folder
|
||||
:: I.e. PublishPath.txt should contain one line with a folder path
|
||||
:: Call it so:
|
||||
:: IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")
|
||||
::
|
||||
|
||||
SET targetDir=%~1
|
||||
SET targetName=%~2
|
||||
SET targetExt=%~3
|
||||
SET projectDir=%~4
|
||||
SET destination=
|
||||
|
||||
IF NOT EXIST "%projectDir%\PublishPath.txt" (
|
||||
ECHO No deployment path specified. Create PublishPath.txt near PostBuild.bat with paths on separate lines for auto deployment.
|
||||
exit /B 0
|
||||
)
|
||||
|
||||
FOR /f "tokens=* delims= usebackq" %%a IN ("%projectDir%\PublishPath.txt") DO (
|
||||
ECHO Deploying to: %%a
|
||||
IF NOT "%%a" == "" (
|
||||
copy /Y "%targetDir%%targetName%%targetExt%" "%%a"
|
||||
IF NOT ERRORLEVEL 1 (
|
||||
IF EXIST "%targetDir%%targetName%.pdb" (
|
||||
copy /Y "%targetDir%%targetName%.pdb" "%%a"
|
||||
)
|
||||
) ELSE (
|
||||
ECHO PostBuild.bat ^(27^) : warning : Can't copy '%targetName%%targetExt%' to deploy path '%%a'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
IF "%%a" == "" (
|
||||
ECHO No deployment path specified.
|
||||
)
|
||||
|
||||
exit /B 0
|
771
rehlds/HLTV/Director/src/Director.cpp
Normal file
771
rehlds/HLTV/Director/src/Director.cpp
Normal file
@ -0,0 +1,771 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#ifdef DIRECTOR_MODULE
|
||||
EXPOSE_SINGLE_INTERFACE(Director, IDirector, DIRECTOR_INTERFACE_VERSION);
|
||||
#endif // DIRECTOR_MODULE
|
||||
|
||||
bool Director::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseSystemModule::Init(system, serial, name);
|
||||
m_System->RegisterCommand("slowmotion", this, CMD_ID_SLOWMOTION);
|
||||
|
||||
m_historyLength = MAX_WORLD_HISTORY;
|
||||
m_history = (worldHistory_t *)malloc(sizeof(worldHistory_t) * m_historyLength);
|
||||
if (!m_history) {
|
||||
m_System->Printf("ERROR!Director::Init: not enough memory for world history.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_LastExecTime = 0;
|
||||
m_currentTime = 0;
|
||||
m_slowMotion = 0.5f;
|
||||
|
||||
for (int i = 0; i < MAX_WORLD_HISTORY; i++) {
|
||||
m_gaussFilter[i] = 1.0f / exp((i * i) / 10000.0f);
|
||||
}
|
||||
|
||||
m_World = nullptr;
|
||||
m_Active = false;
|
||||
m_System->ExecuteFile("director.cfg");
|
||||
m_System->Printf("Director module initialized.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
float WeightedAngle(vec_t *vec1, vec_t *vec2)
|
||||
{
|
||||
float a = AngleBetweenVectors(vec1, vec2);
|
||||
if (a < 11.25f) {
|
||||
return 1;
|
||||
}
|
||||
else if (a < 22.5f) {
|
||||
return 0.5f;
|
||||
}
|
||||
else if (a < 45.0f) {
|
||||
return 0.25f;
|
||||
}
|
||||
else if (a < 90.0f) {
|
||||
return 0.125f;
|
||||
}
|
||||
|
||||
return 0.05f;
|
||||
}
|
||||
|
||||
void Director::WriteProxyStatus(BitBuffer *stream)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void Director::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_history) {
|
||||
free(m_history);
|
||||
}
|
||||
|
||||
if (m_World) {
|
||||
m_World->RemoveListener(this);
|
||||
}
|
||||
|
||||
ClearDirectorCommands();
|
||||
BaseSystemModule::ShutDown();
|
||||
|
||||
m_System->Printf("Director module shutdown.\n");
|
||||
}
|
||||
|
||||
void Director::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
if (!m_World || !m_World->IsActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_nextCutTime && m_Active)
|
||||
{
|
||||
ExecuteDirectorCommands();
|
||||
if ((m_currentTime - m_nextCutTime) > 10)
|
||||
{
|
||||
float duration = AddBestMODCut();
|
||||
if (!duration) {
|
||||
duration = AddBestGenericCut();
|
||||
}
|
||||
|
||||
m_nextCutTime += duration;
|
||||
|
||||
while (m_nextCutTime > m_history[m_nextCutSeqnr % m_historyLength].time) {
|
||||
m_nextCutSeqnr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Director::ReceiveSignal(ISystemModule *module, unsigned int signal, void *data)
|
||||
{
|
||||
int from = module->GetSerial();
|
||||
if (m_World->GetSerial() != from) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (signal != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_World) {
|
||||
m_System->Printf("Director::ReceiveSignal: world == NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
frame_t frame;
|
||||
m_World->GetUncompressedFrame(m_World->GetLastFrame()->seqnr, &frame);
|
||||
AnalyseFrame(&frame);
|
||||
}
|
||||
|
||||
char *Director::GetModName()
|
||||
{
|
||||
return "valve";
|
||||
}
|
||||
|
||||
void Director::NewGame(IWorld *world, IProxy *proxy)
|
||||
{
|
||||
m_World = world;
|
||||
m_Proxy = proxy;
|
||||
|
||||
world->RegisterListener(this);
|
||||
m_WorldModel = m_World->GetWorldModel();
|
||||
|
||||
memset(m_history, 0, sizeof(*m_history) * m_historyLength);
|
||||
memset(&m_frameEvent, 0, sizeof(m_frameEvent));
|
||||
|
||||
ClearDirectorCommands();
|
||||
|
||||
m_lastCut = nullptr;
|
||||
m_LastExecTime = 0;
|
||||
m_nextCutTime = 0;
|
||||
m_currentTime = 0;
|
||||
m_nextCutSeqnr = 0;
|
||||
m_maxRank = 0;
|
||||
|
||||
WriteSignonData();
|
||||
m_Active = true;
|
||||
}
|
||||
|
||||
void Director::AnalyseFrame(frame_t *frame)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int num;
|
||||
float ranks[MAX_CLIENTS];
|
||||
unsigned int maxclients = m_World->GetMaxClients();
|
||||
unsigned int seqnr = frame->seqnr;
|
||||
worldHistory_t *now = &m_history[seqnr % m_historyLength];
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
ranks[i] = now->players[i].rank;
|
||||
}
|
||||
|
||||
memset(now, 0, sizeof(*now));
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
now->players[i].rank = ranks[i];
|
||||
}
|
||||
|
||||
if (frame->delta || !m_Active) {
|
||||
m_System->DPrintf("Director::AnalyseFrame: frame must be uncompressed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_currentTime)
|
||||
{
|
||||
m_nextCutTime = frame->time;
|
||||
m_nextCutSeqnr = seqnr;
|
||||
}
|
||||
|
||||
m_currentSeqnr = seqnr;
|
||||
now->seqNr = seqnr;
|
||||
|
||||
m_currentTime = frame->time;
|
||||
now->time = frame->time;
|
||||
|
||||
unsigned int count = min(maxclients, frame->entitynum);
|
||||
for (num = 0; num < count; num++)
|
||||
{
|
||||
entity_state_t *ent = &((entity_state_t *)frame->entities)[num];
|
||||
unsigned int index = ent->number - 1;
|
||||
if (index >= maxclients) {
|
||||
continue;
|
||||
}
|
||||
|
||||
playerData_t *player = &now->players[i];
|
||||
player->active = (ent->solid != SOLID_NOT);
|
||||
if (player->active)
|
||||
{
|
||||
player->origin[0] = ent->origin[0];
|
||||
player->origin[1] = ent->origin[1];
|
||||
player->origin[2] = ent->origin[2];
|
||||
|
||||
vec3_t angles;
|
||||
AngleVectors(ent->angles, angles);
|
||||
VectorCopy(angles, player->angles);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
AnalysePlayer(i);
|
||||
}
|
||||
|
||||
now->event.entity1 = m_frameEvent.entity1;
|
||||
now->event.entity2 = m_frameEvent.entity2;
|
||||
now->event.flags = m_frameEvent.flags;
|
||||
|
||||
memset(&m_frameEvent, 0, sizeof(m_frameEvent));
|
||||
}
|
||||
|
||||
void Director::SmoothRank(int playerNum, float rank)
|
||||
{
|
||||
const unsigned int smoothRange = 40;
|
||||
m_history[(m_currentSeqnr + smoothRange) % m_historyLength].players[playerNum].rank = 0;
|
||||
|
||||
unsigned int steps;
|
||||
for (unsigned int i = 0; i < smoothRange; i++)
|
||||
{
|
||||
float addition = rank * m_gaussFilter[i * (MAX_WORLD_HISTORY / smoothRange)];
|
||||
|
||||
steps = (m_currentSeqnr - i) % m_historyLength;
|
||||
m_history[steps].players[playerNum].rank += addition;
|
||||
|
||||
steps = (i + m_currentSeqnr) % m_historyLength;
|
||||
m_history[steps].players[playerNum].rank += addition;
|
||||
}
|
||||
}
|
||||
|
||||
void Director::AnalysePlayer(int playerNum)
|
||||
{
|
||||
int secondTarget = 0;
|
||||
float rank = RandomFloat(0.0f, 0.01f) + 1;
|
||||
float targetRank, bestTargetRank = 0;
|
||||
|
||||
worldHistory_t *now = &m_history[m_currentSeqnr % m_historyLength];
|
||||
playerData_t *player = &now->players[playerNum];
|
||||
|
||||
if (player->active)
|
||||
{
|
||||
if (m_WorldModel->IsValid())
|
||||
{
|
||||
m_WorldModel->SetPVS(player->origin);
|
||||
for (int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
playerData_t *target = &now->players[i];
|
||||
if (!target->active || !m_WorldModel->InPVS(target->origin)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vec3_t offset;
|
||||
VectorSubtract(target->origin, player->origin, offset);
|
||||
|
||||
float distance = Length(offset);
|
||||
if (distance >= 1.0f)
|
||||
{
|
||||
targetRank = WeightedAngle(target->angles, offset) + 1 / distance;
|
||||
|
||||
// inverted
|
||||
VectorScale(offset, -1.0f, offset);
|
||||
|
||||
targetRank = WeightedAngle(target->angles, offset) * targetRank;
|
||||
rank += targetRank;
|
||||
|
||||
// remember closest player
|
||||
if (targetRank > bestTargetRank)
|
||||
{
|
||||
bestTargetRank = targetRank;
|
||||
secondTarget = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rank = 0;
|
||||
}
|
||||
|
||||
player->target = secondTarget;
|
||||
player->rank = player->rank + rank;
|
||||
SmoothRank(playerNum, rank);
|
||||
}
|
||||
|
||||
void Director::WriteCommands(BitBuffer *stream, float startTime, float endTime)
|
||||
{
|
||||
DirectorCmd *cmd = (DirectorCmd *)m_Commands.FindClosestKey(startTime);
|
||||
while (cmd && cmd->GetTime() <= endTime)
|
||||
{
|
||||
if (cmd->GetTime() > startTime)
|
||||
{
|
||||
if (cmd->GetType() == DRC_CMD_TIMESCALE)
|
||||
{
|
||||
float timescale;
|
||||
cmd->GetTimeScaleData(timescale);
|
||||
|
||||
stream->WriteByte(svc_timescale);
|
||||
stream->WriteFloat(timescale);
|
||||
}
|
||||
|
||||
cmd->WriteToStream(stream);
|
||||
}
|
||||
|
||||
cmd = (DirectorCmd *)m_Commands.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void Director::WriteSignonData()
|
||||
{
|
||||
static unsigned char cmd[] = {
|
||||
1, // command length in bytes
|
||||
DRC_CMD_START // tell them for start director
|
||||
};
|
||||
|
||||
m_World->AddSignonData(svc_director, cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
void Director::AddEvent(int entity1, int entity2, unsigned int flags)
|
||||
{
|
||||
if ((flags & DRC_FLAG_PRIO_MASK) > (m_frameEvent.flags & DRC_FLAG_PRIO_MASK))
|
||||
{
|
||||
m_frameEvent.flags = flags;
|
||||
m_frameEvent.entity1 = entity1;
|
||||
m_frameEvent.entity2 = entity2;
|
||||
}
|
||||
}
|
||||
|
||||
float Director::AddBestGenericCut()
|
||||
{
|
||||
int seqNrMod = m_nextCutSeqnr % m_historyLength;
|
||||
|
||||
float sumTarget2Rank[MAX_CLIENTS];
|
||||
float bestTarget2Rank, bestRank = 0;
|
||||
float targetRankSum = 0;
|
||||
int newTarget, newTarget2;
|
||||
int bestTarget2;
|
||||
|
||||
for (int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
memset(sumTarget2Rank, 0, sizeof(sumTarget2Rank));
|
||||
|
||||
float tillTime = m_nextCutTime + 4;
|
||||
while (tillTime > m_history[seqNrMod].time)
|
||||
{
|
||||
playerData_t *player = &m_history[seqNrMod].players[i];
|
||||
|
||||
targetRankSum += player->rank;
|
||||
if (player->target) {
|
||||
sumTarget2Rank[player->target - 1] += player->rank;
|
||||
}
|
||||
|
||||
if (++seqNrMod == m_historyLength) {
|
||||
seqNrMod = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bestTarget2 = 0;
|
||||
bestTarget2Rank = 0;
|
||||
|
||||
for (int j = 0; j < MAX_CLIENTS; j++)
|
||||
{
|
||||
if (sumTarget2Rank[j] > bestTarget2Rank)
|
||||
{
|
||||
bestTarget2 = j + 1;
|
||||
bestTarget2Rank = sumTarget2Rank[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (targetRankSum > bestRank)
|
||||
{
|
||||
bestRank = targetRankSum;
|
||||
newTarget = i + 1;
|
||||
newTarget2 = bestTarget2;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestRank > m_maxRank) {
|
||||
m_maxRank = bestRank;
|
||||
}
|
||||
|
||||
float duration = 1.0f;
|
||||
if (newTarget > 0)
|
||||
{
|
||||
if (m_lastCut && m_lastCut->GetType() == TYPE_DIRECTOR)
|
||||
{
|
||||
int lastTarget1, lastTarget2,flags;
|
||||
m_lastCut->GetEventData(lastTarget1, lastTarget2, flags);
|
||||
|
||||
if (newTarget == lastTarget1 && newTarget2 == lastTarget2) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if (newTarget == lastTarget1) {
|
||||
duration = 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
DirectorCmd *cmd = new DirectorCmd;
|
||||
cmd->SetEventData(newTarget, newTarget2, 0);
|
||||
cmd->SetTime(m_nextCutTime);
|
||||
|
||||
RandomizeCommand(cmd);
|
||||
m_Commands.Add(cmd, m_nextCutTime);
|
||||
m_lastCut = cmd;
|
||||
}
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
float Director::AddBestMODCut()
|
||||
{
|
||||
worldHistory_t *timepoint = FindBestEvent();
|
||||
if (!timepoint) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DirectorCmd *cmd = new DirectorCmd;
|
||||
cmd->SetEventData(timepoint->event.entity1, timepoint->event.entity2, timepoint->event.flags);
|
||||
cmd->SetTime(m_nextCutTime);
|
||||
|
||||
RandomizeCommand(cmd);
|
||||
m_Commands.Add(cmd, cmd->GetTime());
|
||||
m_lastCut = cmd;
|
||||
|
||||
int lastTarget1, lastTarget2, lastFlags;
|
||||
cmd->GetEventData(lastTarget1, lastTarget2, lastFlags);
|
||||
|
||||
float trailTime = 2.0f;
|
||||
if ((lastFlags & DRC_FLAG_SLOWMOTION) && m_slowMotion)
|
||||
{
|
||||
trailTime = 1.5f;
|
||||
|
||||
cmd = new DirectorCmd;
|
||||
cmd->SetTimeScaleData(m_slowMotion);
|
||||
cmd->SetTime(timepoint->time - 0.25f);
|
||||
m_Commands.Add(cmd, cmd->GetTime());
|
||||
|
||||
cmd = new DirectorCmd;
|
||||
cmd->SetTimeScaleData(1.0);
|
||||
cmd->SetTime(timepoint->time + 1.5f);
|
||||
m_Commands.Add(cmd, cmd->GetTime());
|
||||
}
|
||||
|
||||
return trailTime + timepoint->time - m_nextCutTime;
|
||||
}
|
||||
|
||||
int Director::GetClosestPlayer(frame_t *frame, int entityIndex)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int bestPlayer = 0;
|
||||
unsigned int maxclients = m_World->GetMaxClients();
|
||||
|
||||
if (!m_WorldModel->IsValid()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec3_t origin;
|
||||
for (i = 0; i < frame->entitynum; i++)
|
||||
{
|
||||
entity_state_t *ent = &((entity_state_t *)frame->entities)[i];
|
||||
if (ent->number == entityIndex) {
|
||||
VectorCopy(origin, ent->origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// entityIndex not found
|
||||
if (i == frame->entitynum) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_WorldModel->SetPVS(origin);
|
||||
|
||||
float minDistance = 32000.0f;
|
||||
unsigned int count = min(maxclients, frame->entitynum);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
entity_state_t *ent = &((entity_state_t *)frame->entities)[i];
|
||||
if ((unsigned)(ent->number - 1) < maxclients && m_WorldModel->InPVS(ent->origin))
|
||||
{
|
||||
vec3_t offset;
|
||||
VectorSubtract(ent->origin, origin, offset);
|
||||
|
||||
float distance = Length(offset);
|
||||
if (distance >= 1 && distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
bestPlayer = ent->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestPlayer;
|
||||
}
|
||||
|
||||
void Director::ClearDirectorCommands()
|
||||
{
|
||||
DirectorCmd *cmd = (DirectorCmd *)m_Commands.GetFirst();
|
||||
while (cmd)
|
||||
{
|
||||
delete cmd;
|
||||
cmd = (DirectorCmd *)m_Commands.GetNext();
|
||||
}
|
||||
|
||||
m_Commands.Clear();
|
||||
}
|
||||
|
||||
void Director::RandomizeCommand(DirectorCmd *cmd)
|
||||
{
|
||||
if ((cmd->GetType() & DRC_FLAG_NO_RANDOM) || cmd->GetType() != DRC_CMD_EVENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
int target1, target2, flags;
|
||||
cmd->GetEventData(target1, target2, flags);
|
||||
if ((flags & DRC_FLAG_SLOWMOTION) && RandomFloat(0, 1) > 0.25f)
|
||||
{
|
||||
flags &= ~DRC_FLAG_SLOWMOTION;
|
||||
}
|
||||
// check DRC_CMD_SOUND, DRC_CMD_STATUS, DRC_CMD_BANNER
|
||||
else if ((flags & DRC_FLAG_PRIO_MASK) > DRC_CMD_MESSAGE
|
||||
&& (flags & DRC_FLAG_PRIO_MASK) < DRC_CMD_STUFFTEXT && RandomFloat(0, 1) < 0.15f)
|
||||
{
|
||||
flags |= DRC_FLAG_SLOWMOTION;
|
||||
}
|
||||
|
||||
// toggle flag DRC_FLAG_DRAMATIC
|
||||
if (RandomFloat(0, 1) < 0.33f) {
|
||||
flags ^= DRC_FLAG_DRAMATIC;
|
||||
}
|
||||
|
||||
if (target1 && target2 && !(flags & DRC_FLAG_SLOWMOTION) && RandomFloat(0, 1) < 0.33f)
|
||||
{
|
||||
int swap = target1;
|
||||
target1 = target2;
|
||||
target2 = swap;
|
||||
}
|
||||
|
||||
worldHistory_t *now = &m_history[m_nextCutSeqnr % m_historyLength];
|
||||
|
||||
vec3_t v1, v2;
|
||||
VectorSubtract(now->players[target2 % MAX_CLIENTS].origin, now->players[target1 % MAX_CLIENTS].origin, v1);
|
||||
|
||||
v1[2] = 0;
|
||||
VectorAngles(v1, v1);
|
||||
|
||||
VectorCopy(now->players[target1 % MAX_CLIENTS].angles, v2);
|
||||
if (AngleLeftOfOther(v1, v2))
|
||||
flags &= ~DRC_FLAG_SIDE;
|
||||
else
|
||||
flags |= DRC_FLAG_SIDE;
|
||||
|
||||
if (target1 == target2) {
|
||||
target2 = 0;
|
||||
}
|
||||
|
||||
cmd->SetEventData(target1, target2, flags);
|
||||
}
|
||||
|
||||
void Director::ExecuteCommand(int commandID, char *commandLine)
|
||||
{
|
||||
if (commandID == CMD_ID_SLOWMOTION) {
|
||||
CMD_SlowMotion(commandLine);
|
||||
return;
|
||||
}
|
||||
|
||||
m_System->Printf("ERROR! Director::ExecuteCommand: unknown command ID %i.\n", commandID);
|
||||
}
|
||||
|
||||
char *Director::GetStatusLine()
|
||||
{
|
||||
return "Default Director";
|
||||
}
|
||||
|
||||
char *Director::GetType()
|
||||
{
|
||||
return DIRECTOR_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
void Director::ExecuteDirectorCommands()
|
||||
{
|
||||
unsigned char bufferdata[4096];
|
||||
BitBuffer buffer(bufferdata, sizeof(bufferdata));
|
||||
buffer.Clear();
|
||||
|
||||
float newTime = (float)m_Proxy->GetSpectatorTime();
|
||||
DirectorCmd *cmd = (DirectorCmd *)m_Commands.FindClosestKey(m_LastExecTime);
|
||||
if (!cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (cmd && cmd->GetTime() <= newTime)
|
||||
{
|
||||
if (cmd->GetTime() > m_LastExecTime)
|
||||
{
|
||||
if (cmd->GetType() == DRC_CMD_TIMESCALE)
|
||||
{
|
||||
float timescale;
|
||||
cmd->GetTimeScaleData(timescale);
|
||||
m_Proxy->SetClientTimeScale(timescale);
|
||||
|
||||
if (timescale < 1.0)
|
||||
{
|
||||
vec3_t pos = { 0.02f, 0.85f, 0.f };
|
||||
|
||||
DirectorCmd slowmo;
|
||||
slowmo.SetMessageData(0, COM_PackRGBA(255, 160, 0, 255), pos, 0.3f, 0.1f, 2, 0, "Slow Motion");
|
||||
slowmo.WriteToStream(&buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->WriteToStream(&buffer);
|
||||
}
|
||||
}
|
||||
|
||||
cmd = (DirectorCmd *)m_Commands.GetNext();
|
||||
}
|
||||
|
||||
if (buffer.IsOverflowed())
|
||||
{
|
||||
m_System->Printf("Director::ExecuteDirectorCommands: command overflow.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Proxy->Broadcast(buffer.GetData(), buffer.CurrentSize(), GROUP_CLIENT_ALL, true);
|
||||
}
|
||||
|
||||
m_LastExecTime = newTime;
|
||||
}
|
||||
|
||||
void Director::CMD_SlowMotion(char *cmdLine)
|
||||
{
|
||||
TokenLine params(cmdLine);
|
||||
if (params.CountToken() != 2) {
|
||||
m_System->Printf("Syntax: slowmotion <factor>\n");
|
||||
m_System->Printf("Currently slowmotion factor is %.2f\n", m_slowMotion);
|
||||
return;
|
||||
}
|
||||
|
||||
float val = (float)atof(params.GetToken(1));
|
||||
m_slowMotion = clamp(val, 0.05f, 4.0f);
|
||||
}
|
||||
|
||||
Director::worldHistory_t *Director::FindBestEvent()
|
||||
{
|
||||
int i;
|
||||
int nseqMod = m_nextCutSeqnr % m_historyLength;
|
||||
int bestEvent[] = { 0, 0, 0, 0 };
|
||||
int bestEventPrio[] = { 0, 0, 0, 0 };
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
bestEventPrio[i] = 0;
|
||||
bestEvent[i] = 0;
|
||||
|
||||
float tillTime = (i + 1) * 2 + m_nextCutTime;
|
||||
while (tillTime > m_history[nseqMod].time)
|
||||
{
|
||||
if ((m_history[nseqMod].event.flags & DRC_FLAG_PRIO_MASK) > (unsigned int)bestEventPrio[i]) {
|
||||
bestEventPrio[i] = (m_history[nseqMod].event.flags & DRC_FLAG_PRIO_MASK);
|
||||
bestEvent[i] = nseqMod;
|
||||
}
|
||||
|
||||
if (++nseqMod == m_historyLength) {
|
||||
nseqMod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestEventPrio[0] || bestEventPrio[1] || bestEventPrio[2])
|
||||
{
|
||||
if (bestEventPrio[1] >= bestEventPrio[0]
|
||||
&& bestEventPrio[1] >= bestEventPrio[2]
|
||||
&& bestEventPrio[1] >= bestEventPrio[3]) {
|
||||
return &m_history[ bestEvent[1] ];
|
||||
}
|
||||
|
||||
else if (bestEventPrio[0] > bestEventPrio[1]
|
||||
&& bestEventPrio[0] > bestEventPrio[2]) {
|
||||
return &m_history[ bestEvent[0] ];
|
||||
}
|
||||
|
||||
else if (bestEventPrio[2] > bestEventPrio[3]) {
|
||||
return &m_history[ bestEvent[2] ];
|
||||
}
|
||||
|
||||
if (bestEventPrio[0]) {
|
||||
return &m_history[ bestEvent[0] ];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Director::AddCommand(DirectorCmd *cmd)
|
||||
{
|
||||
if (cmd->GetType() > DRC_CMD_LAST) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd->GetType() == DRC_CMD_EVENT)
|
||||
{
|
||||
int target1, target2, flags;
|
||||
cmd->GetEventData(target1, target2, flags);
|
||||
AddEvent(target1, target2, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DirectorCmd *newcmd = new DirectorCmd;
|
||||
newcmd->Copy(cmd);
|
||||
|
||||
m_Commands.Add(newcmd, newcmd->GetTime());
|
||||
return 1;
|
||||
}
|
||||
|
||||
IObjectContainer *Director::GetCommands()
|
||||
{
|
||||
return &m_Commands;
|
||||
}
|
||||
|
||||
bool Director::RemoveCommand(int index)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DirectorCmd *Director::GetLastCommand()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
126
rehlds/HLTV/Director/src/Director.h
Normal file
126
rehlds/HLTV/Director/src/Director.h
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IProxy.h>
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <HLTV/IDirector.h>
|
||||
|
||||
#include "BaseSystemModule.h"
|
||||
#include "ObjectDictionary.h"
|
||||
|
||||
class Director: public IDirector, public BaseSystemModule {
|
||||
public:
|
||||
Director() {}
|
||||
virtual ~Director() {}
|
||||
|
||||
virtual bool Init(IBaseSystem *system, int serial, char *name);
|
||||
virtual void RunFrame(double time);
|
||||
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
virtual void ExecuteCommand(int commandID, char *commandLine);
|
||||
virtual char *GetStatusLine();
|
||||
virtual char *GetType();
|
||||
virtual void ShutDown();
|
||||
|
||||
virtual void NewGame(IWorld *world, IProxy *proxy);
|
||||
virtual int AddCommand(DirectorCmd *cmd);
|
||||
virtual void WriteCommands(BitBuffer *stream, float startTime, float endTime);
|
||||
virtual char *GetModName();
|
||||
virtual bool RemoveCommand(int index);
|
||||
virtual DirectorCmd *GetLastCommand();
|
||||
virtual IObjectContainer *GetCommands();
|
||||
|
||||
typedef struct playerData_s {
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
int active;
|
||||
int target;
|
||||
float rank;
|
||||
} playerData_t;
|
||||
|
||||
typedef struct worldHistory_s
|
||||
{
|
||||
float time;
|
||||
unsigned int seqNr;
|
||||
|
||||
typedef struct worldEvent_s {
|
||||
int entity1;
|
||||
int entity2;
|
||||
unsigned int flags;
|
||||
} worldEvent_t;
|
||||
|
||||
worldEvent_t event;
|
||||
playerData_t players[MAX_CLIENTS];
|
||||
|
||||
} worldHistory_t;
|
||||
|
||||
worldHistory_t *FindBestEvent();
|
||||
|
||||
void ExecuteDirectorCommands();
|
||||
void RandomizeCommand(DirectorCmd *cmd);
|
||||
int GetClosestPlayer(frame_t *frame, int entityIndex);
|
||||
void AddEvent(int entity1, int entity2, unsigned int flags);
|
||||
void SmoothRank(int playerNum, float rank);
|
||||
void AnalysePlayer(int playerNum);
|
||||
void AnalyseFrame(frame_t *frame);
|
||||
void ClearDirectorCommands();
|
||||
float AddBestMODCut();
|
||||
float AddBestGenericCut();
|
||||
void WriteSignonData();
|
||||
void WriteProxyStatus(BitBuffer *stream);
|
||||
|
||||
private:
|
||||
enum LocalCommandIDs { CMD_ID_SLOWMOTION = 1 };
|
||||
void CMD_SlowMotion(char *cmdLine);
|
||||
|
||||
protected:
|
||||
ObjectDictionary m_Commands;
|
||||
|
||||
worldHistory_t *m_history;
|
||||
float m_maxRank;
|
||||
|
||||
enum { MAX_WORLD_HISTORY = 200 };
|
||||
float m_gaussFilter[MAX_WORLD_HISTORY];
|
||||
|
||||
int m_historyLength;
|
||||
unsigned int m_nextCutSeqnr;
|
||||
unsigned int m_currentSeqnr;
|
||||
|
||||
float m_nextCutTime;
|
||||
float m_currentTime;
|
||||
float m_LastExecTime;
|
||||
float m_slowMotion;
|
||||
|
||||
worldHistory_t::worldEvent_t m_frameEvent;
|
||||
DirectorCmd *m_lastCut;
|
||||
IBSPModel *m_WorldModel;
|
||||
bool m_Active;
|
||||
IWorld *m_World;
|
||||
IProxy *m_Proxy;
|
||||
};
|
57
rehlds/HLTV/Director/src/DirectorNull.h
Normal file
57
rehlds/HLTV/Director/src/DirectorNull.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <HLTV/IDirector.h>
|
||||
#include "BaseSystemModule.h"
|
||||
|
||||
class IObjectContainer;
|
||||
class DirectorNull: public IDirector, public BaseSystemModule {
|
||||
public:
|
||||
void NewGame(IWorld *world, IProxy *proxy)
|
||||
{
|
||||
static unsigned char cmd[] = {
|
||||
1, // command length in bytes
|
||||
DRC_CMD_START // tell them for start director
|
||||
};
|
||||
|
||||
world->AddSignonData(svc_director, cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
int AddCommand(DirectorCmd *cmd) { return 0; }
|
||||
void WriteCommands(BitBuffer *stream, float startTime, float endTime) {}
|
||||
char *GetModName() { return "NULL"; }
|
||||
bool RemoveCommand(int index) { return false; }
|
||||
|
||||
DirectorCmd *GetLastCommand() { return nullptr; }
|
||||
IObjectContainer *GetCommands() { return nullptr; }
|
||||
|
||||
virtual ~DirectorNull() {}
|
||||
};
|
1
rehlds/HLTV/Director/src/precompiled.cpp
Normal file
1
rehlds/HLTV/Director/src/precompiled.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "precompiled.h"
|
24
rehlds/HLTV/Director/src/precompiled.h
Normal file
24
rehlds/HLTV/Director/src/precompiled.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "osconfig.h"
|
||||
#include "archtypes.h"
|
||||
#include "mathlib.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include "TokenLine.h"
|
||||
#include "interface.h"
|
||||
|
||||
#include "hltv.h"
|
||||
#include "mem.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "common/random.h"
|
||||
#include "common/byteorder.h"
|
||||
#include "common/BitBuffer.h"
|
||||
#include "common/DirectorCmd.h"
|
||||
#include "common/mathlib_internal.h"
|
||||
#include "common/net_internal.h"
|
||||
#include "common/common_hltv.h"
|
||||
|
||||
#include "Director.h"
|
||||
#include "DirectorNull.h"
|
3
rehlds/HLTV/Director/src/public_amalgamation.cpp
Normal file
3
rehlds/HLTV/Director/src/public_amalgamation.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "interface.cpp"
|
165
rehlds/HLTV/Proxy/build.gradle
Normal file
165
rehlds/HLTV/Proxy/build.gradle
Normal file
@ -0,0 +1,165 @@
|
||||
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
|
||||
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
|
||||
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
|
||||
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
|
||||
import org.gradle.nativeplatform.NativeBinarySpec
|
||||
import org.gradle.nativeplatform.NativeLibrarySpec
|
||||
import org.gradle.nativeplatform.toolchain.VisualCpp
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: IccCompilerPlugin
|
||||
apply plugin: GccCompilerPlugin
|
||||
|
||||
project.ext.dep_bzip2 = project(':dep/bzip2')
|
||||
|
||||
void setupToolchain(NativeBinarySpec b) {
|
||||
def cfg = rootProject.createToolchainConfig(b);
|
||||
cfg.projectInclude(project, '/..', '/../..', '/src', '/../Director/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared');
|
||||
cfg.projectInclude(dep_bzip2, '/include')
|
||||
|
||||
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'CORE_MODULE'
|
||||
|
||||
if (cfg instanceof MsvcToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
|
||||
enabled: true,
|
||||
pchHeader: 'precompiled.h',
|
||||
pchSourceSet: 'proxy_pch'
|
||||
);
|
||||
|
||||
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
||||
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF'
|
||||
cfg.projectLibpath(project, '/../../lib')
|
||||
cfg.extraLibs "steam_api.lib", "psapi.lib", "ws2_32.lib"
|
||||
}
|
||||
else if (cfg instanceof GccToolchainConfig) {
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'proxy_pch'
|
||||
);
|
||||
|
||||
cfg.compilerOptions.languageStandard = 'c++0x'
|
||||
cfg.defines([
|
||||
'_strdup': 'strdup',
|
||||
'_stricmp': 'strcasecmp',
|
||||
'_strnicmp': 'strncasecmp',
|
||||
'_vsnprintf': 'vsnprintf',
|
||||
'_snprintf': 'snprintf',
|
||||
]);
|
||||
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-fno-exceptions'
|
||||
cfg.projectLibpath(project, '/../../lib/linux32')
|
||||
cfg.extraLibs "steam_api"
|
||||
}
|
||||
|
||||
ToolchainConfigUtils.apply(project, cfg, b);
|
||||
}
|
||||
|
||||
model {
|
||||
buildTypes {
|
||||
release
|
||||
}
|
||||
|
||||
platforms {
|
||||
x86 {
|
||||
architecture "x86"
|
||||
}
|
||||
}
|
||||
|
||||
toolChains {
|
||||
visualCpp(VisualCpp) {
|
||||
}
|
||||
icc(Icc) {
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
proxy(NativeLibrarySpec) {
|
||||
targetPlatform 'x86'
|
||||
baseName 'proxy'
|
||||
|
||||
sources {
|
||||
proxy_main(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "**/*.cpp"
|
||||
exclude "precompiled.cpp"
|
||||
}
|
||||
|
||||
lib project: ':dep/bzip2', library: 'bzip2', linkage: 'static'
|
||||
}
|
||||
|
||||
proxy_common(CppSourceSet) {
|
||||
source {
|
||||
srcDirs "../../common", "../common"
|
||||
|
||||
// common
|
||||
include "BaseSystemModule.cpp"
|
||||
include "ObjectDictionary.cpp"
|
||||
include "ObjectList.cpp"
|
||||
include "TokenLine.cpp"
|
||||
|
||||
// HLTV common
|
||||
include "BaseClient.cpp"
|
||||
include "BitBuffer.cpp"
|
||||
include "byteorder.cpp"
|
||||
include "common.cpp"
|
||||
include "DemoFile.cpp"
|
||||
include "DirectorCmd.cpp"
|
||||
include "InfoString.cpp"
|
||||
include "mathlib.cpp"
|
||||
include "md5.cpp"
|
||||
include "munge.cpp"
|
||||
include "NetAddress.cpp"
|
||||
include "NetChannel.cpp"
|
||||
include "random.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
proxy_engine(CppSourceSet) {
|
||||
source {
|
||||
srcDir "../../engine"
|
||||
include "mem.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
proxy_director(CppSourceSet) {
|
||||
source {
|
||||
srcDir "../Director/src"
|
||||
include "Director.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
proxy_pch(CppSourceSet) {
|
||||
source {
|
||||
srcDir "src"
|
||||
include "precompiled.cpp"
|
||||
|
||||
lib project: ':dep/bzip2', library: 'bzip2', linkage: 'static'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binaries.all {
|
||||
NativeBinarySpec b -> project.setupToolchain(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task buildFixes {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
task buildRelease {
|
||||
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
|
||||
blib.buildable && blib.buildType.name == 'release'
|
||||
}
|
||||
}
|
||||
|
||||
// prevent static lib building
|
||||
binaries.withType(StaticLibraryBinarySpec) { binary ->
|
||||
buildable = false
|
||||
}
|
39
rehlds/HLTV/Proxy/msvc/PostBuild.bat
Normal file
39
rehlds/HLTV/Proxy/msvc/PostBuild.bat
Normal file
@ -0,0 +1,39 @@
|
||||
@echo OFF
|
||||
::
|
||||
:: Post-build auto-deploy script
|
||||
:: Create and fill PublishPath.txt file with path to deployment folder
|
||||
:: I.e. PublishPath.txt should contain one line with a folder path
|
||||
:: Call it so:
|
||||
:: IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")
|
||||
::
|
||||
|
||||
SET targetDir=%~1
|
||||
SET targetName=%~2
|
||||
SET targetExt=%~3
|
||||
SET projectDir=%~4
|
||||
SET destination=
|
||||
|
||||
IF NOT EXIST "%projectDir%\PublishPath.txt" (
|
||||
ECHO No deployment path specified. Create PublishPath.txt near PostBuild.bat with paths on separate lines for auto deployment.
|
||||
exit /B 0
|
||||
)
|
||||
|
||||
FOR /f "tokens=* delims= usebackq" %%a IN ("%projectDir%\PublishPath.txt") DO (
|
||||
ECHO Deploying to: %%a
|
||||
IF NOT "%%a" == "" (
|
||||
copy /Y "%targetDir%%targetName%%targetExt%" "%%a"
|
||||
IF NOT ERRORLEVEL 1 (
|
||||
IF EXIST "%targetDir%%targetName%.pdb" (
|
||||
copy /Y "%targetDir%%targetName%.pdb" "%%a"
|
||||
)
|
||||
) ELSE (
|
||||
ECHO PostBuild.bat ^(27^) : warning : Can't copy '%targetName%%targetExt%' to deploy path '%%a'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
IF "%%a" == "" (
|
||||
ECHO No deployment path specified.
|
||||
)
|
||||
|
||||
exit /B 0
|
28
rehlds/HLTV/Proxy/msvc/Proxy.sln
Normal file
28
rehlds/HLTV/Proxy/msvc/Proxy.sln
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proxy", "Proxy.vcxproj", "{ADDFF069-D39D-4A1B-87C9-85A62B980547}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "..\..\..\..\dep\bzip2\msvc\bzip2.vcxproj", "{792DF067-9904-4579-99B9-46C17277ADE3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{ADDFF069-D39D-4A1B-87C9-85A62B980547}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{ADDFF069-D39D-4A1B-87C9-85A62B980547}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{ADDFF069-D39D-4A1B-87C9-85A62B980547}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{ADDFF069-D39D-4A1B-87C9-85A62B980547}.Release|Win32.Build.0 = Release|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{792DF067-9904-4579-99B9-46C17277ADE3}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
377
rehlds/HLTV/Proxy/msvc/Proxy.vcxproj
Normal file
377
rehlds/HLTV/Proxy/msvc/Proxy.vcxproj
Normal file
@ -0,0 +1,377 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" 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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp" />
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Proxy\hooklist.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Proxy\main.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BaseClient.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\byteorder.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DemoFile.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\InfoString.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\mathlib.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\md5.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\munge.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\NetAddress.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\NetChannel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\random.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Director\src\Director.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\DemoClient.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\FakeClient.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Master.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Proxy.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\ProxyClient.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Status.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h" />
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h" />
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h" />
|
||||
<ClInclude Include="..\..\..\engine\mem.h" />
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\Proxy\hooklist.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BaseClient.h" />
|
||||
<ClInclude Include="..\..\common\BitBuffer.h" />
|
||||
<ClInclude Include="..\..\common\byteorder.h" />
|
||||
<ClInclude Include="..\..\common\common_hltv.h" />
|
||||
<ClInclude Include="..\..\common\DemoFile.h" />
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h" />
|
||||
<ClInclude Include="..\..\common\InfoString.h" />
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h" />
|
||||
<ClInclude Include="..\..\common\md5.h" />
|
||||
<ClInclude Include="..\..\common\munge.h" />
|
||||
<ClInclude Include="..\..\common\NetChannel.h" />
|
||||
<ClInclude Include="..\..\common\NetAddress.h" />
|
||||
<ClInclude Include="..\..\common\net_internal.h" />
|
||||
<ClInclude Include="..\..\common\random.h" />
|
||||
<ClInclude Include="..\src\DemoClient.h" />
|
||||
<ClInclude Include="..\src\FakeClient.h" />
|
||||
<ClInclude Include="..\src\Master.h" />
|
||||
<ClInclude Include="..\src\precompiled.h" />
|
||||
<ClInclude Include="..\src\Proxy.h" />
|
||||
<ClInclude Include="..\src\ProxyClient.h" />
|
||||
<ClInclude Include="..\src\Status.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\dep\bzip2\msvc\bzip2.vcxproj">
|
||||
<Project>{792df067-9904-4579-99b9-46c17277ade3}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{ADDFF069-D39D-4A1B-87C9-85A62B980547}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Proxy</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120_xp</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>proxy</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>proxy</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;PROXY_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\Director\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>psapi.lib;ws2_32.lib;steam_api.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)../../../lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;PROXY_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\Director\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>psapi.lib;ws2_32.lib;steam_api.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)../../../lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<PreBuildEvent>
|
||||
<Message>
|
||||
</Message>
|
||||
</PreBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>echo Empty Action</Command>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Message>Force build to run Pre-Build event</Message>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Outputs>git.always.run</Outputs>
|
||||
</CustomBuildStep>
|
||||
<CustomBuildStep>
|
||||
<Inputs>git.always.run</Inputs>
|
||||
</CustomBuildStep>
|
||||
<PostBuildEvent>
|
||||
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Automatic deployment script</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
195
rehlds/HLTV/Proxy/msvc/Proxy.vcxproj.filters
Normal file
195
rehlds/HLTV/Proxy/msvc/Proxy.vcxproj.filters
Normal file
@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{e272c141-8f15-473d-9ea7-8c46b9f2db19}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV">
|
||||
<UniqueIdentifier>{b7066def-60e7-4352-8787-a31a8f9dec0d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="HLTV\common">
|
||||
<UniqueIdentifier>{feda00f0-7c09-4c63-b5a1-e4fbcdfc6b69}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\hookers">
|
||||
<UniqueIdentifier>{199d99ef-8924-48fc-8c8a-2859f8d40c82}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="engine">
|
||||
<UniqueIdentifier>{1777708a-8593-40c0-8caa-9154180854dc}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{ee194364-02f4-428c-a25f-0a60a7d20263}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\common\BaseClient.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\BitBuffer.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DemoFile.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\DirectorCmd.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\InfoString.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\mathlib.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\md5.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\munge.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\NetAddress.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\NetChannel.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\DemoClient.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\FakeClient.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Master.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Proxy.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\ProxyClient.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\public_amalgamation.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Status.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\common.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\random.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\byteorder.cpp">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Proxy\hooklist.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\hookers\HLTV\Proxy\main.cpp">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Director\src\Director.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\BaseSystemModule.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectDictionary.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\ObjectList.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\common\TokenLine.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\engine\mem.cpp">
|
||||
<Filter>engine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\common\BitBuffer.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DemoFile.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\DirectorCmd.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\InfoString.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\mathlib_internal.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\md5.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\munge.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\precompiled.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Proxy.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\DemoClient.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\BaseClient.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\FakeClient.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Master.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\ProxyClient.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Status.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\common_hltv.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\net_internal.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\NetChannel.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\random.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\byteorder.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\NetAddress.h">
|
||||
<Filter>HLTV\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\hookers\HLTV\Proxy\hooklist.h">
|
||||
<Filter>src\hookers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\BaseSystemModule.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectDictionary.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\ObjectList.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\common\TokenLine.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\engine\mem.h">
|
||||
<Filter>engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
294
rehlds/HLTV/Proxy/src/DemoClient.cpp
Normal file
294
rehlds/HLTV/Proxy/src/DemoClient.cpp
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
bool DemoClient::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseSystemModule::Init(system, serial, name);
|
||||
|
||||
m_Proxy = nullptr;
|
||||
m_LastFrameSeqNr = 0;
|
||||
m_ClientDelta = 0;
|
||||
m_IsActive = false;
|
||||
|
||||
memset(m_BaseFileName, 0, sizeof(m_BaseFileName));
|
||||
m_DemoInfo.SetMaxSize(MAX_DEMO_INFO);
|
||||
|
||||
m_State = MODULE_RUNNING;
|
||||
m_System->Printf("Demo client initialized.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *DemoClient::GetStatusLine()
|
||||
{
|
||||
static char string[256];
|
||||
_snprintf(string, sizeof(string), "Recording to %s (%.1f seconds)\n", m_DemoFile.GetFileName(), m_DemoFile.GetDemoTime());
|
||||
return string;
|
||||
}
|
||||
|
||||
bool DemoClient::IsHearingVoices()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DemoClient::HasChatEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char *DemoClient::GetType()
|
||||
{
|
||||
return DEMOCLIENT_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
int DemoClient::GetClientType()
|
||||
{
|
||||
return TYPE_DEMO;
|
||||
}
|
||||
|
||||
void DemoClient::Reconnect()
|
||||
{
|
||||
FinishDemo();
|
||||
}
|
||||
|
||||
bool DemoClient::Connect(INetSocket *socket, NetAddress *adr, char *userinfo)
|
||||
{
|
||||
if (IsActive())
|
||||
{
|
||||
if (m_DemoFile.IsRecording()) {
|
||||
m_System->Printf("Already recording to %s.\n", m_DemoFile.GetFileName());
|
||||
} else {
|
||||
m_System->Printf("Already recording initialized for %s.\n", m_BaseFileName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_DemoChannel.Create(m_System);
|
||||
m_DemoChannel.SetUpdateRate(40);
|
||||
m_DemoChannel.SetRate(20000);
|
||||
|
||||
m_LastFrameSeqNr = 0;
|
||||
m_ClientDelta = 0;
|
||||
|
||||
m_DemoChannel.SetKeepAlive(false);
|
||||
m_DemoFile.Init(m_World, nullptr, &m_DemoChannel);
|
||||
|
||||
m_IsActive = true;
|
||||
m_System->Printf("Recording initialized.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DemoClient::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
NetPacket *packet = m_DemoChannel.GetPacket();
|
||||
while (packet)
|
||||
{
|
||||
m_System->DPrintf("WARNING! Incoming data in demo game channel.Ignored.\n");
|
||||
m_DemoChannel.FreePacket(packet);
|
||||
|
||||
packet = m_DemoChannel.GetPacket();
|
||||
}
|
||||
|
||||
if (IsActive() && m_World->IsActive() && m_DemoChannel.IsReadyToSend()) {
|
||||
SendDatagram();
|
||||
}
|
||||
}
|
||||
|
||||
void DemoClient::SendDatagram()
|
||||
{
|
||||
if (m_Proxy->GetDelay() > 0)
|
||||
{
|
||||
double worldTime = m_Proxy->GetSpectatorTime();
|
||||
double proxyTime = m_Proxy->GetProxyTime();
|
||||
|
||||
frame_t *frame = m_World->GetFrameByTime(worldTime);
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame->seqnr > 1) {
|
||||
WriteDatagram(proxyTime - (worldTime - frame->time), frame);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
frame_t *frame = m_World->GetLastFrame();
|
||||
if (frame) {
|
||||
WriteDatagram(frame->time, frame);
|
||||
}
|
||||
}
|
||||
|
||||
void DemoClient::WriteDatagram(double time, frame_t *frame)
|
||||
{
|
||||
unsigned int deltaFrameSeqNr = m_LastFrameSeqNr;
|
||||
if (deltaFrameSeqNr > 0)
|
||||
{
|
||||
if (deltaFrameSeqNr == frame->seqnr)
|
||||
return;
|
||||
|
||||
if (deltaFrameSeqNr > frame->seqnr)
|
||||
m_LastFrameSeqNr = frame->seqnr - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char mapname[MAX_PATH];
|
||||
COM_FileBase(m_World->GetLevelName(), mapname);
|
||||
|
||||
char fileName[MAX_PATH];
|
||||
_snprintf(fileName, sizeof(fileName), "%s-%s-%s.dem", m_BaseFileName, COM_TimeString(), mapname);
|
||||
|
||||
m_DemoFile.StartRecording(fileName);
|
||||
m_Proxy->WriteSignonData(TYPE_DEMO, &m_DemoChannel.m_reliableStream);
|
||||
}
|
||||
|
||||
m_DemoChannel.m_unreliableStream.WriteByte(svc_time);
|
||||
m_DemoChannel.m_unreliableStream.WriteFloat((float)time);
|
||||
|
||||
m_World->WriteFrame(frame, m_LastFrameSeqNr, &m_DemoChannel.m_reliableStream, &m_DemoChannel.m_unreliableStream, deltaFrameSeqNr, m_ClientDelta, true);
|
||||
m_LastFrameSeqNr = frame->seqnr;
|
||||
m_ClientDelta = (m_DemoChannel.m_outgoing_sequence & 0xFF);
|
||||
|
||||
// reliable stream has overflowed
|
||||
if (m_DemoChannel.m_reliableStream.IsOverflowed())
|
||||
{
|
||||
m_System->Printf("WARNING! DemoClient::WriteDatagram: reliable data overflow.\n");
|
||||
Disconnect("reliable data overflow");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_DemoChannel.m_unreliableStream.IsOverflowed()) {
|
||||
m_DemoChannel.m_unreliableStream.Clear();
|
||||
}
|
||||
|
||||
m_DemoFile.WriteDemoMessage(&m_DemoChannel.m_unreliableStream, &m_DemoChannel.m_reliableStream);
|
||||
m_DemoChannel.TransmitOutgoing();
|
||||
|
||||
client_data_t cdata;
|
||||
memset(&cdata, 0, sizeof(cdata));
|
||||
m_DemoFile.WriteUpdateClientData(&cdata);
|
||||
}
|
||||
|
||||
bool DemoClient::IsActive()
|
||||
{
|
||||
return m_IsActive;
|
||||
}
|
||||
|
||||
void DemoClient::Disconnect(const char *reason)
|
||||
{
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
if (reason)
|
||||
{
|
||||
m_DemoChannel.m_reliableStream.WriteByte(svc_print);
|
||||
m_DemoChannel.m_reliableStream.WriteString(reason);
|
||||
}
|
||||
|
||||
FinishDemo();
|
||||
m_IsActive = false;
|
||||
}
|
||||
|
||||
void DemoClient::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED)
|
||||
return;
|
||||
|
||||
FinishDemo();
|
||||
m_IsActive = false;
|
||||
|
||||
BaseSystemModule::ShutDown();
|
||||
m_System->Printf("Demo module shutdown.\n");
|
||||
}
|
||||
|
||||
void DemoClient::FinishDemo()
|
||||
{
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
m_DemoChannel.m_reliableStream.WriteByte(svc_print);
|
||||
m_DemoChannel.m_reliableStream.WriteString("HLTV Demo finished.\n");
|
||||
|
||||
m_DemoFile.WriteDemoMessage(&m_DemoChannel.m_unreliableStream, &m_DemoChannel.m_reliableStream);
|
||||
m_DemoFile.CloseFile();
|
||||
m_DemoChannel.Clear();
|
||||
|
||||
m_LastFrameSeqNr = 0;
|
||||
m_ClientDelta = 0;
|
||||
}
|
||||
|
||||
NetAddress *DemoClient::GetAddress()
|
||||
{
|
||||
static NetAddress fakeaddress;
|
||||
fakeaddress.Clear();
|
||||
return &fakeaddress;
|
||||
}
|
||||
|
||||
void DemoClient::Send(unsigned char *data, int length, bool isReliable)
|
||||
{
|
||||
if (isReliable)
|
||||
m_DemoChannel.m_reliableStream.WriteBuf(data, length);
|
||||
else
|
||||
m_DemoChannel.m_unreliableStream.WriteBuf(data, length);
|
||||
}
|
||||
|
||||
void DemoClient::SetProxy(IProxy *proxy)
|
||||
{
|
||||
m_Proxy = proxy;
|
||||
}
|
||||
|
||||
InfoString *DemoClient::GetUserInfo()
|
||||
{
|
||||
return &m_DemoInfo;
|
||||
}
|
||||
|
||||
char *DemoClient::GetClientName()
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
void DemoClient::SetWorld(IWorld *world)
|
||||
{
|
||||
m_World = world;
|
||||
}
|
||||
|
||||
void DemoClient::SetFileName(char *fileName)
|
||||
{
|
||||
strcopy(m_BaseFileName, fileName);
|
||||
}
|
||||
|
||||
DemoFile *DemoClient::GetDemoFile()
|
||||
{
|
||||
return &m_DemoFile;
|
||||
}
|
78
rehlds/HLTV/Proxy/src/DemoClient.h
Normal file
78
rehlds/HLTV/Proxy/src/DemoClient.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/InfoString.h"
|
||||
|
||||
class DemoClient: public IClient, public BaseSystemModule {
|
||||
public:
|
||||
DemoClient() {}
|
||||
virtual ~DemoClient() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
void ShutDown();
|
||||
bool Connect(INetSocket *socket = nullptr, NetAddress *adr = nullptr, char *userinfo = "");
|
||||
void Disconnect(const char *reason);
|
||||
void Reconnect();
|
||||
void SetWorld(IWorld *world);
|
||||
bool IsHearingVoices();
|
||||
bool HasChatEnabled();
|
||||
NetAddress *GetAddress();
|
||||
int GetClientType();
|
||||
char *GetClientName();
|
||||
InfoString *GetUserInfo();
|
||||
bool IsActive();
|
||||
void Send(unsigned char *data, int length, bool isReliable);
|
||||
|
||||
void SetProxy(IProxy *proxy);
|
||||
void SetFileName(char *fileName);
|
||||
DemoFile *GetDemoFile();
|
||||
void FinishDemo();
|
||||
void SendDatagram();
|
||||
void WriteDatagram(double time, frame_t *frame);
|
||||
|
||||
protected:
|
||||
IProxy *m_Proxy;
|
||||
IWorld *m_World;
|
||||
bool m_IsActive;
|
||||
NetChannel m_DemoChannel;
|
||||
|
||||
enum { MAX_DEMO_INFO = 256 };
|
||||
DemoFile m_DemoFile;
|
||||
char m_BaseFileName[MAX_PATH];
|
||||
|
||||
InfoString m_DemoInfo;
|
||||
unsigned int m_LastFrameSeqNr;
|
||||
unsigned int m_ClientDelta;
|
||||
};
|
||||
|
||||
#define DEMOCLIENT_INTERFACE_VERSION "democlient000"
|
156
rehlds/HLTV/Proxy/src/FakeClient.cpp
Normal file
156
rehlds/HLTV/Proxy/src/FakeClient.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
bool FakeClient::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseSystemModule::Init(system, serial, name);
|
||||
|
||||
_snprintf(m_Name, sizeof(m_Name), "fakeclient%i", serial);
|
||||
|
||||
m_Network = dynamic_cast<INetwork *>(m_System->GetModule(NETWORK_INTERFACE_VERSION, "core"));
|
||||
if (!m_Network)
|
||||
{
|
||||
m_System->Errorf("FakeClient::Init: couldn't load network module.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(m_Socket = m_Network->CreateSocket(serial + 2048)))
|
||||
{
|
||||
m_System->Errorf("FakeClient::Init: Could not create port %i.\n", serial + 2048);
|
||||
return false;
|
||||
}
|
||||
|
||||
char temp[256];
|
||||
sprintf(temp, "fakeserver%i", serial);
|
||||
|
||||
m_Server = dynamic_cast<IServer *>(m_System->GetModule(SERVER_INTERFACE_VERSION, "core", temp));
|
||||
if (!m_Server)
|
||||
{
|
||||
m_System->Errorf("FakeClient::Init: couldn't load server module.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Server->RegisterListener(this);
|
||||
m_Server->SetUserInfo("hspecs", "0");
|
||||
m_Server->SetUserInfo("hslots", "0");
|
||||
m_Server->SetDelayReconnect(false);
|
||||
m_Server->SetPlayerName(m_Name);
|
||||
m_Server->SetAutoRetry(false);
|
||||
|
||||
sprintf(temp, "fakeworld%i", serial);
|
||||
|
||||
m_World = dynamic_cast<IWorld *>(m_System->GetModule(WORLD_INTERFACE_VERSION, "core", temp));
|
||||
if (!m_World)
|
||||
{
|
||||
m_System->Errorf("FakeClient::Init: couldn't load world module.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_World->RegisterListener(this);
|
||||
|
||||
m_State = MODULE_RUNNING;
|
||||
m_System->Printf("Fake client module initialized (%i).\n", serial);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeClient::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
NetPacket *packet;
|
||||
while ((packet = m_Socket->ReceivePacket()))
|
||||
{
|
||||
m_System->DPrintf("FakeClient: WARNING! Packet from %s with invalid sequence number.\n", packet->address.ToString());
|
||||
m_Socket->FreePacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void FakeClient::SetRate(int rate)
|
||||
{
|
||||
m_Server->SetRate(rate);
|
||||
}
|
||||
|
||||
void FakeClient::Connect(NetAddress *adr)
|
||||
{
|
||||
m_Server->Connect(m_World, adr, m_Socket);
|
||||
}
|
||||
|
||||
void FakeClient::Retry()
|
||||
{
|
||||
m_Server->Retry();
|
||||
}
|
||||
|
||||
void FakeClient::Say(char *text)
|
||||
{
|
||||
if (!m_Server->IsConnected())
|
||||
return;
|
||||
|
||||
char string[1024];
|
||||
_snprintf(string, sizeof(string), "say \"%s\"", text);
|
||||
m_Server->SendStringCommand(text);
|
||||
}
|
||||
|
||||
void FakeClient::Disconnect()
|
||||
{
|
||||
m_Server->Disconnect();
|
||||
}
|
||||
|
||||
void FakeClient::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED)
|
||||
return;
|
||||
|
||||
if (m_World) {
|
||||
m_World->RemoveListener(this);
|
||||
}
|
||||
|
||||
BaseSystemModule::ShutDown();
|
||||
m_System->Printf("FakeClient module shutdown.\n");
|
||||
}
|
||||
|
||||
void FakeClient::ReceiveSignal(ISystemModule *module, unsigned int signal, void *data)
|
||||
{
|
||||
if (module->GetSerial() != m_World->GetSerial())
|
||||
return;
|
||||
|
||||
if (signal == 8 /* signal to shutdown*/) {
|
||||
ShutDown();
|
||||
}
|
||||
}
|
||||
|
||||
char *FakeClient::GetType()
|
||||
{
|
||||
return FAKECLIENT_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
char *FakeClient::GetStatusLine()
|
||||
{
|
||||
return "I am a fake client.\n";
|
||||
}
|
63
rehlds/HLTV/Proxy/src/FakeClient.h
Normal file
63
rehlds/HLTV/Proxy/src/FakeClient.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseSystemModule.h"
|
||||
|
||||
class IWorld;
|
||||
class IServer;
|
||||
class INetwork;
|
||||
class INetSocket;
|
||||
|
||||
class FakeClient: public BaseSystemModule {
|
||||
public:
|
||||
FakeClient() {}
|
||||
virtual ~FakeClient() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
void ShutDown();
|
||||
|
||||
void SetRate(int rate);
|
||||
void Connect(NetAddress *adr);
|
||||
void Retry();
|
||||
void Say(char *text);
|
||||
void Disconnect();
|
||||
|
||||
protected:
|
||||
INetwork *m_Network;
|
||||
IWorld *m_World;
|
||||
IServer *m_Server;
|
||||
INetSocket *m_Socket;
|
||||
};
|
||||
|
||||
#define FAKECLIENT_INTERFACE_VERSION "fakeclient000"
|
293
rehlds/HLTV/Proxy/src/Master.cpp
Normal file
293
rehlds/HLTV/Proxy/src/Master.cpp
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
Master::GameToAppIDMapItem_t Master::m_GameToAppIDMap[] =
|
||||
{
|
||||
{ GAME_APPID_CSTRIKE, "cstrike" },
|
||||
{ GAME_APPID_TFC, "tfc" },
|
||||
{ GAME_APPID_DOD, "dod" },
|
||||
{ GAME_APPID_DMC, "dmc" },
|
||||
{ GAME_APPID_GEARBOX, "gearbox" },
|
||||
{ GAME_APPID_RICOCHET, "ricochet" },
|
||||
{ GAME_APPID_VALVE, "valve" },
|
||||
{ GAME_APPID_CZERO, "czero" },
|
||||
{ GAME_APPID_CZEROR, "czeror" },
|
||||
{ GAME_APPID_BSHIFT, "bshift" },
|
||||
{ GAME_APPID_CSTRIKE_BETA, "cstrike_beta" }
|
||||
};
|
||||
|
||||
Master::Master() :
|
||||
m_flMasterUpdateTime(0),
|
||||
m_bSteamInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
int Master::GetGameAppID(const char *gamedir) const
|
||||
{
|
||||
for (auto& game : m_GameToAppIDMap) {
|
||||
if (!_stricmp(game.dir, gamedir)) {
|
||||
return game.appID;
|
||||
}
|
||||
}
|
||||
|
||||
return GAME_APPID_VALVE;
|
||||
}
|
||||
|
||||
bool Master::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseSystemModule::Init(system, serial, name);
|
||||
|
||||
m_MasterSocket = m_Proxy->GetSocket();
|
||||
|
||||
m_System->RegisterCommand("heartbeat", this, CMD_ID_HEARTBEAT);
|
||||
m_System->RegisterCommand("nomaster", this, CMD_ID_NOMASTER);
|
||||
m_System->RegisterCommand("listmaster", this, CMD_ID_LISTMASTER);
|
||||
|
||||
m_State = MODULE_RUNNING;
|
||||
m_NoMaster = false;
|
||||
m_bMasterLoaded = false;
|
||||
|
||||
INetwork *network = m_MasterSocket->GetNetwork();
|
||||
if (!network->GetLocalAddress()) {
|
||||
m_System->Printf("Master module failed to initialize (no net).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bSteamInitialized = false;
|
||||
m_System->Printf("Master module initialized.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Master::SetProxy(IProxy *proxy)
|
||||
{
|
||||
m_Proxy = proxy;
|
||||
}
|
||||
|
||||
void Master::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
static double s_flLastRunCallbacks = 0.0f;
|
||||
if ((time - s_flLastRunCallbacks) > 0.1)
|
||||
{
|
||||
SteamGameServer_RunCallbacks();
|
||||
s_flLastRunCallbacks = time;
|
||||
}
|
||||
|
||||
if (m_NoMaster)
|
||||
return;
|
||||
|
||||
if (m_Proxy->IsActive())
|
||||
{
|
||||
if (!m_bSteamInitialized)
|
||||
{
|
||||
IWorld *world = m_Proxy->GetWorld();
|
||||
if (world)
|
||||
{
|
||||
int nAppID = GetGameAppID(world->GetGameDir());
|
||||
if (nAppID > 0)
|
||||
{
|
||||
FILE *f = fopen("steam_appid.txt", "w+");
|
||||
if (f)
|
||||
{
|
||||
fprintf(f, "%d\n", nAppID);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
INetwork *network = m_MasterSocket->GetNetwork();
|
||||
NetAddress *netAdr = network->GetLocalAddress();
|
||||
|
||||
if (SteamGameServer_Init(ntohl(*(u_long *)&netAdr->m_IP[0]), 0, 0, 0xFFFFu, eServerModeNoAuthentication, MASTER_VERSION))
|
||||
{
|
||||
SteamGameServer()->SetProduct("hltv");
|
||||
SteamGameServer()->SetGameDescription("hltv");
|
||||
SteamGameServer()->SetModDir(world->GetGameDir());
|
||||
SteamGameServer()->SetDedicatedServer(true);
|
||||
SteamGameServer()->SetSpectatorPort(netAdr->m_Port);
|
||||
SteamGameServer()->LogOnAnonymous();
|
||||
|
||||
SteamGameServer()->EnableHeartbeats(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: Actually here call via Printf, but we will be use DPrintf to avoid useless print into console
|
||||
// or at least make only print once.
|
||||
m_System->DPrintf("Master module failed to initialize. (init failed)\n");
|
||||
}
|
||||
|
||||
m_bSteamInitialized = SteamGameServer() ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bSteamInitialized)
|
||||
{
|
||||
IWorld *world = m_Proxy->GetWorld();
|
||||
if (m_flMasterUpdateTime < m_System->GetTime())
|
||||
{
|
||||
char mapName[MAX_PATH];
|
||||
COM_FileBase(world->GetLevelName(), mapName);
|
||||
|
||||
char szHostName[MAX_PATH];
|
||||
strcopy(szHostName, world->GetHostName());
|
||||
|
||||
int slots, proxies, spectators;
|
||||
m_Proxy->GetStatistics(proxies, slots, spectators);
|
||||
|
||||
SteamGameServer()->SetMaxPlayerCount(min(slots, 127)); // max slots
|
||||
SteamGameServer()->SetServerName(szHostName);
|
||||
SteamGameServer()->SetMapName(mapName);
|
||||
SteamGameServer()->SetPasswordProtected(m_Proxy->IsPasswordProtected());
|
||||
SteamGameServer()->SetModDir(world->GetGameDir());
|
||||
|
||||
m_flMasterUpdateTime = m_System->GetTime() + 5.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bSteamInitialized)
|
||||
{
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
char szOutBuf[4096];
|
||||
|
||||
int iLen = SteamGameServer()->GetNextOutgoingPacket(szOutBuf, sizeof(szOutBuf), &ip, &port);
|
||||
while (iLen > 0)
|
||||
{
|
||||
NetAddress netAdr;
|
||||
*((uint32 *)&netAdr.m_IP[0]) = htonl(ip);
|
||||
netAdr.m_Port = htons(port);
|
||||
|
||||
m_MasterSocket->SendPacket(&netAdr, szOutBuf, iLen);
|
||||
|
||||
iLen = SteamGameServer()->GetNextOutgoingPacket(szOutBuf, sizeof(szOutBuf), &ip, &port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Master::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SteamGameServer()) {
|
||||
SteamGameServer()->LogOff();
|
||||
}
|
||||
|
||||
BaseSystemModule::ShutDown();
|
||||
SteamGameServer_Shutdown();
|
||||
m_System->Printf("Master module shutdown.\n");
|
||||
}
|
||||
|
||||
void Master::CMD_Heartbeat(char *cmdLine)
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SteamGameServer()) {
|
||||
SteamGameServer()->ForceHeartbeat();
|
||||
}
|
||||
}
|
||||
|
||||
void Master::CMD_NoMaster(char *cmdLine)
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED || !SteamGameServer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TokenLine params(cmdLine);
|
||||
if (params.CountToken() != 2)
|
||||
{
|
||||
m_System->Printf("Syntax: nomaster <0|1>\n");
|
||||
m_System->Printf("Master server notification is %s.\n", m_NoMaster ? "disabled" : "enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
bool bOldMasterState = m_NoMaster;
|
||||
m_NoMaster = atoi(params.GetToken(1)) ? true : false;
|
||||
|
||||
if (bOldMasterState != m_NoMaster) {
|
||||
SteamGameServer()->EnableHeartbeats(m_NoMaster);
|
||||
}
|
||||
}
|
||||
|
||||
void Master::CMD_ListMaster(char *pchCmdLine)
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_System->Printf("No longer used\n");
|
||||
}
|
||||
|
||||
void Master::ExecuteCommand(int commandID, char *commandLine)
|
||||
{
|
||||
switch (commandID)
|
||||
{
|
||||
case CMD_ID_HEARTBEAT:
|
||||
CMD_Heartbeat(commandLine);
|
||||
break;
|
||||
case CMD_ID_NOMASTER:
|
||||
CMD_NoMaster(commandLine);
|
||||
break;
|
||||
case CMD_ID_LISTMASTER:
|
||||
CMD_ListMaster(commandLine);
|
||||
break;
|
||||
default:
|
||||
m_System->Printf("ERROR! Master::ExecuteCommand: unknown command ID %i.\n", commandID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *Master::GetType()
|
||||
{
|
||||
return MASTER_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
void Master::SendShutdown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SteamGameServer()) {
|
||||
SteamGameServer()->EnableHeartbeats(false);
|
||||
}
|
||||
}
|
||||
|
||||
char *Master::GetStatusLine()
|
||||
{
|
||||
static char string[256];
|
||||
_snprintf(string, sizeof(string), "Master servers: 0\n");
|
||||
return string;
|
||||
}
|
115
rehlds/HLTV/Proxy/src/Master.h
Normal file
115
rehlds/HLTV/Proxy/src/Master.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseSystemModule.h"
|
||||
#include "TokenLine.h"
|
||||
|
||||
#define MASTER_VERSION "1.1.2.6"
|
||||
|
||||
enum GameType_e
|
||||
{
|
||||
GT_CSTRIKE,
|
||||
GT_TFC,
|
||||
GT_DOD,
|
||||
GT_DMC,
|
||||
GT_GEARBOX,
|
||||
GT_RICOCHET,
|
||||
GT_VALVE,
|
||||
GT_CZERO,
|
||||
GT_CZEROR,
|
||||
GT_BSHIFT,
|
||||
GT_CSTRIKE_BETA,
|
||||
};
|
||||
|
||||
class Proxy;
|
||||
class INetSocket;
|
||||
|
||||
class Master: public BaseSystemModule {
|
||||
public:
|
||||
Master();
|
||||
virtual ~Master() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
void RunFrame(double time);
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
void ShutDown();
|
||||
|
||||
void InitializeSteam();
|
||||
void SendShutdown();
|
||||
void SetProxy(IProxy *proxy);
|
||||
|
||||
private:
|
||||
enum LocalCommandIDs {
|
||||
CMD_ID_HEARTBEAT = 1,
|
||||
CMD_ID_NOMASTER,
|
||||
CMD_ID_LISTMASTER,
|
||||
};
|
||||
|
||||
void CMD_Heartbeat(char *cmdLine);
|
||||
void CMD_NoMaster(char *cmdLine);
|
||||
void CMD_ListMaster(char *cmdLine);
|
||||
|
||||
enum {
|
||||
GAME_APPID_CSTRIKE = 10,
|
||||
GAME_APPID_TFC = 20,
|
||||
GAME_APPID_DOD = 30,
|
||||
GAME_APPID_DMC = 40,
|
||||
GAME_APPID_GEARBOX = 50,
|
||||
GAME_APPID_RICOCHET = 60,
|
||||
GAME_APPID_VALVE = 70,
|
||||
GAME_APPID_CZERO = 80,
|
||||
GAME_APPID_CZEROR = 100,
|
||||
GAME_APPID_BSHIFT = 130,
|
||||
GAME_APPID_CSTRIKE_BETA = 150,
|
||||
};
|
||||
|
||||
typedef struct GameToAppIDMapItem_s
|
||||
{
|
||||
size_t appID;
|
||||
const char *dir;
|
||||
} GameToAppIDMapItem_t;
|
||||
|
||||
static GameToAppIDMapItem_t m_GameToAppIDMap[];
|
||||
int GetGameAppID(const char *gamedir) const;
|
||||
|
||||
protected:
|
||||
friend class Proxy;
|
||||
|
||||
bool m_NoMaster;
|
||||
bool m_bMasterLoaded;
|
||||
INetSocket *m_MasterSocket;
|
||||
IProxy *m_Proxy;
|
||||
double m_flMasterUpdateTime;
|
||||
bool m_bSteamInitialized;
|
||||
};
|
||||
|
||||
#define MASTER_INTERFACE_VERSION "master000"
|
2770
rehlds/HLTV/Proxy/src/Proxy.cpp
Normal file
2770
rehlds/HLTV/Proxy/src/Proxy.cpp
Normal file
File diff suppressed because it is too large
Load Diff
377
rehlds/HLTV/Proxy/src/Proxy.h
Normal file
377
rehlds/HLTV/Proxy/src/Proxy.h
Normal file
@ -0,0 +1,377 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseSystemModule.h"
|
||||
#include "common/NetAddress.h"
|
||||
|
||||
#include "ObjectList.h"
|
||||
#include "DemoClient.h"
|
||||
#include "Status.h"
|
||||
#include "Master.h"
|
||||
#include "Director.h"
|
||||
#include "DirectorNull.h"
|
||||
|
||||
class IWorld;
|
||||
class IServer;
|
||||
class INetwork;
|
||||
class IDirector;
|
||||
class IBaseSystem;
|
||||
|
||||
#define MAX_NAME 32
|
||||
#define MAX_PROXY_RATE 20000
|
||||
#define MAX_PROXY_UPDATERATE 40
|
||||
|
||||
#define PROXY_CHALLENGE_LIFE 40.0f
|
||||
#define PROXY_PRIVATE 0x8000
|
||||
#define PROXY_VERSION "1.1.2.0"
|
||||
#define PROXY_DEFAULT_PORT "27020"
|
||||
|
||||
// TODO: it is necessary to unify with rehlsdk
|
||||
typedef struct textmessage_s {
|
||||
int effect;
|
||||
byte r1, g1, b1, a1; // 2 colors for effects
|
||||
byte r2, g2, b2, a2;
|
||||
float x;
|
||||
float y;
|
||||
float fadein;
|
||||
float fadeout;
|
||||
float holdtime;
|
||||
float fxtime;
|
||||
char text[80];
|
||||
} textmessage_t;
|
||||
|
||||
class Proxy: public IProxy, public BaseSystemModule {
|
||||
public:
|
||||
Proxy() {}
|
||||
virtual ~Proxy() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void RunFrame(double time);
|
||||
void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
void ShutDown();
|
||||
|
||||
void Reset();
|
||||
void Broadcast(byte *data, int length, int groupType, bool isReliable);
|
||||
void IncreaseCheering(int votes);
|
||||
void ChatCommentator(char *nick, char *text);
|
||||
void ChatSpectator(char *nick, char *text);
|
||||
void CountLocalClients(int &spectators, int &proxies);
|
||||
void ParseStatusMsg(BitBuffer *stream);
|
||||
void ParseStatusReport(NetAddress *from, BitBuffer *stream);
|
||||
bool ProcessConnectionlessMessage(NetAddress *from, BitBuffer *stream);
|
||||
resource_t *AddResource(char *fileName, resourcetype_t type, char *asFileName = nullptr);
|
||||
bool IsMaster();
|
||||
bool IsLanOnly();
|
||||
bool IsActive();
|
||||
bool IsPublicGame();
|
||||
bool IsPasswordProtected();
|
||||
bool IsStressed();
|
||||
void SetDelay(float seconds);
|
||||
void SetClientTime(double time, bool relative);
|
||||
void SetClientTimeScale(float scale);
|
||||
void SetMaxRate(int rate);
|
||||
void SetMaxLoss(float maxloss);
|
||||
void SetMaxUpdateRate(int updaterate);
|
||||
bool SetMaxClients(int number);
|
||||
void SetRegion(unsigned char region);
|
||||
float GetDelay();
|
||||
double GetSpectatorTime();
|
||||
double GetProxyTime();
|
||||
IObjectContainer *GetClients();
|
||||
IWorld *GetWorld();
|
||||
IServer *GetServer();
|
||||
IDirector *GetDirector();
|
||||
INetSocket *GetSocket();
|
||||
ChatMode_e GetChatMode();
|
||||
void GetStatistics(int &proxies, int &slots, int &spectators);
|
||||
int GetMaxRate();
|
||||
int GetMaxClients();
|
||||
int GetMaxUpdateRate();
|
||||
resource_t *GetResource(char *fileName);
|
||||
int GetDispatchMode();
|
||||
unsigned char GetRegion();
|
||||
bool WriteSignonData(int type, BitBuffer *stream);
|
||||
|
||||
void ReconnectClients();
|
||||
void ExecuteRcon(NetAddress *from, char *command);
|
||||
void SendRcon(NetAddress *to, unsigned int challenge);
|
||||
void ReplyServiceChallenge(NetAddress *to, char *type);
|
||||
void ReplyListen(NetAddress *to);
|
||||
void RejectConnection(NetAddress *adr, bool badPassword, const char *fmt, ...);
|
||||
void ReplyConnect(NetAddress *to, int protocol, int challenge, char *protinfo, char *userinfo);
|
||||
void ReplyRules(NetAddress *to);
|
||||
void ReplyPlayers(NetAddress *to);
|
||||
void ReplyInfo(NetAddress *to, bool detailed);
|
||||
void ReplyInfoString(NetAddress *to);
|
||||
void ReplyChallenge(NetAddress *to);
|
||||
void ReplyPing(NetAddress *to);
|
||||
|
||||
void UpdateStatusLine();
|
||||
void DispatchClient(NetAddress *client, NetAddress *proxy);
|
||||
bool IsValidPassword(int type, char *pw);
|
||||
void WriteHUDMsg(textmessage_t *msg, BitBuffer *stream);
|
||||
|
||||
typedef struct loopcmd_s {
|
||||
int id;
|
||||
float interval;
|
||||
float lastTime;
|
||||
char command[255];
|
||||
} loopcmd_t;
|
||||
|
||||
void ExecuteLoopCommands();
|
||||
unsigned int GetChallengeNumber(NetAddress *host);
|
||||
bool CheckChallenge(NetAddress *from, unsigned int challengeNumber);
|
||||
void CreateServerInfoString(InfoString *info);
|
||||
bool CheckDirectorModule();
|
||||
void RunClocks();
|
||||
void NewGameStarted();
|
||||
void NewServerConnection();
|
||||
void BroadcastPaused(bool paused);
|
||||
void BroadcastRetryMessage();
|
||||
void StopBroadcast(const char *message);
|
||||
char *GetModVersion(char *gamedir);
|
||||
void DisconnectClients(const char *reason);
|
||||
void FreeResource(resource_t *resource);
|
||||
void ClearResources();
|
||||
resource_t *LoadResourceFromFile(char *fileName, resourcetype_t type);
|
||||
bool IsBanned(NetAddress *adr);
|
||||
void UpdateInfoMessages();
|
||||
void SetName(char *newName);
|
||||
|
||||
private:
|
||||
enum LocalCommandIDs {
|
||||
CMD_ID_RCON = 1,
|
||||
CMD_ID_RCONPASSWORD,
|
||||
CMD_ID_RCONADDRESS,
|
||||
CMD_ID_SAY,
|
||||
CMD_ID_MSG,
|
||||
CMD_ID_CLIENTS,
|
||||
CMD_ID_KICK,
|
||||
CMD_ID_CHATMODE,
|
||||
CMD_ID_PUBLICGAME,
|
||||
CMD_ID_OFFLINETEXT,
|
||||
CMD_ID_ADMINPASSWORD,
|
||||
CMD_ID_SIGNONCOMMANDS,
|
||||
CMD_ID_SPECTATORPASSWORD,
|
||||
CMD_ID_DISPATCHMODE,
|
||||
CMD_ID_CHEERINGTHRESHOLD,
|
||||
CMD_ID_INFORMPLAYERS,
|
||||
CMD_ID_PING,
|
||||
CMD_ID_PROXYPASSWORD,
|
||||
CMD_ID_MAXRATE,
|
||||
CMD_ID_LOOPCMD,
|
||||
CMD_ID_MAXCLIENTS,
|
||||
CMD_ID_DISCONNECT,
|
||||
CMD_ID_LOCALMSG,
|
||||
CMD_ID_CONNECT,
|
||||
CMD_ID_PLAYDEMO,
|
||||
CMD_ID_DELAY,
|
||||
CMD_ID_STOP,
|
||||
CMD_ID_RECORD,
|
||||
CMD_ID_STOPRECORDING,
|
||||
CMD_ID_SERVERCMD,
|
||||
CMD_ID_CLIENTCMD,
|
||||
CMD_ID_BLOCKVOICE,
|
||||
CMD_ID_NAME,
|
||||
CMD_ID_UPDATERATE,
|
||||
CMD_ID_RATE,
|
||||
CMD_ID_ADDRESOURCE,
|
||||
CMD_ID_RESOURCES,
|
||||
CMD_ID_BANNERFILE,
|
||||
CMD_ID_BANN,
|
||||
CMD_ID_ADDFAKECLIENTS,
|
||||
CMD_ID_RETRY,
|
||||
CMD_ID_PLAYERS,
|
||||
CMD_ID_AUTORETRY,
|
||||
CMD_ID_SERVERPASSWORD,
|
||||
CMD_ID_STATUS,
|
||||
CMD_ID_HOSTNAME,
|
||||
CMD_ID_MAXQUERIES,
|
||||
CMD_ID_CLEARBANNS,
|
||||
CMD_ID_MAXLOSS,
|
||||
CMD_ID_PROTOCOL,
|
||||
CMD_ID_REGION
|
||||
};
|
||||
|
||||
void CMD_Rcon(char *cmdLine);
|
||||
void CMD_ServerCmd(char *cmdLine);
|
||||
void CMD_ClientCmd(char *cmdLine);
|
||||
void CMD_RconPassword(char *cmdLine);
|
||||
void CMD_RconAddress(char *cmdLine);
|
||||
void CMD_Say(char *cmdLine);
|
||||
void CMD_Msg(char *cmdLine);
|
||||
void CMD_Clients(char *cmdLine);
|
||||
void CMD_Kick(char *cmdLine);
|
||||
void CMD_ChatMode(char *cmdLine);
|
||||
void CMD_PublicGame(char *cmdLine);
|
||||
void CMD_OffLineText(char *cmdLine);
|
||||
void CMD_AdminPassword(char *cmdLine);
|
||||
void CMD_SignOnCommands(char *cmdLine);
|
||||
void CMD_SpectatorPassword(char *cmdLine);
|
||||
void CMD_DispatchMode(char *cmdLine);
|
||||
void CMD_CheeringThreshold(char *cmdLine);
|
||||
void CMD_InformPlayers(char *cmdLine);
|
||||
void CMD_Ping(char *cmdLine);
|
||||
void CMD_ProxyPassword(char *cmdLine);
|
||||
void CMD_MaxRate(char *cmdLine);
|
||||
void CMD_MaxUpdateRate(char *cmdLine);
|
||||
void CMD_LoopCmd(char *cmdLine);
|
||||
void CMD_MaxClients(char *cmdLine);
|
||||
void CMD_LocalMsg(char *cmdLine);
|
||||
void CMD_Connect(char *cmdLine);
|
||||
void CMD_Disconnect(char *cmdLine);
|
||||
void CMD_PlayDemo(char *cmdLine);
|
||||
void CMD_Delay(char *cmdLine);
|
||||
void CMD_Stop(char *cmdLine);
|
||||
void CMD_Record(char *cmdLine);
|
||||
void CMD_StopRecording(char *cmdLine);
|
||||
void CMD_BlockVoice(char *cmdLine);
|
||||
void CMD_Name(char *cmdLine);
|
||||
void CMD_Rate(char *cmdLine);
|
||||
void CMD_Updaterate(char *cmdLine);
|
||||
void CMD_HostName(char *cmdLine);
|
||||
void CMD_AddResource(char *cmdLine);
|
||||
void CMD_Resources(char *cmdLine);
|
||||
void CMD_BannerFile(char *cmdLine);
|
||||
void CMD_Bann(char *cmdLine);
|
||||
void CMD_AddFakeClients(char *cmdLine);
|
||||
void CMD_Retry(char *cmdLine);
|
||||
void CMD_AutoRetry(char *cmdLine);
|
||||
void CMD_ServerPassword(char *cmdLine);
|
||||
void CMD_Status(char *cmdLine);
|
||||
void CMD_MaxQueries(char *cmdLine);
|
||||
void CMD_Players(char *cmdLine);
|
||||
void CMD_ClearBanns(char *cmdLine);
|
||||
void CMD_MaxLoss(char *cmdLine);
|
||||
void CMD_Protocol(char *cmdLine);
|
||||
void CMD_Region(char *cmdLine);
|
||||
|
||||
struct LocalCommandID_s {
|
||||
char *name;
|
||||
LocalCommandIDs id;
|
||||
void (Proxy::*pfnCmd)(char *cmdLine);
|
||||
};
|
||||
static LocalCommandID_s m_LocalCmdReg[];
|
||||
const char *GetDescription();
|
||||
|
||||
protected:
|
||||
friend class DemoClient;
|
||||
friend class Status;
|
||||
friend class Master;
|
||||
friend class Director;
|
||||
|
||||
INetwork *m_Network;
|
||||
IWorld *m_World;
|
||||
IDirector *m_Director;
|
||||
IServer *m_Server;
|
||||
ObjectList m_Clients;
|
||||
|
||||
DemoClient m_DemoClient;
|
||||
Status m_Status;
|
||||
Master m_Master;
|
||||
Director m_DefaultDirector;
|
||||
DirectorNull m_NullDirector;
|
||||
INetSocket *m_Socket;
|
||||
|
||||
typedef struct challenge_s {
|
||||
NetAddress adr;
|
||||
unsigned int challenge;
|
||||
float time;
|
||||
} challenge_t;
|
||||
|
||||
// MAX_CHALLENGES is made large to prevent a denial
|
||||
// of service attack that could cycle all of them
|
||||
// out before legitimate users connected
|
||||
enum { MAX_CHALLENGES = 1024 };
|
||||
challenge_t m_Challenges[MAX_CHALLENGES];
|
||||
|
||||
bool m_IsMaster;
|
||||
bool m_IsFinishingBroadcast;
|
||||
bool m_IsReconnectRequested;
|
||||
|
||||
int m_MaxRate;
|
||||
int m_MaxUpdateRate;
|
||||
|
||||
ChatMode_e m_ChatMode;
|
||||
int m_MaxClients;
|
||||
float m_MaxQueries;
|
||||
int m_MaxFrameQueries;
|
||||
int m_MaxSeenClients;
|
||||
|
||||
NetAddress m_RconAddress;
|
||||
char m_RconPassword[128];
|
||||
char m_AdminPassword[128];
|
||||
char m_ProxyPassword[128];
|
||||
char m_SpectatorPassword[128];
|
||||
char m_LastRconCommand[1024];
|
||||
char m_OffLineText[128];
|
||||
char m_SignonCommands[256];
|
||||
|
||||
ObjectList m_LoopCommands;
|
||||
bool m_PublicGame;
|
||||
|
||||
enum DispatchMode_e : int {
|
||||
DISPATCH_OFF, // Won't redirect any clients.
|
||||
DISPATCH_BALANCE, // Will redirect connecting clients to other proxies balancing work load between all proxies.
|
||||
DISPATCH_ALL, // Any spectator clients will be redirected, so this proxy serves only as dispatcher.
|
||||
};
|
||||
DispatchMode_e m_DispatchMode;
|
||||
|
||||
float m_ClientDelay;
|
||||
float m_ClientTimeScale;
|
||||
double m_ClientWorldTime;
|
||||
double m_ClientProxyTime;
|
||||
|
||||
double m_LastClockUpdateTime;
|
||||
float m_CheeringThreshold;
|
||||
float m_LastCheeringUpdate;
|
||||
int m_CheeringPlayers;
|
||||
resource_t *m_BannerTGA;
|
||||
ObjectList m_Resources;
|
||||
double m_NextStatusUpdateTime;
|
||||
float m_FPS;
|
||||
float m_MaxLoss;
|
||||
float m_CurrentLoss;
|
||||
ObjectList m_BannList;
|
||||
unsigned char m_Region;
|
||||
|
||||
textmessage_t m_LocalMessage;
|
||||
textmessage_t m_CommentatorMessage;
|
||||
|
||||
double m_NextInfoMessagesUpdate;
|
||||
BitBuffer m_InfoRules;
|
||||
BitBuffer m_InfoPlayers;
|
||||
BitBuffer m_InfoDetails;
|
||||
BitBuffer m_InfoInfo;
|
||||
BitBuffer m_InfoString;
|
||||
};
|
317
rehlds/HLTV/Proxy/src/ProxyClient.cpp
Normal file
317
rehlds/HLTV/Proxy/src/ProxyClient.cpp
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void ProxyClient::ShutDown()
|
||||
{
|
||||
char *clientTypeString[] = { "Spectator", "Relay Proxy", "Director", "Commentator", "Fake Client" };
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_System->Printf("%s disconnected (%s)\n", clientTypeString[m_ClientType], m_ClientChannel.m_remote_address.ToString());
|
||||
m_Proxy->GetClients()->Remove(this);
|
||||
|
||||
BaseClient::ShutDown();
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool ProxyClient::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseClient::Init(system, serial, name);
|
||||
|
||||
m_ClientType = TYPE_CLIENT;
|
||||
m_ChatEnabled = true;
|
||||
|
||||
m_LastChatTime = 0;
|
||||
m_LastCheerTime = 0;
|
||||
m_NextDecalTime = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ProxyClient::LocalCommandID_s ProxyClient::m_LocalCmdReg[] = {
|
||||
{ "cheer", CMD_ID_CHEER, &ProxyClient::CMD_Cheer },
|
||||
{ "say", CMD_ID_SAY, &ProxyClient::CMD_Say },
|
||||
{ "joingame", CMD_ID_JOINGAME, &ProxyClient::CMD_JoinGame },
|
||||
{ "status", CMD_ID_STATUS, &ProxyClient::CMD_Status },
|
||||
{ "ignoremsg", CMD_ID_IGNOREMSG, &ProxyClient::CMD_IgnoreMsg },
|
||||
};
|
||||
|
||||
bool ProxyClient::ProcessStringCmd(char *string)
|
||||
{
|
||||
if (BaseClient::ProcessStringCmd(string)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TokenLine cmdLine;
|
||||
if (!cmdLine.SetLine(string)) {
|
||||
m_System->Printf("WARNING! ProxyClient::ProcessStringCmd: string command too long.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
char *cmd = cmdLine.GetToken(0);
|
||||
for (auto& local_cmd : m_LocalCmdReg)
|
||||
{
|
||||
if (!_stricmp(local_cmd.name, cmd)) {
|
||||
(this->*local_cmd.pfnCmd)(&cmdLine);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ClientType < TYPE_COMMENTATOR) {
|
||||
m_System->DPrintf("Unkown client command: \"%s\"\n", cmd);
|
||||
}
|
||||
|
||||
m_System->DPrintf("Unkown director command: \"%s\"\n", cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProxyClient::CMD_Cheer(TokenLine *cmd)
|
||||
{
|
||||
if (m_SystemTime <= m_LastCheerTime + 6) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_LastCheerTime = float(m_SystemTime);
|
||||
m_Proxy->IncreaseCheering(1);
|
||||
}
|
||||
|
||||
void ProxyClient::CMD_Say(TokenLine *cmd)
|
||||
{
|
||||
char *chatText = (cmd->CountToken() > 2) ? cmd->GetRestOfLine(1) : cmd->GetToken(1);
|
||||
if (m_ClientType == TYPE_COMMENTATOR) {
|
||||
m_Proxy->ChatCommentator(nullptr, chatText);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ClientType == TYPE_PROXY && m_Proxy->GetChatMode() == CHAT_GLOBAL) {
|
||||
m_Proxy->ChatSpectator("Unknown", chatText);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_SystemTime >= m_LastChatTime + 6) {
|
||||
m_Proxy->ChatSpectator(m_ClientName, chatText);
|
||||
m_LastChatTime = float(m_SystemTime);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyClient::CMD_JoinGame(TokenLine *cmd)
|
||||
{
|
||||
if (m_Proxy->GetServer()->IsDemoFile()) {
|
||||
PrintfToClient("Proxy is replaying demo.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Proxy->IsPublicGame())
|
||||
{
|
||||
char string[64];
|
||||
_snprintf(string, sizeof(string), "connect %s\n", m_World->GetGameServerAddress()->ToString());
|
||||
|
||||
m_ClientChannel.m_reliableStream.WriteByte(svc_stufftext);
|
||||
m_ClientChannel.m_reliableStream.WriteString(string);
|
||||
}
|
||||
|
||||
PrintfToClient("Joining game is not allowed.\n");
|
||||
}
|
||||
|
||||
void ProxyClient::CMD_Status(TokenLine *cmd)
|
||||
{
|
||||
PrintfToClient("--- HLTV Status ---\n");
|
||||
|
||||
if (m_Proxy->GetServer()->IsDemoFile()) {
|
||||
PrintfToClient("Replay demo file %s\n", m_Proxy->GetServer()->GetDemoFileName());
|
||||
}
|
||||
else if (m_Proxy->IsPublicGame()) {
|
||||
PrintfToClient("Game Server: %s\n", m_World->GetGameServerAddress()->ToString());
|
||||
}
|
||||
else {
|
||||
PrintfToClient("Private game server\n");
|
||||
}
|
||||
|
||||
int proxies, spectators, slots;
|
||||
m_Proxy->GetStatistics(proxies, slots, spectators);
|
||||
PrintfToClient("Global HLTV stats: spectators %i, slots %i, proxies %i\n", spectators, slots, proxies);
|
||||
}
|
||||
|
||||
void ProxyClient::CMD_IgnoreMsg(TokenLine *cmd)
|
||||
{
|
||||
if (cmd->CountToken() != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ChatEnabled = !atoi(cmd->GetToken(1));
|
||||
PrintfToClient("Global HLTV stats: spectators %i, slots %i, proxies %i\n", m_ChatEnabled ? "Spectator chat enabled.\n" : "Spectator chat disabled.\n");
|
||||
}
|
||||
|
||||
void ProxyClient::UpdateUserInfo(char *userinfostring)
|
||||
{
|
||||
BaseClient::UpdateUserInfo(userinfostring);
|
||||
|
||||
if (m_ClientType > TYPE_DEMO) {
|
||||
m_System->DPrintf("WARNING! Client::UpdateUserInfo: invalid client ype %i\n", m_ClientType);
|
||||
m_ClientType = TYPE_CLIENT;
|
||||
}
|
||||
|
||||
if (m_ClientType) {
|
||||
return;
|
||||
}
|
||||
|
||||
// clamp rate
|
||||
if (m_ClientChannel.GetRate() > m_Proxy->GetMaxRate()) {
|
||||
m_ClientChannel.SetRate(m_Proxy->GetMaxRate());
|
||||
}
|
||||
|
||||
if (m_ClientType == TYPE_CLIENT)
|
||||
{
|
||||
if (m_ClientChannel.GetUpdateRate() > m_Proxy->GetMaxUpdateRate()) {
|
||||
m_ClientChannel.SetUpdateRate(m_Proxy->GetMaxUpdateRate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyClient::ParseHLTV(NetPacket *packet)
|
||||
{
|
||||
unsigned char cmd = packet->data.ReadByte();
|
||||
if (cmd != HLTV_STATUS) {
|
||||
m_System->Printf("WARNING! unknown HLTV client msg %i\n", cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ClientType != TYPE_PROXY) {
|
||||
m_System->DPrintf("WARNING! HLTV status data from spectator client\n");
|
||||
packet->data.SkipBytes(12);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Proxy->ParseStatusReport(GetAddress(), &packet->data);
|
||||
}
|
||||
|
||||
void ProxyClient::ReplySpawn(int spawncount, int crcMap)
|
||||
{
|
||||
BaseClient::ReplySpawn(spawncount, crcMap);
|
||||
|
||||
if (m_ClientType == TYPE_PROXY) {
|
||||
m_VoiceQuery = false;
|
||||
}
|
||||
|
||||
m_Proxy->WriteSignonData(m_ClientType, &m_ClientChannel.m_reliableStream);
|
||||
}
|
||||
|
||||
void ProxyClient::SendDatagram()
|
||||
{
|
||||
if (m_Proxy->GetDelay() > 0)
|
||||
{
|
||||
double worldTime = m_Proxy->GetSpectatorTime();
|
||||
double proxyTime = m_Proxy->GetProxyTime();
|
||||
|
||||
frame_t *frame = m_World->GetFrameByTime(worldTime);
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ClientChannel.GetIdleTime() > 2) {
|
||||
m_ClientChannel.m_unreliableStream.WriteByte(svc_centerprint);
|
||||
m_ClientChannel.m_unreliableStream.WriteString((frame->seqnr > 1) ? "Game pending..." : "Buffering game...");
|
||||
}
|
||||
|
||||
double time = proxyTime - (worldTime - frame->time);
|
||||
WriteDatagram(time, frame);
|
||||
return;
|
||||
}
|
||||
|
||||
frame_t *frame = m_World->GetLastFrame();
|
||||
if (frame)
|
||||
{
|
||||
if (m_ClientChannel.GetIdleTime() > 2) {
|
||||
m_ClientChannel.m_unreliableStream.WriteByte(svc_centerprint);
|
||||
m_ClientChannel.m_unreliableStream.WriteString("Game pending...");
|
||||
}
|
||||
|
||||
WriteDatagram(frame->time, frame);
|
||||
}
|
||||
}
|
||||
|
||||
bool ProxyClient::HasChatEnabled()
|
||||
{
|
||||
return m_ChatEnabled;
|
||||
}
|
||||
|
||||
void ProxyClient::ParseVoiceData(NetPacket *packet)
|
||||
{
|
||||
int nDataLength = packet->data.ReadShort();
|
||||
BitBuffer voiceMsg(nDataLength + 8);
|
||||
|
||||
if (m_ClientType != TYPE_COMMENTATOR) {
|
||||
packet->data.SkipBytes(nDataLength);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nDataLength > MAX_VOICEDATA_LEN) {
|
||||
Disconnect("Invalid voice message.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
voiceMsg.WriteByte(svc_voicedata);
|
||||
voiceMsg.WriteByte(m_World->GetSlotNumber());
|
||||
voiceMsg.WriteShort(nDataLength);
|
||||
voiceMsg.WriteBuf(packet->data.CurrentByte(), nDataLength);
|
||||
|
||||
m_Proxy->Broadcast(voiceMsg.GetData(), voiceMsg.CurrentSize(), GROUP_PROXY | GROUP_DEMO | GROUP_UNKNOWN | GROUP_VOICE, false);
|
||||
packet->data.SkipBytes(nDataLength);
|
||||
}
|
||||
|
||||
void ProxyClient::DownloadFile(char *fileName)
|
||||
{
|
||||
if (!fileName || !fileName[0])
|
||||
return;
|
||||
|
||||
const char szMD5[] = "!MD5";
|
||||
if (strstr(fileName, "..") ||
|
||||
// ignore customization's
|
||||
(strlen(fileName) == 36 && !_strnicmp(fileName, szMD5, sizeof(szMD5) - 1)))
|
||||
{
|
||||
DownloadFailed(fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
resource_t *resource = m_Proxy->GetResource(fileName);
|
||||
if (resource) {
|
||||
m_ClientChannel.CreateFragmentsFromBuffer(resource->data, resource->nDownloadSize, FRAG_FILE_STREAM, fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ClientChannel.CreateFragmentsFromFile(fileName)) {
|
||||
m_ClientChannel.FragSend();
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadFailed(fileName);
|
||||
}
|
82
rehlds/HLTV/Proxy/src/ProxyClient.h
Normal file
82
rehlds/HLTV/Proxy/src/ProxyClient.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/BaseClient.h"
|
||||
|
||||
class IProxy;
|
||||
class NetPacket;
|
||||
class IBaseSystem;
|
||||
|
||||
class ProxyClient: public BaseClient {
|
||||
public:
|
||||
ProxyClient(IProxy *proxy) : m_Proxy(proxy) {}
|
||||
virtual ~ProxyClient() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void ShutDown();
|
||||
bool HasChatEnabled();
|
||||
bool ProcessStringCmd(char *string);
|
||||
void ReplySpawn(int spawncount, int crcMap);
|
||||
void UpdateUserInfo(char *userinfostring = nullptr);
|
||||
void ParseVoiceData(NetPacket *packet);
|
||||
void DownloadFile(char *fileName);
|
||||
void SendDatagram();
|
||||
void ParseHLTV(NetPacket *packet);
|
||||
|
||||
private:
|
||||
enum LocalCommandIDs {
|
||||
CMD_ID_CHEER = 1,
|
||||
CMD_ID_SAY,
|
||||
CMD_ID_JOINGAME,
|
||||
CMD_ID_STATUS,
|
||||
CMD_ID_IGNOREMSG
|
||||
};
|
||||
|
||||
void CMD_Cheer(TokenLine *cmd);
|
||||
void CMD_Say(TokenLine *cmd);
|
||||
void CMD_JoinGame(TokenLine *cmd);
|
||||
void CMD_Status(TokenLine *cmd);
|
||||
void CMD_IgnoreMsg(TokenLine *cmd);
|
||||
|
||||
struct LocalCommandID_s {
|
||||
char *name;
|
||||
LocalCommandIDs id;
|
||||
void (ProxyClient::*pfnCmd)(TokenLine *cmd);
|
||||
};
|
||||
static LocalCommandID_s m_LocalCmdReg[];
|
||||
|
||||
protected:
|
||||
IProxy *m_Proxy;
|
||||
|
||||
float m_LastChatTime;
|
||||
float m_LastCheerTime;
|
||||
float m_NextDecalTime;
|
||||
bool m_ChatEnabled;
|
||||
};
|
318
rehlds/HLTV/Proxy/src/Status.cpp
Normal file
318
rehlds/HLTV/Proxy/src/Status.cpp
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
bool Status::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
BaseSystemModule::Init(system, serial, name);
|
||||
|
||||
SetName("status");
|
||||
|
||||
m_Proxies.Init();
|
||||
m_System->RegisterCommand("proxies", this, CMD_ID_PROXIES);
|
||||
|
||||
Reset();
|
||||
|
||||
m_State = MODULE_RUNNING;
|
||||
m_System->DPrintf("Status module initialized.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Status::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
if (m_MaxNumberOfSpectators < m_NumberOfSpectators) {
|
||||
m_MaxNumberOfSpectators = m_NumberOfSpectators;
|
||||
}
|
||||
|
||||
if (!m_Proxy->IsMaster() || !m_Proxy->IsActive())
|
||||
return;
|
||||
|
||||
if (m_SystemTime > m_NextUpdateTime)
|
||||
{
|
||||
GetLocalStats(m_NumberOfProxies, m_NumberOfSlots, m_NumberOfSpectators);
|
||||
SendStatusUpdate();
|
||||
|
||||
m_Proxy->GetServer()->SetUserInfo("hspecs", COM_VarArgs("%u", m_NumberOfSpectators));
|
||||
m_Proxy->GetServer()->SetUserInfo("hslots", COM_VarArgs("%u", m_NumberOfSlots));
|
||||
|
||||
m_NextUpdateTime = float(m_SystemTime) + 16.f;
|
||||
}
|
||||
}
|
||||
|
||||
void Status::ExecuteCommand(int commandID, char *commandLine)
|
||||
{
|
||||
if (commandID == CMD_ID_PROXIES) {
|
||||
CMD_Proxies(commandLine);
|
||||
return;
|
||||
}
|
||||
|
||||
m_System->Printf("ERROR! Status::ExecuteCommand: unknown command ID %i.\n", commandID);
|
||||
}
|
||||
|
||||
void Status::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED)
|
||||
return;
|
||||
|
||||
m_Proxies.Clear(true);
|
||||
m_System->Printf("Status module shutdown.\n");
|
||||
|
||||
BaseSystemModule::ShutDown();
|
||||
}
|
||||
|
||||
void Status::GetGlobalStats(int &proxies, int &slots, int &spectators)
|
||||
{
|
||||
proxies = m_NumberOfProxies;
|
||||
slots = m_NumberOfSlots;
|
||||
spectators = m_NumberOfSpectators;
|
||||
}
|
||||
|
||||
void Status::SetProxy(IProxy *proxy)
|
||||
{
|
||||
m_Proxy = proxy;
|
||||
}
|
||||
|
||||
void Status::SendStatusUpdate()
|
||||
{
|
||||
BitBuffer buffer(128);
|
||||
|
||||
buffer.WriteByte(svc_hltv);
|
||||
buffer.WriteByte(HLTV_STATUS);
|
||||
|
||||
buffer.WriteWord(m_NumberOfProxies);
|
||||
buffer.WriteLong(m_NumberOfSlots);
|
||||
buffer.WriteLong(m_NumberOfSpectators);
|
||||
|
||||
m_Proxy->Broadcast(buffer.GetData(), buffer.CurrentSize(), GROUP_PROXY, true);
|
||||
buffer.FastClear();
|
||||
|
||||
DirectorCmd cmd;
|
||||
cmd.SetStatusData(m_NumberOfSlots, m_NumberOfSpectators, m_NumberOfProxies);
|
||||
cmd.WriteToStream(&buffer);
|
||||
|
||||
// group spectators
|
||||
m_Proxy->Broadcast(buffer.GetData(), buffer.CurrentSize(), GROUP_CLIENT | GROUP_DEMO | GROUP_UNKNOWN, false);
|
||||
buffer.FastClear();
|
||||
}
|
||||
|
||||
void Status::SetName(char *newName)
|
||||
{
|
||||
strcopy(m_Name, newName);
|
||||
}
|
||||
|
||||
char *Status::GetType()
|
||||
{
|
||||
return STATUS_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
char *Status::GetStatusLine()
|
||||
{
|
||||
static char string[256];
|
||||
_snprintf(string, sizeof(string), "Global Status: Proxies %i, Slots %i, Spectators %i (max %i)\n",
|
||||
m_NumberOfProxies, m_NumberOfSlots,
|
||||
m_NumberOfSpectators, m_MaxNumberOfSpectators);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
void Status::Reset()
|
||||
{
|
||||
m_Proxies.Clear(true);
|
||||
|
||||
m_NumberOfProxies = 0;
|
||||
m_NumberOfSlots = 0;
|
||||
m_NumberOfSpectators = 0;
|
||||
m_MaxNumberOfSpectators = 0;
|
||||
m_NextUpdateTime = 0;
|
||||
}
|
||||
|
||||
void Status::ParseStatusMsg(BitBuffer *stream)
|
||||
{
|
||||
if (m_Proxy->IsMaster()) {
|
||||
m_System->Printf("WARNING! Status::ParseStatusMsg: unexpected HLTV_STATUS message as Master.\n");
|
||||
stream->SkipBytes(10);
|
||||
return;
|
||||
}
|
||||
|
||||
m_NumberOfProxies = stream->ReadWord();
|
||||
m_NumberOfSlots = stream->ReadLong();
|
||||
m_NumberOfSpectators = stream->ReadLong();
|
||||
|
||||
ReplyStatusReport();
|
||||
SendStatusUpdate();
|
||||
}
|
||||
|
||||
void Status::ReplyStatusReport()
|
||||
{
|
||||
BitBuffer buf(128);
|
||||
|
||||
int slots, proxies, spectators;
|
||||
GetLocalStats(proxies, slots, spectators);
|
||||
|
||||
if (!m_Proxy->IsPasswordProtected())
|
||||
{
|
||||
if (!m_Proxy->GetDispatchMode()) {
|
||||
slots = m_Proxy->GetMaxClients();
|
||||
}
|
||||
else if (m_Proxy->IsStressed()) {
|
||||
proxies |= PROXY_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteByte(1);
|
||||
buf.WriteWord(proxies);
|
||||
buf.WriteLong(slots);
|
||||
buf.WriteLong(spectators);
|
||||
|
||||
m_Proxy->GetServer()->SendHLTVCommand(&buf);
|
||||
}
|
||||
|
||||
int Status::GetMaxSpectatorNumber()
|
||||
{
|
||||
return m_MaxNumberOfSpectators;
|
||||
}
|
||||
|
||||
void Status::ParseStatusReport(NetAddress *from, BitBuffer *stream)
|
||||
{
|
||||
int proxies = stream->ReadWord();
|
||||
int slots = stream->ReadLong();
|
||||
int spectators = stream->ReadLong();
|
||||
|
||||
bool isPrivate = false;
|
||||
if (proxies & PROXY_PRIVATE) {
|
||||
proxies &= ~PROXY_PRIVATE;
|
||||
isPrivate = true;
|
||||
}
|
||||
|
||||
proxyInfo_t *proxy = (proxyInfo_t *)m_Proxies.GetFirst();
|
||||
while (proxy)
|
||||
{
|
||||
if (from->Equal(&proxy->address)) {
|
||||
break;
|
||||
}
|
||||
|
||||
proxy = (proxyInfo_t *)m_Proxies.GetNext();
|
||||
}
|
||||
|
||||
// couldn't find it?
|
||||
// allocate for
|
||||
if (!proxy)
|
||||
{
|
||||
proxy = (proxyInfo_t *)Mem_ZeroMalloc(sizeof(proxyInfo_t));
|
||||
if (!proxy) {
|
||||
m_System->Printf("WARNING! Status::ParseStatusReport: not enough memory to increase proxy list.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
proxy->address.FromNetAddress(from);
|
||||
m_Proxies.Add(proxy);
|
||||
}
|
||||
|
||||
proxy->slots = slots;
|
||||
proxy->spectators = spectators;
|
||||
proxy->proxies = proxies;
|
||||
proxy->time = float(m_SystemTime);
|
||||
proxy->isPrivate = isPrivate;
|
||||
|
||||
float ratio = (slots > 0 && !isPrivate) ? float(spectators / slots) : 1;
|
||||
m_Proxies.ChangeKey(proxy, ratio);
|
||||
}
|
||||
|
||||
void Status::GetLocalStats(int &proxies, int &slots, int &spectators)
|
||||
{
|
||||
slots = 0;
|
||||
spectators = 0;
|
||||
proxies = 0;
|
||||
|
||||
proxyInfo_t *proxy = (proxyInfo_t *)m_Proxies.GetFirst();
|
||||
while (proxy)
|
||||
{
|
||||
if (m_SystemTime > proxy->time + 64)
|
||||
{
|
||||
m_Proxies.Remove(proxy);
|
||||
free(proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxies += proxy->proxies;
|
||||
slots += proxy->slots;
|
||||
spectators += proxy->spectators;
|
||||
}
|
||||
|
||||
proxy = (proxyInfo_t *)m_Proxies.GetNext();
|
||||
}
|
||||
|
||||
int mySpecs, myProxies;
|
||||
m_Proxy->CountLocalClients(mySpecs, myProxies);
|
||||
|
||||
spectators += mySpecs;
|
||||
slots += m_Proxy->GetMaxClients();
|
||||
|
||||
proxies++;
|
||||
}
|
||||
|
||||
void Status::CMD_Proxies(char *cmdLine)
|
||||
{
|
||||
int nCount = 0;
|
||||
proxyInfo_t *proxy = (proxyInfo_t *)m_Proxies.GetFirst();
|
||||
while (proxy)
|
||||
{
|
||||
nCount++;
|
||||
m_System->Printf("IP %s, Clients %i, MaxClients %i%s\n", proxy->address.ToString(), proxy->spectators, proxy->slots, proxy->isPrivate ? " (excluded)" : "");
|
||||
|
||||
proxy = (proxyInfo_t *)m_Proxies.GetNext();
|
||||
}
|
||||
|
||||
m_System->Printf("--- Total %i relay proxies ---\n", nCount);
|
||||
}
|
||||
|
||||
float Status::GetBestRelayProxy(NetAddress *addr)
|
||||
{
|
||||
proxyInfo_t *proxy = (proxyInfo_t *)m_Proxies.GetFirst();
|
||||
while (proxy)
|
||||
{
|
||||
if (proxy->slots > 0 && proxy->slots >= proxy->spectators && !proxy->isPrivate)
|
||||
{
|
||||
float ratio = float(++proxy->spectators / proxy->slots);
|
||||
|
||||
m_Proxies.ChangeKey(proxy, ratio);
|
||||
addr->FromNetAddress(&proxy->address);
|
||||
return ratio;
|
||||
}
|
||||
|
||||
m_Proxies.ChangeKey(proxy, 1);
|
||||
proxy = (proxyInfo_t *)m_Proxies.GetNext();
|
||||
}
|
||||
|
||||
addr->Clear();
|
||||
return -1;
|
||||
}
|
85
rehlds/HLTV/Proxy/src/Status.h
Normal file
85
rehlds/HLTV/Proxy/src/Status.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/NetAddress.h"
|
||||
#include "ObjectDictionary.h"
|
||||
#include "hltv.h"
|
||||
|
||||
typedef struct proxyInfo_s {
|
||||
NetAddress address;
|
||||
int slots;
|
||||
int proxies;
|
||||
int spectators;
|
||||
int isPrivate;
|
||||
float time;
|
||||
} proxyInfo_t;
|
||||
|
||||
class IProxy;
|
||||
class Status: public BaseSystemModule {
|
||||
public:
|
||||
Status() {}
|
||||
virtual ~Status() {}
|
||||
|
||||
bool Init(IBaseSystem *system, int serial, char *name);
|
||||
void ExecuteCommand(int commandID, char *commandLine);
|
||||
void RunFrame(double time);
|
||||
char *GetStatusLine();
|
||||
char *GetType();
|
||||
void ShutDown();
|
||||
|
||||
void GetGlobalStats(int &proxies, int &slots, int &spectators);
|
||||
void GetLocalStats(int &proxies, int &slots, int &spectators);
|
||||
void SetProxy(IProxy *proxy);
|
||||
float GetBestRelayProxy(NetAddress *addr);
|
||||
void ParseStatusMsg(BitBuffer *stream);
|
||||
void ParseStatusReport(NetAddress *from, BitBuffer *stream);
|
||||
void Reset();
|
||||
int GetMaxSpectatorNumber();
|
||||
void RemoveProxy(NetAddress *addr);
|
||||
void ClearProxyList();
|
||||
void ReplyStatusReport();
|
||||
void SendStatusUpdate();
|
||||
void SetName(char *newName);
|
||||
|
||||
protected:
|
||||
enum LocalCommandIDs { CMD_ID_PROXIES = 1 };
|
||||
void CMD_Proxies(char *cmdLine);
|
||||
|
||||
private:
|
||||
IProxy *m_Proxy;
|
||||
float m_NextUpdateTime;
|
||||
ObjectDictionary m_Proxies;
|
||||
int m_NumberOfProxies;
|
||||
int m_NumberOfSlots;
|
||||
int m_NumberOfSpectators;
|
||||
int m_MaxNumberOfSpectators;
|
||||
};
|
||||
|
||||
#define STATUS_INTERFACE_VERSION "status000"
|
1
rehlds/HLTV/Proxy/src/precompiled.cpp
Normal file
1
rehlds/HLTV/Proxy/src/precompiled.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "precompiled.h"
|
49
rehlds/HLTV/Proxy/src/precompiled.h
Normal file
49
rehlds/HLTV/Proxy/src/precompiled.h
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "archtypes.h"
|
||||
#include "mathlib.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include "interface.h"
|
||||
#include "IBaseSystem.h"
|
||||
|
||||
#include "mem.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "common/md5.h"
|
||||
#include "common/random.h"
|
||||
#include "common/byteorder.h"
|
||||
#include "common/ServerInfo.h"
|
||||
#include "common/common_hltv.h"
|
||||
#include "common/net_internal.h"
|
||||
#include "common/mathlib_internal.h"
|
||||
|
||||
// Hooks stuff
|
||||
#include "hookers/HLTV/Proxy/hooklist.h"
|
||||
|
||||
#include "common/DirectorCmd.h"
|
||||
#include "common/NetAddress.h"
|
||||
#include "common/NetChannel.h"
|
||||
#include "common/BaseClient.h"
|
||||
|
||||
#include "common/DemoFile.h"
|
||||
#include "common/munge.h"
|
||||
|
||||
#include <steam/steam_gameserver.h>
|
||||
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <HLTV/IProxy.h>
|
||||
#include <HLTV/IServer.h>
|
||||
#include <HLTV/IClient.h>
|
||||
#include <HLTV/INetChannel.h>
|
||||
#include <HLTV/INetwork.h>
|
||||
|
||||
// Proxy module stuff
|
||||
#include "Proxy.h"
|
||||
#include "ProxyClient.h"
|
||||
#include "DemoClient.h"
|
||||
#include "FakeClient.h"
|
||||
|
||||
#include "Master.h"
|
||||
#include "Status.h"
|
3
rehlds/HLTV/Proxy/src/public_amalgamation.cpp
Normal file
3
rehlds/HLTV/Proxy/src/public_amalgamation.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "interface.cpp"
|
333
rehlds/HLTV/README.md
Normal file
333
rehlds/HLTV/README.md
Normal file
@ -0,0 +1,333 @@
|
||||
## Half-Life TV for Goldsrc based games <img align="right" src="https://cloud.githubusercontent.com/assets/5860435/25316484/320cce9a-2892-11e7-8d12-3290baf4458c.png" alt="HLTV Launcher"/>
|
||||
|
||||
### Building
|
||||
On Windows:
|
||||
<pre>gradlew --max-workers=1 clean rehlds/HLTV:build</pre>
|
||||
|
||||
On Linux (ICC):
|
||||
<pre>./gradlew --max-workers=1 clean rehlds/HLTV:build</pre>
|
||||
|
||||
On Linux (GCC):
|
||||
<pre>./gradlew --max-workers=1 -PuseGcc clean rehlds/HLTV:build</pre>
|
||||
|
||||
Compiled binaries will be placed in each project rehlds/HLTV/**/binaries/ directory
|
||||
|
||||
### Overview
|
||||
Half-Life TV offers the ability to have an unlimited number of spectators watching online games.
|
||||
They can follow the game just like they would as a spectator on the game server.
|
||||
Spectators are invisible to players and can't interact with the running game in any way.
|
||||
Each spectator can choose any view position or choose any player to track individually.
|
||||
|
||||
To have the most enjoyable spectating experience, spectators can enable the Auto-Director mode.
|
||||
Then the camera is changed automatically so that only interesting scenes are shown from a suitable viewpoint.
|
||||
Thus the spectator can lean back and won't miss any relevant action.
|
||||
All the time, spectators may communicate between each other using the standard HL chat system.
|
||||
|
||||
Most popular Half-Life MODs are supported like `Counter-Strike`, `Team Fortress Classic`, `Day of Defeat` and many others.
|
||||
HLTV providers have full control over their HLTV system, may change number of spectator slots, add text messages or change the HLTV logo.
|
||||
|
||||
The broadcast is delayed by a customizable amount of time, by default 30 seconds. This ensures that the playing teams can't use
|
||||
HLTV to get any usable information about their opponents. Providing a single HLTV server for up to 100 spectators is an easy task
|
||||
and doesn't need any changes in default configurations.
|
||||
|
||||
Installing a larger HLTV network for thousands of spectators needs some more planning time and experience about required bandwidth
|
||||
and CPU/RAM demands (see [Larger Broadcasts](#larger-broadcasts)).
|
||||
|
||||
### Spectating Games
|
||||
To watch a HLTV game, start Half-Life, open the Multiplayer menu and select 'Find Servers'.
|
||||
To search for currently broadcasted games, choose the 'Spectate' section and hit 'Refresh All'.
|
||||
After the list has been updated, double click on the server you want to spectate and you'll be connected.
|
||||
|
||||
If computer game leagues announce important matches to be broadcasted via HLTV, they often provide IP:Port addresses of their HLTV servers.
|
||||
Instead of searching them via the server browser, you can also go to the 'Favorites' folder and add the HLTV address to your server
|
||||
list by pressing the right mouse button. Otherwise, you can also open the console window and use the 'connect' command to spectate a certain game.
|
||||
|
||||
For example:
|
||||
<pre>
|
||||
connect 192.168.130.42:27020
|
||||
</pre>
|
||||
|
||||
The default HLTV port number is 27020, but may be changed.
|
||||
It should always be included in the given address, since commonly this port number is different from the default port number 27015.
|
||||
|
||||
You can spectate the game in different modes: `Chase Cam`, `First Person`, `Free Look`, `Map Overview` and `Map Chase`.<br />
|
||||
The easiest way to change modes is to press the JUMP key (default `SPACE`). Alternatively you can use the spectator menu, which can be enabled by pressing the `DUCK` key (default `CTRL`).
|
||||
Here you can customize your personal view style and enable the Auto-Director Mode. Press `USE` (default `E`) to cycle through the different `Picture-In-Picture` modes.
|
||||
|
||||
The following HL console commands can be used to customize spectator settings:
|
||||
|
||||
| Console commands | Default | Min | Max | Description |
|
||||
| :---------------------------- | :-----: | :-: | :----------: | :--------------------------------------------- |
|
||||
| spec_autodirector | 1 | 0 | 1 | Turns Auto Director mode on or off |
|
||||
| spec_drawcone | 1 | 0 | 1 | Shows your view cone in map overview mode |
|
||||
| spec_drawnames | 1 | 0 | 1 | Shows player names under their icons |
|
||||
| spec_drawstatus | 1 | 0 | 1 | Shows game information (time, map etc) |
|
||||
| spec_pip | 0 | 0 | 1 | Turns Picture-In-Picture mode on or off |
|
||||
| spec_mode | 1 | 1 | 6 | Set the main view mode, seconds parameter is the PIP mode.<br />Not all combinations are valid.<br />Main modes are:<br />`1` Locked Chase<br />`2` Free Chase<br />`3` Free Roaming<br />`4` First Person<br />`5` Map Overview<br />`6` Chase Map Overview<br /><br />PIP modes are:<br />`0` PIP off<br />`1` Free Chase<br />`2` First Person<br />`3` Map Overview<br />`4` Chase Map Overview<br /> |
|
||||
| spec_menu | - | - | - | Opens the spectator menu |
|
||||
| spec_help | - | - | - | Shows a help screen |
|
||||
|
||||
### HLTV Basics
|
||||
The core of the HLTV broadcasting system is the HLTV server, also called HLTV proxy.
|
||||
The HLTV executable is a console application that works much like a HL dedicated server.
|
||||
To broadcast a game running on a certain game server, the HLTV proxy connects to this server just like a normal player.
|
||||
Spectators connect themselves to the HLTV proxy and the game data stream is relayed through the HLTV proxy to all connected spectator clients.
|
||||
|
||||
The next figure shows a basic HLTV configuration:
|
||||
<pre>
|
||||
HL Game Server -> HLTV Proxy => Spectator Clients
|
||||
</pre>
|
||||
|
||||
The number of clients that one HLTV proxy can serve depends on available hardware and network resources.
|
||||
Theoretically, a single proxy can hold a maximum of 255 spectator clients.
|
||||
But be careful, even a proxy with 100 spectator clients needs a full 2 MBit line to run smoothly.
|
||||
If more spectator slots are needed, the required network load must be distributed over multiple HLTV proxies.
|
||||
|
||||
The first HLTV proxy connected to the game server is called the Master proxy, which sets the general broadcast settings like
|
||||
game stream delay or packet rate. All other HLTV proxies linked to this proxy are the Relay proxies. Their total number and
|
||||
link order is not restricted, they may form a chain or tree of proxies.
|
||||
Most important is that their location is in different networks to ensure a balanced bandwidth usage.
|
||||
|
||||
<pre>
|
||||
-> HLTV Relay Proxy 1 => Spectator Clients
|
||||
HL Game Server -> HLTV Master -> HLTV Relay Proxy 2 => Spectator Clients
|
||||
-> HLTV Relay Proxy 3 => Spectator Clients
|
||||
</pre>
|
||||
|
||||
### Broadcasting Games
|
||||
Let's assume the most simple configuration, a single HLTV proxy in a LAN environment.
|
||||
This is a very common situation and the default HLTV settings doesn't need to be changed.
|
||||
Choose a dedicated computer as your HLTV proxy and install the Half-Life Dedicated Server, which also includes all files needed by a HLTV proxy.
|
||||
This isn't needed if Half-Life is already installed.
|
||||
|
||||
Start the HLTV application (HL icon with a small camera) and the HLTV console will open, showing some initialization messages
|
||||
(if that takes a long time, HLTV maybe can't resolve some IP addresses, then start HLTV with the '-nodns' command line option).
|
||||
Then the console is ready to accept your commands, here we use '>' as the console prompt.
|
||||
|
||||
First give your HLTV proxy an unique name:
|
||||
<pre>
|
||||
>name "My HLTV Proxy"
|
||||
</pre>
|
||||
|
||||
Let's assume you have started the proxy on host `192.168.1.2` and the game server,
|
||||
you want to spectate is running on host `192.168.1.3:27015`.
|
||||
|
||||
Then connect the HLTV proxy to this game server by typing:
|
||||
<pre>
|
||||
>connect 192.168.1.3:27015
|
||||
</pre>
|
||||
|
||||
After a few seconds HLTV will be fully connected and ready to serve spectator clients.
|
||||
Use the 'status' command to verify that the HLTV proxy has connected properly:
|
||||
<pre>
|
||||
>status
|
||||
--- HLTV Status ---
|
||||
Online 00:23, FPS 79.0, Version 2435 (Win32)
|
||||
Local IP 192.168.1.2:27020, Network In 1.7, Out 1.0, Loss 0.00
|
||||
Local Slots 128, Spectators 0, Proxies 0
|
||||
Total Slots 128, Spectators 0, Proxies 1
|
||||
Source Game Server 192.168.1.3:27015, Delay 30
|
||||
Server Name "Half-Life dedicated server"
|
||||
Time 01:35, Game "valve", Map "maps/rapidcore.bsp", Players 1
|
||||
</pre>
|
||||
|
||||
The 'status' command shows your own IP address, HLTV system cycles per second, total incoming and outgoing network traffic in `kB/sec`.
|
||||
Local slot and spectator numbers your HLTV proxy is providing, total numbers are the sum of all slots & spectators on all proxies broadcasting this game.
|
||||
The game source can be a game server, another HLTV proxy or a demo file.
|
||||
|
||||
### Recording HLTV demos
|
||||
HLTV demo files are like normal recorded games in Half-Life, but you can choose any view point,
|
||||
view mode or player to chase during replay. To play back a HLTV demo, a HLTV proxy is not needed.
|
||||
Just start Half-Life and type in console `playdemo <demoname>` or `viewdemo <demoname>`
|
||||
(viewdemo offers more options during playback like fast forward/backward, pause & slowmotion).
|
||||
To record a HLTV demo, connect the proxy to a game server (see [Broadcasting Games](#broadcasting-games)) and type in console:
|
||||
|
||||
<pre>
|
||||
>record <name>
|
||||
</pre>
|
||||
|
||||
All games will be recorded after issuing this command. The demo files will be saved in the current Mod directory, e.g. `\cstrike`.
|
||||
All demo files have a special naming convention `<name>-<YYMMDDhhmm>-<map>.dem`, including the given name, date/time and map name.
|
||||
Demo files record the same data as send to spectator clients. That means also, the demo file records the game with the same delay as used for spectators.
|
||||
To verify, that a demo file is recorded use the `status` command. The recording may be stopped with `stoprecording`.
|
||||
|
||||
Sometimes a HLTV broadcast is not wanted and the HLTV proxy is only used to record a demo file.
|
||||
In this case, some HLTV settings should be made to gain optimal recording results:
|
||||
<pre>
|
||||
>maxclients 0 // don't allow any spectator clients
|
||||
>delay 0 // no game stream delay
|
||||
>rate 10000 // maximum data rate
|
||||
>updaterate 20 // standard update rate
|
||||
>nomaster 1 // don't register at master servers
|
||||
</pre>
|
||||
|
||||
### Larger Broadcasts
|
||||
Setting up a HLTV network that can handle a larger number of spectators (>1000) is a difficult and time consuming task.
|
||||
The following guide should help to configure and run such a HLTV network. One of the most important rule should be `Quality, not Quantity`.
|
||||
It's better to offer a smaller number of spectator slots, than operating at the maximum bandwidth limit, thus all spectators would suffer from lags and timeouts.
|
||||
Check carefully your available bandwidth capacity and calculate how many spectators can be handled by your HLTV servers.
|
||||
The average bandwidth demand per spectator is between 2 and 3 KB/sec and depends on the current mod, map and number of players.
|
||||
CPU and RAM shouldn't be a bottleneck on modern PC systems.
|
||||
|
||||
|
||||
This list for common Internet connection types gives a feeling, how bandwidth demanding HLTV can be:
|
||||
<pre>
|
||||
- ISDN 64 Kbps : 2 spectators
|
||||
- DSL 128 Kbps (upstream) : 5 spectators
|
||||
- T1 1.5 Mbps : 75 spectators
|
||||
- LAN 10 Mbps : 500 spectators
|
||||
- T3 75 Mbps : 4000 spectators
|
||||
</pre>
|
||||
|
||||
Use the `maxclients` command to set how many clients should be accepted by a HLTV proxy.
|
||||
Make sure that the `maxrate` variable is set too a reasonable value, e.g. `3500 kB/sec`. Lower values are possible,
|
||||
but make sure spectators don't get too much `choke` during a running game. The `maxrate` command doesn't effect
|
||||
the bandwidth limit between HLTV proxies, only for spectator clients.
|
||||
To lower the general bandwidth demand, you can turn off the internal HLTV chat (`chatmode 0`) or decrease the game
|
||||
update rate from the default value 20 to 10 (`updaterate 10`). A lower update rate may save up to 25% network traffic
|
||||
and is an acceptable tradeoff in this case since spectators doesn't need a high update rate like real players does.
|
||||
|
||||
A very common setup for large broadcasts is to use 2 dedicated HLTV servers to create a private and a public HLTV segment.
|
||||
Let's assume the game server is in a closed LAN and not accessible from outside.
|
||||
This ensures a maximum security against attacks (DOS etc) from outside. The HLTV master server is started within the
|
||||
LAN and it's IP address should be kept secret. The second HLTV server is started outside the LAN with a global IP
|
||||
and is connected to the HLTV master server. This second HLTV server is the public HLTV dispatcher, which IP address is given to the audience.
|
||||
Any relay proxies are connected to this HLTV dispatcher. Thus the HLTV master server is in a secure LAN environment
|
||||
and can be used for demo recording or for HL clients serving video projectors.
|
||||
Spectators connect to the HLTV dispatcher and are relayed through the HLTV network to a relay proxy with a low usage.
|
||||
Thus the total network load is balanced between all connected HLTV proxies.
|
||||
|
||||
<pre>
|
||||
Private LAN Public Internet
|
||||
-> HLTV Proxy 1
|
||||
HL Server -> HLTV Master -> HLTV Dispatcher -> HLTV Proxy 2
|
||||
-> HLTV Proxy 3
|
||||
</pre>
|
||||
|
||||
The configuration files of HLTV master and HLTV dispatcher are different:
|
||||
|
||||
**master.cfg:**
|
||||
<pre>
|
||||
nomaster 1 // don't register at WON master servers
|
||||
proxypassword MyPWD // protect HLTV server
|
||||
publicgame 0 // don't show game server IP
|
||||
dispatchmode 0 // don't dispatch spectators
|
||||
</pre>
|
||||
|
||||
**dispatcher.cfg:**
|
||||
<pre>
|
||||
forcemaster 1 // register at WON master servers
|
||||
publicgame 0 // don't show game server IP
|
||||
dispatchmode 2 // dispatch all clients to other proxies
|
||||
hostname MyGame // public HLTV server name
|
||||
</pre>
|
||||
|
||||
If you're running 3 or more HLTV servers in total, it's a good idea to use RCON to manage them via a single server admin tool.
|
||||
To enable RCON on a HLTV server an `adminpassword` must been set.
|
||||
Also `proxypassword` should be set to ensure only known HLTV providers can connect to your HLTV network.
|
||||
Otherwise anybody can connect with slow HLTV proxies and disturb your network load balancing.
|
||||
|
||||
### HLTV Configuration
|
||||
|
||||
A short note about console command syntax.
|
||||
A command may have one or more parameters. Parameters in brackets `[]` are optional.
|
||||
|
||||
Common used parameters are:
|
||||
<pre>
|
||||
<string> : text, must be in quotes if text contains spaces "My Name"
|
||||
<n> : a whole number, e.g. 42
|
||||
<f> : a floating point number, e.g. 4.2
|
||||
<IP:Port> : an IP address, e.g. 192.168.130.42:27020
|
||||
<a|b|c> : a set of options, a or b or c
|
||||
</pre>
|
||||
|
||||
`NOTE:` Any of these special characters <, >, |, [ or ] are not part of the final command as typed in the console.
|
||||
Lots of these commands are boolean switches, were 1 is meaning ON and 0 is respectively OFF.
|
||||
|
||||
|
||||
| HLTV Commands | Arguments | Description |
|
||||
| :---------------------------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ |
|
||||
| connect | IP:Port | Connect HLTV proxy to game server. (default port `27015`) |
|
||||
| disconnect | - | Disconnects proxy from server, but doesn't stop the broadcast.<br />All spectator clients stay connected. |
|
||||
| stop | [ `text` ] | Disconnects from server, disconnects all clients and stops demo recording.<br />Optional goodbye message. |
|
||||
| quit | 1 | Quits the HLTV process. |
|
||||
| retry | 0 | Retries the last server connection. |
|
||||
| autoretry | `0/1` | If enabled, proxy will retry connection to server.<br />If connection was interrupted for any reason. |
|
||||
| name | `text` | Sets the HLTV proxy scoreboard name. |
|
||||
| hostname | `text` | Sets the HLTV host name for game browser list. |
|
||||
| serverpassword | `text` | Sets the game server password. |
|
||||
| adminpassword | `text` | Sets password for RCON & commentator. |
|
||||
| proxypassword | `text` | Sets password for other relay proxies. |
|
||||
| spectatorpassword | `text` | Sets spectator password. Will also exclude proxy from global load balancing. |
|
||||
| clients | - | Lists connected spectator clients. |
|
||||
| proxies | - | Lists connected relay proxies. |
|
||||
| players | - | Lists players on game server. |
|
||||
| kick | `ID` | Kicks a spectator client from proxy. |
|
||||
| bann | `IP` | Banns an IP address. (completely ignored) |
|
||||
| clearbanns | - | Removes all IPs from bann list. |
|
||||
| say | `text` | Sends a text message to game server. (chat with players) |
|
||||
| msg | `text` [ `duration` `pos x` `pos y` `rgba` ] | Sends a text message to all spectators as big HUD text. |
|
||||
| localmsg | `text` [ `duration` `pos x` `pos y` `rgba` ] | Same as msg, but only seen by local clients. |
|
||||
| servercmd | `string` | Forwards console command to game server. |
|
||||
| clientcmd | `group` `string` | Forwards a console command to all clients of given group:<br />`1` SPECTATORS<br />`2` PROXIES<br />`3` ALL |
|
||||
| loopcmd | `id` `n` `string` | Loopcmd will execute `string` every `n` seconds.<br />`<id>` is a number between `1` and `64` to identify this loopcmd.<br />`loopcmd <id> none` will disable a looping command again.<br />loopcmd without any parameter will list any command currently in the list. |
|
||||
| signoncommands | `string` | Console commands that will be executed by local<br />spectator clients after connection is established.<br />Commands may be separated by semicolons. |
|
||||
| maxclients | `n` | Set spectator number limit for this proxy. (default `128`) |
|
||||
| delay | `n` | Delays the game stream for n seconds on the Master Proxy.<br />The default value is 30 seconds to avoid cheating.<br />If the delay is set to a value below 10 seconds (e.g. 0),<br />the auto director function will be disabled. |
|
||||
| rate | `n` | Bandwidth rate the game server sends data to the proxy. |
|
||||
| updaterate | `n` | Game updates per seconds send from server to proxy. |
|
||||
| maxrate | `n` | Sets the maximum bandwidth rate for spectator clients. |
|
||||
| maxloss | `f` | Sets the acceptable packet loss rate, default value is 0.05 (5%).<br />If packet loss is higher, new spectator clients will be rejected. |
|
||||
| maxqueries | `n` | Maximum of status queries per second requested by server browsers. |
|
||||
| dispatchmode | `0/1/2` | `0` (OFF) Won't redirect any clients.<br />`1` (AUTO) Will redirect connecting clients to other<br />proxies balancing work load between all proxies.<br />`2` (ALWAYS) Any spectator clients will be redirected,<br />so this proxy serves only as dispatcher.<br /> |
|
||||
| publicgame | `0/1` | `0` Private.<br />`1` Game server IP will be visible to spectators and 'joingame' is allowed. |
|
||||
| offlinetext | `string` | Info text clients will see as reject reason if HLTV isn't broadcasting yet. |
|
||||
| chatmode | `0/1/2` | `0` Spectators can't chat.<br />`1` Only spectators connected to the same proxy can see their chat messages.<br />`2` All spectators can chat between each other (then Master and all Relay proxies must have set chatmode 2).<br /> |
|
||||
| bannerfile | `file` | Specifies a TGA file (`RGBA`) that will be shown as logo in spectator GUI. |
|
||||
| ping | `host:port` | Pings a HL server on the given port. (default `27015`) |
|
||||
| nomaster | `0/1` | `0` Disabled.<br />`1` Proxy won't register at WON master servers. |
|
||||
| forcemaster | `0/1` | `0` Disabled.<br />`1` Proxy will register at WON master server. |
|
||||
| heartbeat | - | Sends manually a status packet to WON master servers. |
|
||||
| region | `n` | Set the region your HLTV proxy is located in. |
|
||||
| rcon | `string` | Sends a remote control command to other servers. |
|
||||
| rconaddress | `IP:Port` | Sets the remote control target address. |
|
||||
| rconpassword | `string` | Sets the password for the remote controlled host. |
|
||||
| cheeringthreshold | `f` | Number of cheering players must be above this threshold to play<br />the cheering sound. (by default `0.25`). |
|
||||
| blockvoice | `0/1` | `0` Disabled.<br />`1` All incoming voice data is blocked.<br />This is useful to override incoming voice commentators<br />or player voice with own commentators voice. |
|
||||
| cmdlist | - | Shows all registered proxy commands. |
|
||||
| logfile | `0/1` | Starts/stops console logging in `logfile<date>.log` |
|
||||
| status | - | Shows proxy status information. |
|
||||
| modules | - | Shows all loaded HLTV modules and versions. |
|
||||
| exec | `filename` | Executes a `.cfg` file. |
|
||||
| echo | `string` | Prints a text to HLTV console. |
|
||||
| developer | `0/1` | `0` Disabled.<br />`1` Additional debug messages are shown in developer mode. |
|
||||
| record | `filename` | Records all following games to demo files<br />using name syntax `filename-<date>-<map>.dem` |
|
||||
| stoprecording | - | Stops recording a demo file. |
|
||||
| playdemo | `filename` | Starts broadcasting a demo file. |
|
||||
|
||||
The console does auto-completion by hitting `TAB`.
|
||||
All commands in the config file `hltv.cfg` are executed during startup.
|
||||
|
||||
Some parameters can only be set in the command line:
|
||||
<pre>
|
||||
-port <n> - sets the HLTV proxy port that spectators connect to (default "27020" )
|
||||
-ip <IP> - forces the proxy to use this IP on a multihomed host
|
||||
-nodns - disables any DNS resolving (useful for LAN proxies)
|
||||
-maxfps <n> - sets maximum system cycles per seconds (default "100")
|
||||
-highpriority - starts the HLTV proxy as high priority process
|
||||
-multicastttl <n> - sets the Time-To-Live value for multicast packets
|
||||
-steam - proxy enables special Steam support
|
||||
-dev - developer mode
|
||||
</pre>
|
||||
|
||||
These parameters cannot be changed during runtime, thus they can't be used in config files.<br />
|
||||
All console commands can be used in the command line, if a `+` is prepended to them, for example:
|
||||
<pre>
|
||||
hltv.exe +connect localhost:27015 -port 27021
|
||||
</pre>
|
||||
|
||||
A Half-Life server can set sv_proxies `n`, to determine how many proxies are allowed to connect.<br />
|
||||
If HLTV proxies should be forbidden, set it to `0`, otherwise `1` to allow for a Master Proxy.<br />
|
||||
Other values are experimental.
|
||||
|
||||
Copyright © 2003, `Valve LLC`, All rights reserved.
|
13
rehlds/HLTV/build.gradle
Normal file
13
rehlds/HLTV/build.gradle
Normal file
@ -0,0 +1,13 @@
|
||||
evaluationDependsOn(':rehlds/HLTV/Console');
|
||||
evaluationDependsOn(':rehlds/HLTV/Core');
|
||||
evaluationDependsOn(':rehlds/HLTV/DemoPlayer');
|
||||
evaluationDependsOn(':rehlds/HLTV/Director');
|
||||
evaluationDependsOn(':rehlds/HLTV/Proxy');
|
||||
|
||||
task build {
|
||||
dependsOn project(':rehlds/HLTV/Console').tasks.build,
|
||||
project(':rehlds/HLTV/Core').tasks.build,
|
||||
project(':rehlds/HLTV/DemoPlayer').tasks.build,
|
||||
project(':rehlds/HLTV/Director').tasks.build,
|
||||
project(':rehlds/HLTV/Proxy').tasks.build
|
||||
}
|
776
rehlds/HLTV/common/BaseClient.cpp
Normal file
776
rehlds/HLTV/common/BaseClient.cpp
Normal file
@ -0,0 +1,776 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
bool BaseClient::Init(IBaseSystem *system, int serial, char *name)
|
||||
{
|
||||
if (!BaseSystemModule::Init(system, serial, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
strcopy(m_Name, CLIENT_INTERFACE_VERSION);
|
||||
}
|
||||
|
||||
SetState(CLIENT_INITIALIZING);
|
||||
|
||||
m_ClientType = TYPE_CLIENT;
|
||||
m_World = nullptr;
|
||||
m_Socket = nullptr;
|
||||
|
||||
m_VoiceEnabled = false;
|
||||
m_VoiceQuery = false;
|
||||
m_Userinfo.SetMaxSize(MAX_USER_INFO);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BaseClient::RunFrame(double time)
|
||||
{
|
||||
BaseSystemModule::RunFrame(time);
|
||||
|
||||
if (m_ClientState != CLIENT_DISCONNECTED && m_ClientChannel.IsTimedOut()) {
|
||||
m_System->Printf("Client %s timed out.\n", m_ClientChannel.GetTargetAddress()->ToString());
|
||||
Disconnect("Timed out.\n");
|
||||
}
|
||||
|
||||
if (m_ClientState != CLIENT_DISCONNECTED && m_ClientChannel.IsCrashed()) {
|
||||
m_System->Printf("Client %s netchannel crashed.\n", m_ClientChannel.GetTargetAddress()->ToString());
|
||||
Disconnect("Netchannel crashed.\n");
|
||||
}
|
||||
|
||||
int numPackets = 0;
|
||||
NetPacket *packet;
|
||||
while ((packet = m_ClientChannel.GetPacket()))
|
||||
{
|
||||
if (packet->connectionless)
|
||||
{
|
||||
m_Socket->AddPacket(packet);
|
||||
}
|
||||
else if (numPackets < 32)
|
||||
{
|
||||
numPackets++;
|
||||
ProcessMessage(packet);
|
||||
}
|
||||
|
||||
m_ClientChannel.FreePacket(packet);
|
||||
}
|
||||
|
||||
// process state
|
||||
switch (m_ClientState)
|
||||
{
|
||||
case CLIENT_RUNNING:
|
||||
{
|
||||
if (m_World->IsActive() && m_ClientChannel.IsReadyToSend()) {
|
||||
SendDatagram();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLIENT_DISCONNECTED:
|
||||
ShutDown();
|
||||
break;
|
||||
case CLIENT_INITIALIZING:
|
||||
case CLIENT_CONNECTING:
|
||||
/* do nothing */
|
||||
break;
|
||||
default:
|
||||
case CLIENT_UNDEFINED:
|
||||
m_System->Errorf("Client::RunFrame: not valid state.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseClient::ShutDown()
|
||||
{
|
||||
if (m_State == MODULE_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ClientState != CLIENT_DISCONNECTED) {
|
||||
Disconnect("Connection dropped (hard).\n");
|
||||
}
|
||||
|
||||
m_ClientChannel.Close();
|
||||
BaseSystemModule::ShutDown();
|
||||
}
|
||||
|
||||
bool BaseClient::Connect(INetSocket *socket, NetAddress *adr, char *userinfo)
|
||||
{
|
||||
if (!userinfo || !adr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ClientType = TYPE_CLIENT;
|
||||
m_Socket = socket;
|
||||
|
||||
if (!adr->Equal(m_ClientChannel.GetTargetAddress())) {
|
||||
m_ClientChannel.Create(m_System, m_Socket, adr);
|
||||
} else {
|
||||
m_ClientChannel.Clear();
|
||||
m_ClientChannel.Reset();
|
||||
}
|
||||
|
||||
SetState(CLIENT_CONNECTING);
|
||||
m_ClientChannel.SetUpdateRate(20);
|
||||
m_ClientChannel.SetRate(20000);
|
||||
m_ClientChannel.SetConnected(1);
|
||||
|
||||
UpdateUserInfo(userinfo);
|
||||
m_ClientChannel.OutOfBandPrintf("%c0000000000000000", S2C_CONNECTION);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BaseClient::clc_func_s BaseClient::m_ClientFuncs[] = {
|
||||
{ clc_bad, "clc_bad", &BaseClient::ParseBad },
|
||||
{ clc_nop, "clc_nop", &BaseClient::ParseNop },
|
||||
{ clc_move, "clc_move", &BaseClient::ParseMove },
|
||||
{ clc_stringcmd, "clc_stringcmd", &BaseClient::ParseStringCmd },
|
||||
{ clc_delta, "clc_delta", &BaseClient::ParseDelta },
|
||||
{ clc_resourcelist, "clc_resourcelist", nullptr },
|
||||
{ clc_tmove, "clc_tmove", nullptr },
|
||||
{ clc_fileconsistency, "clc_fileconsistency", nullptr },
|
||||
{ clc_voicedata, "clc_voicedata", &BaseClient::ParseVoiceData },
|
||||
{ clc_hltv, "clc_hltv", &BaseClient::ParseHLTV },
|
||||
{ clc_cvarvalue, "clc_cvarvalue", &BaseClient::ParseCvarValue },
|
||||
{ clc_cvarvalue2, "clc_cvarvalue2", &BaseClient::ParseCvarValue2 },
|
||||
{ clc_endoflist, "End of List", nullptr },
|
||||
};
|
||||
|
||||
void BaseClient::ProcessMessage(NetPacket *packet)
|
||||
{
|
||||
m_ClientDelta = 0;
|
||||
m_DeltaFrameSeqNr = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (packet->data.IsOverflowed()) {
|
||||
m_System->Printf("Client::ProcessMessage: packet read overflow\n");
|
||||
Disconnect("Dropped due to bad message format!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
int cmd = packet->data.ReadByte();
|
||||
if (cmd == -1)
|
||||
break;
|
||||
|
||||
if (cmd < clc_bad || cmd > clc_cvarvalue2)
|
||||
{
|
||||
m_System->Printf("Client::ProcessMessage: unknown command char\n");
|
||||
Disconnect("Bad command character in client command");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_ClientFuncs[cmd].func) {
|
||||
m_System->Printf("TODO! Client::ProcessMessage: missing parsing routine for %s.\n", m_ClientFuncs[cmd].pszname);
|
||||
return;
|
||||
}
|
||||
|
||||
(this->*m_ClientFuncs[cmd].func)(packet);
|
||||
}
|
||||
}
|
||||
|
||||
char *BaseClient::GetClientName()
|
||||
{
|
||||
return m_ClientName;
|
||||
}
|
||||
|
||||
InfoString *BaseClient::GetUserInfo()
|
||||
{
|
||||
return &m_Userinfo;
|
||||
}
|
||||
|
||||
void BaseClient::Disconnect(const char *reason)
|
||||
{
|
||||
SetState(CLIENT_DISCONNECTED);
|
||||
|
||||
m_ClientChannel.m_reliableStream.WriteByte(svc_disconnect);
|
||||
m_ClientChannel.m_reliableStream.WriteString(reason ? reason : "");
|
||||
|
||||
m_ClientChannel.m_unreliableStream.WriteByte(svc_disconnect);
|
||||
m_ClientChannel.m_unreliableStream.WriteString(reason ? reason : "");
|
||||
m_ClientChannel.TransmitOutgoing();
|
||||
}
|
||||
|
||||
void BaseClient::ParseNop(NetPacket *packet)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void BaseClient::ParseBad(NetPacket *packet)
|
||||
{
|
||||
m_System->Printf("Client::ParseBad: bad command char\n");
|
||||
Disconnect("Bad command character in client command");
|
||||
}
|
||||
|
||||
void BaseClient::ParseStringCmd(NetPacket *packet)
|
||||
{
|
||||
char *string = packet->data.ReadString();
|
||||
ProcessStringCmd(string);
|
||||
}
|
||||
|
||||
BaseClient::LocalCommandID_s BaseClient::m_LocalCmdReg[] = {
|
||||
{ "name", CMD_ID_NAME, &BaseClient::CMD_Name },
|
||||
{ "spawn", CMD_ID_SPAWN, &BaseClient::CMD_Spawn },
|
||||
{ "new", CMD_ID_NEW, &BaseClient::CMD_New },
|
||||
{ "fullupdate", CMD_ID_FULLUPDATE, &BaseClient::CMD_FullUpdate },
|
||||
{ "dropclient", CMD_ID_DROPCLIENT, &BaseClient::CMD_DropClient },
|
||||
{ "dlfile", CMD_ID_DLFILE, &BaseClient::CMD_DownloadFile },
|
||||
{ "setinfo", CMD_ID_SETINFO, &BaseClient::CMD_SetInfo },
|
||||
{ "showinfo", CMD_ID_SHOWINFO, &BaseClient::CMD_ShowInfo },
|
||||
{ "sendents", CMD_ID_SENDENTS, &BaseClient::CMD_SendEntities },
|
||||
{ "VModEnable", CMD_ID_VMODENABLE, &BaseClient::CMD_VoiceModEnable },
|
||||
{ "vban", CMD_ID_VBAN, &BaseClient::CMD_VoiceBan },
|
||||
|
||||
// TODO: Pure function's, finish them.
|
||||
{ "sendres", CMD_ID_SENDERS, &BaseClient::CMD_SendResources },
|
||||
{ "ping", CMD_ID_PING, &BaseClient::CMD_RequestPing },
|
||||
{ "spectate", CMD_ID_SPECTATE, &BaseClient::CMD_Spectate },
|
||||
{ "spk", CMD_ID_SPK, &BaseClient::CMD_Spk },
|
||||
{ "pause", CMD_ID_PAUSE, &BaseClient::CMD_Pause },
|
||||
{ "unpause", CMD_ID_UNPAUSE, &BaseClient::CMD_UnPause },
|
||||
{ "setpause", CMD_ID_SETPAUSE, &BaseClient::CMD_SetPause }
|
||||
};
|
||||
|
||||
bool BaseClient::ProcessStringCmd(char *string)
|
||||
{
|
||||
TokenLine cmdLine;
|
||||
if (!cmdLine.SetLine(string)) {
|
||||
m_System->Printf("WARNING! BaseClient::ProcessStringCmd: string command too long.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char *cmd = cmdLine.GetToken(0);
|
||||
for (auto& local_cmd : m_LocalCmdReg)
|
||||
{
|
||||
if (!_stricmp(local_cmd.name, cmd)) {
|
||||
(this->*local_cmd.pfnCmd)(&cmdLine);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BaseClient::CMD_Name(TokenLine *cmd)
|
||||
{
|
||||
SetName(cmd->GetRestOfLine(1));
|
||||
}
|
||||
|
||||
void BaseClient::CMD_Spawn(TokenLine *cmd)
|
||||
{
|
||||
if (cmd->CountToken() != 3) {
|
||||
m_System->Printf("Client::ParseStringCmd: spawn is not valid\n");
|
||||
Disconnect("Spawn is not valid.");
|
||||
return;
|
||||
}
|
||||
|
||||
ReplySpawn(atoi(cmd->GetToken(1)), atoi(cmd->GetToken(2)));
|
||||
}
|
||||
|
||||
void BaseClient::CMD_New(TokenLine *cmd)
|
||||
{
|
||||
ReplyNew();
|
||||
}
|
||||
|
||||
void BaseClient::CMD_FullUpdate(TokenLine *cmd)
|
||||
{
|
||||
ReplyFullUpdate();
|
||||
}
|
||||
|
||||
void BaseClient::CMD_DropClient(TokenLine *cmd)
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
void BaseClient::CMD_DownloadFile(TokenLine *cmd)
|
||||
{
|
||||
DownloadFile(cmd->GetToken(1));
|
||||
}
|
||||
|
||||
void BaseClient::CMD_SetInfo(TokenLine *cmd)
|
||||
{
|
||||
if (cmd->CountToken() != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Userinfo.SetValueForKey(cmd->GetToken(1), cmd->GetToken(2));
|
||||
UpdateUserInfo();
|
||||
}
|
||||
|
||||
void BaseClient::CMD_ShowInfo(TokenLine *cmd)
|
||||
{
|
||||
InfoString info(MAX_INFO_STRING);
|
||||
|
||||
info.SetString(m_World->GetServerInfoString()->GetString());
|
||||
info.RemoveKey("proxy"); // remove proxy ip
|
||||
PrintfToClient("%s\n", info.GetString());
|
||||
}
|
||||
|
||||
void BaseClient::CMD_SendEntities(TokenLine *cmd)
|
||||
{
|
||||
m_System->DPrintf("Client fully connected.\n");
|
||||
SetState(CLIENT_RUNNING);
|
||||
}
|
||||
|
||||
void BaseClient::CMD_VoiceModEnable(TokenLine *cmd)
|
||||
{
|
||||
if (cmd->CountToken() != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_VoiceQuery = false;
|
||||
m_VoiceEnabled = atoi(cmd->GetToken(1)) ? true : false;
|
||||
UpdateVoiceMask(&m_ClientChannel.m_reliableStream);
|
||||
}
|
||||
|
||||
void BaseClient::CMD_VoiceBan(TokenLine *cmd)
|
||||
{
|
||||
if (cmd->CountToken() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i < cmd->CountToken(); i++)
|
||||
{
|
||||
uint32 mask = 0;
|
||||
sscanf(cmd->GetToken(i), "%x", &mask);
|
||||
|
||||
if (i <= VOICE_MAX_PLAYERS_DW) {
|
||||
m_SentBanMask.SetDWord(i - 1, mask);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVoiceMask(&m_ClientChannel.m_reliableStream);
|
||||
}
|
||||
|
||||
void BaseClient::CMD_SendResources(TokenLine *cmd) { /* do nothing */ }
|
||||
void BaseClient::CMD_RequestPing(TokenLine *cmd) { /* do nothing */ }
|
||||
void BaseClient::CMD_Spectate(TokenLine *cmd) { /* do nothing */ }
|
||||
void BaseClient::CMD_Spk(TokenLine *cmd) { /* do nothing */ }
|
||||
void BaseClient::CMD_Pause(TokenLine *cmd) { /* do nothing */ }
|
||||
void BaseClient::CMD_UnPause(TokenLine *cmd) { /* do nothing */ }
|
||||
void BaseClient::CMD_SetPause(TokenLine *cmd) { /* do nothing */ }
|
||||
|
||||
void BaseClient::UpdateUserInfo(char *userinfostring)
|
||||
{
|
||||
char buffer[1024];
|
||||
char *string;
|
||||
|
||||
if (userinfostring) {
|
||||
m_Userinfo.SetString(userinfostring);
|
||||
}
|
||||
|
||||
strcopy(buffer, m_Userinfo.ValueForKey("name"));
|
||||
|
||||
SetName(buffer);
|
||||
m_ClientType = atoi(m_Userinfo.ValueForKey("*hltv"));
|
||||
|
||||
if (m_ClientType < TYPE_CLIENT) {
|
||||
m_System->DPrintf("WARNING! BaseClient::UpdateUserInfo: invalid client ype %i\n", m_ClientType);
|
||||
m_ClientType = TYPE_CLIENT;
|
||||
}
|
||||
|
||||
string = m_Userinfo.ValueForKey("rate");
|
||||
if (*string) {
|
||||
m_ClientChannel.SetRate(atoi(string));
|
||||
}
|
||||
|
||||
string = m_Userinfo.ValueForKey("cl_updaterate");
|
||||
if (*string) {
|
||||
m_ClientChannel.SetUpdateRate(atoi(string));
|
||||
}
|
||||
}
|
||||
|
||||
void BaseClient::PrintfToClient(char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
m_ClientChannel.m_reliableStream.WriteByte(svc_print);
|
||||
m_ClientChannel.m_reliableStream.WriteString(string);
|
||||
}
|
||||
|
||||
void BaseClient::ReplySpawn(int spawncount, int crcMap)
|
||||
{
|
||||
BitBuffer msg(MAX_POSSIBLE_MSG);
|
||||
|
||||
m_CRC_Value = crcMap;
|
||||
COM_UnMunge2((unsigned char *)&m_CRC_Value, 4, (-1 - m_World->GetServerCount()) & 0xFF);
|
||||
|
||||
if (m_World->GetServerCount() != spawncount) {
|
||||
ReplyNew();
|
||||
return;
|
||||
}
|
||||
|
||||
m_World->WriteSigonData(&msg);
|
||||
WriteSpawn(&msg);
|
||||
|
||||
m_ClientChannel.CreateFragmentsFromBuffer(msg.GetData(), msg.CurrentSize(), FRAG_NORMAL_STREAM, nullptr);
|
||||
m_ClientChannel.FragSend();
|
||||
m_LastFrameSeqNr = 0;
|
||||
}
|
||||
|
||||
void BaseClient::ReplyNew()
|
||||
{
|
||||
BitBuffer msg(MAX_POSSIBLE_MSG);
|
||||
|
||||
Reset();
|
||||
m_World->WriteNewData(&msg);
|
||||
|
||||
m_ClientChannel.CreateFragmentsFromBuffer(msg.GetData(), msg.CurrentSize(), FRAG_NORMAL_STREAM, nullptr);
|
||||
m_ClientChannel.FragSend();
|
||||
msg.Free();
|
||||
}
|
||||
|
||||
void BaseClient::ReplyFullUpdate()
|
||||
{
|
||||
BitBuffer msg(1024 * 9);
|
||||
for (int i = 0; i < m_World->GetMaxClients(); i++) {
|
||||
m_World->WriteClientUpdate(&msg, i);
|
||||
}
|
||||
|
||||
m_ClientChannel.CreateFragmentsFromBuffer(msg.GetData(), msg.CurrentSize(), FRAG_NORMAL_STREAM, nullptr);
|
||||
m_ClientChannel.FragSend();
|
||||
}
|
||||
|
||||
void BaseClient::SetState(ClientState newState)
|
||||
{
|
||||
if (newState == m_ClientState)
|
||||
return;
|
||||
|
||||
bool stateError = false;
|
||||
switch (newState)
|
||||
{
|
||||
case CLIENT_INITIALIZING:
|
||||
break;
|
||||
case CLIENT_CONNECTING:
|
||||
{
|
||||
if (m_ClientState != CLIENT_INITIALIZING
|
||||
&& m_ClientState != CLIENT_RUNNING) {
|
||||
stateError = true;
|
||||
}
|
||||
|
||||
m_ClientChannel.SetKeepAlive(true);
|
||||
m_ClientChannel.SetTimeOut(60);
|
||||
break;
|
||||
}
|
||||
case CLIENT_RUNNING:
|
||||
{
|
||||
if (m_ClientState != CLIENT_CONNECTING) {
|
||||
stateError = true;
|
||||
}
|
||||
|
||||
m_ClientChannel.SetKeepAlive(false);
|
||||
m_ClientChannel.SetTimeOut(30);
|
||||
break;
|
||||
}
|
||||
case CLIENT_DISCONNECTED:
|
||||
{
|
||||
m_ClientChannel.SetKeepAlive(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
stateError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (stateError)
|
||||
{
|
||||
m_System->Errorf("Client::SetState: not valid m_ClientState (%i -> %i).\n", m_ClientState, newState);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ClientState = newState;
|
||||
}
|
||||
|
||||
void BaseClient::WriteSpawn(BitBuffer *stream)
|
||||
{
|
||||
stream->WriteByte(svc_time);
|
||||
stream->WriteFloat(1);
|
||||
|
||||
for (int i = 0; i < m_World->GetMaxClients(); i++) {
|
||||
m_World->WriteClientUpdate(stream, i);
|
||||
}
|
||||
|
||||
m_World->WriteLightStyles(stream);
|
||||
|
||||
stream->WriteByte(svc_signonnum);
|
||||
stream->WriteByte(1);
|
||||
}
|
||||
|
||||
void BaseClient::WriteDatagram(double time, frame_t *frame)
|
||||
{
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_LastFrameSeqNr || m_LastFrameSeqNr > frame->seqnr) {
|
||||
m_LastFrameSeqNr = frame->seqnr - 1;
|
||||
m_ClientDelta = 0;
|
||||
m_DeltaFrameSeqNr = 0;
|
||||
}
|
||||
|
||||
if (m_LastFrameSeqNr >= frame->seqnr && m_ClientChannel.GetIdleTime() <= 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ClientChannel.m_unreliableStream.WriteByte(svc_time);
|
||||
m_ClientChannel.m_unreliableStream.WriteFloat(float(time));
|
||||
m_World->WriteFrame(frame, m_LastFrameSeqNr, &m_ClientChannel.m_reliableStream, &m_ClientChannel.m_unreliableStream, m_DeltaFrameSeqNr, m_ClientDelta, IsHearingVoices());
|
||||
|
||||
if (m_VoiceQuery) {
|
||||
QueryVoiceEnabled(&m_ClientChannel.m_unreliableStream);
|
||||
}
|
||||
|
||||
if (m_ClientChannel.m_reliableStream.IsOverflowed()) {
|
||||
Disconnect("Reliable data stream overflow.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ClientChannel.m_unreliableStream.IsOverflowed()) {
|
||||
m_System->DPrintf("Unreliable data stream overflow.\n");
|
||||
m_ClientChannel.m_unreliableStream.Clear();
|
||||
m_LastFrameSeqNr = 0;
|
||||
}
|
||||
|
||||
m_LastFrameSeqNr = frame->seqnr;
|
||||
m_SeqNrMap[m_ClientChannel.m_outgoing_sequence & 0xFF] = frame->seqnr;
|
||||
m_ClientChannel.TransmitOutgoing();
|
||||
}
|
||||
|
||||
void BaseClient::ParseDelta(NetPacket *packet)
|
||||
{
|
||||
if (m_ClientState != CLIENT_RUNNING) {
|
||||
packet->data.SkipBytes(1);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ClientDelta = packet->data.ReadByte();
|
||||
m_DeltaFrameSeqNr = m_SeqNrMap[m_ClientDelta];
|
||||
}
|
||||
|
||||
char *BaseClient::GetStatusLine()
|
||||
{
|
||||
float in, out;
|
||||
static char string[256];
|
||||
|
||||
m_ClientChannel.GetFlowStats(&in, &out);
|
||||
_snprintf(string, sizeof(string),
|
||||
"ID: %i, Name \"%s\", Time %s, IP %s, In %.2f, Out %.2f.\n",
|
||||
GetSerial(),
|
||||
m_ClientName,
|
||||
COM_FormatTime(float(m_SystemTime - m_ClientChannel.m_connect_time)),
|
||||
m_ClientChannel.GetTargetAddress()->ToString(),
|
||||
in,
|
||||
out
|
||||
);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
void BaseClient::SetWorld(IWorld *world)
|
||||
{
|
||||
if (m_World && m_World != world) {
|
||||
Reconnect();
|
||||
}
|
||||
|
||||
m_World = world;
|
||||
}
|
||||
|
||||
void BaseClient::Reconnect()
|
||||
{
|
||||
Reset();
|
||||
m_ClientChannel.m_reliableStream.WriteByte(svc_stufftext);
|
||||
m_ClientChannel.m_reliableStream.WriteString("reconnect\n");
|
||||
}
|
||||
|
||||
bool BaseClient::IsActive()
|
||||
{
|
||||
return (m_ClientState == CLIENT_RUNNING);
|
||||
}
|
||||
|
||||
void BaseClient::ParseVoiceData(NetPacket *packet)
|
||||
{
|
||||
int nDataLength = packet->data.ReadShort();
|
||||
packet->data.SkipBytes(nDataLength);
|
||||
}
|
||||
|
||||
void BaseClient::ParseMove(NetPacket *packet)
|
||||
{
|
||||
int nDataLength = packet->data.ReadByte();
|
||||
packet->data.SkipBytes(nDataLength + 1);
|
||||
}
|
||||
|
||||
void BaseClient::SetName(char *newName)
|
||||
{
|
||||
char temp[32];
|
||||
COM_RemoveEvilChars(newName);
|
||||
COM_TrimSpace(newName, temp);
|
||||
|
||||
if (strlen(temp) > sizeof(temp) - 1) {
|
||||
temp[sizeof(temp) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (!temp[0] || !_stricmp(temp, "console")) {
|
||||
strcpy(temp, "unnamed");
|
||||
}
|
||||
|
||||
strcopy(m_ClientName, temp);
|
||||
m_Userinfo.SetValueForKey("name", m_ClientName);
|
||||
}
|
||||
|
||||
void BaseClient::ParseHLTV(NetPacket *packet)
|
||||
{
|
||||
Disconnect("TODO Client::ParseHLTV: Invalid client command.\n");
|
||||
}
|
||||
|
||||
void BaseClient::ParseCvarValue(NetPacket *packet)
|
||||
{
|
||||
packet->data.ReadString();
|
||||
}
|
||||
|
||||
void BaseClient::ParseCvarValue2(NetPacket *packet)
|
||||
{
|
||||
packet->data.ReadWord();
|
||||
packet->data.ReadString();
|
||||
packet->data.ReadString();
|
||||
}
|
||||
|
||||
void BaseClient::QueryVoiceEnabled(BitBuffer *stream)
|
||||
{
|
||||
int reqState = m_World->FindUserMsgByName("ReqState");
|
||||
if (!reqState || !m_World->IsVoiceEnabled())
|
||||
return;
|
||||
|
||||
stream->WriteByte(reqState);
|
||||
}
|
||||
|
||||
void BaseClient::UpdateVoiceMask(BitBuffer *stream)
|
||||
{
|
||||
int voiceMask = m_World->FindUserMsgByName("VoiceMask");
|
||||
if (!voiceMask) {
|
||||
m_System->DPrintf("WARNING! Client::UpdateVoiceMask(): could find User Msg VoiceMaks.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_World->IsVoiceEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CPlayerBitVec gameRulesMask;
|
||||
gameRulesMask[m_World->GetSlotNumber()] = !!m_VoiceEnabled;
|
||||
|
||||
if (gameRulesMask != m_SentGameRulesMask || m_BanMask != m_SentBanMask)
|
||||
{
|
||||
m_SentGameRulesMask = gameRulesMask;
|
||||
m_SentBanMask = m_BanMask;
|
||||
|
||||
stream->WriteByte(voiceMask);
|
||||
for (int dw = 0; dw < VOICE_MAX_PLAYERS_DW; dw++)
|
||||
{
|
||||
stream->WriteLong(gameRulesMask.GetDWord(dw));
|
||||
stream->WriteLong(m_BanMask.GetDWord(dw));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseClient::IsHearingVoices()
|
||||
{
|
||||
return m_BanMask[m_World->GetSlotNumber()] ? true : false;
|
||||
}
|
||||
|
||||
bool BaseClient::HasChatEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void BaseClient::DownloadFile(char *fileName)
|
||||
{
|
||||
if (!fileName || !fileName[0])
|
||||
return;
|
||||
|
||||
DownloadFailed(fileName);
|
||||
}
|
||||
|
||||
void BaseClient::DownloadFailed(char *fileName)
|
||||
{
|
||||
if (!fileName || !fileName[0])
|
||||
return;
|
||||
|
||||
m_ClientChannel.m_reliableStream.WriteByte(svc_filetxferfailed);
|
||||
m_ClientChannel.m_reliableStream.WriteString(fileName);
|
||||
}
|
||||
|
||||
void BaseClient::Send(unsigned char *data, int length, bool isReliable)
|
||||
{
|
||||
if (isReliable)
|
||||
m_ClientChannel.m_reliableStream.WriteBuf(data, length);
|
||||
else
|
||||
m_ClientChannel.m_unreliableStream.WriteBuf(data, length);
|
||||
}
|
||||
|
||||
NetAddress *BaseClient::GetAddress()
|
||||
{
|
||||
return m_ClientChannel.GetTargetAddress();
|
||||
}
|
||||
|
||||
int BaseClient::GetClientType()
|
||||
{
|
||||
return m_ClientType;
|
||||
}
|
||||
|
||||
char *BaseClient::GetType()
|
||||
{
|
||||
return CLIENT_INTERFACE_VERSION;
|
||||
}
|
||||
|
||||
void BaseClient::SendDatagram()
|
||||
{
|
||||
frame_t *frame = m_World->GetLastFrame();
|
||||
if (frame) {
|
||||
WriteDatagram(frame->time, frame);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseClient::Reset()
|
||||
{
|
||||
SetState(CLIENT_CONNECTING);
|
||||
|
||||
m_LastFrameSeqNr = 0;
|
||||
m_DeltaFrameSeqNr = 0;
|
||||
m_ClientDelta = 0;
|
||||
|
||||
memset(m_SeqNrMap, 0, sizeof(m_SeqNrMap));
|
||||
m_VoiceQuery = true;
|
||||
m_ClientChannel.Clear();
|
||||
}
|
176
rehlds/HLTV/common/BaseClient.h
Normal file
176
rehlds/HLTV/common/BaseClient.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IClient.h>
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <game_shared/voice_common.h>
|
||||
|
||||
#include "InfoString.h"
|
||||
#include "NetChannel.h"
|
||||
#include "BaseSystemModule.h"
|
||||
|
||||
class TokenLine;
|
||||
class BaseClient: public IClient, public BaseSystemModule {
|
||||
public:
|
||||
BaseClient() {}
|
||||
virtual ~BaseClient() {}
|
||||
|
||||
virtual bool Init(IBaseSystem *system, int serial, char *name);
|
||||
virtual void RunFrame(double time);
|
||||
virtual char *GetStatusLine();
|
||||
virtual char *GetType();
|
||||
virtual void ShutDown();
|
||||
virtual bool Connect(INetSocket *socket, NetAddress *adr, char *userinfo);
|
||||
virtual void Disconnect(const char *reason = nullptr);
|
||||
virtual void Reconnect();
|
||||
virtual void SetWorld(IWorld *world);
|
||||
virtual bool IsHearingVoices();
|
||||
virtual bool HasChatEnabled();
|
||||
virtual NetAddress *GetAddress();
|
||||
virtual InfoString *GetUserInfo();
|
||||
virtual int GetClientType();
|
||||
virtual char *GetClientName();
|
||||
virtual bool IsActive();
|
||||
virtual void Send(unsigned char *data, int length, bool isReliable);
|
||||
virtual void DownloadFailed(char *fileName);
|
||||
virtual void DownloadFile(char *fileName);
|
||||
virtual void UpdateVoiceMask(BitBuffer *stream);
|
||||
virtual void QueryVoiceEnabled(BitBuffer *stream);
|
||||
virtual void SetName(char *newName);
|
||||
virtual void WriteSpawn(BitBuffer *stream);
|
||||
virtual void WriteDatagram(double time, frame_t *frame);
|
||||
virtual void SendDatagram();
|
||||
virtual void Reset();
|
||||
|
||||
enum ClientState {
|
||||
CLIENT_UNDEFINED = 0,
|
||||
CLIENT_INITIALIZING,
|
||||
CLIENT_CONNECTING,
|
||||
CLIENT_RUNNING,
|
||||
CLIENT_DISCONNECTED
|
||||
};
|
||||
|
||||
virtual void SetState(ClientState newState);
|
||||
virtual void ReplyNew();
|
||||
virtual void ReplySpawn(int spawncount, int crcMap);
|
||||
virtual void ReplyFullUpdate();
|
||||
virtual void PrintfToClient(char *fmt, ...);
|
||||
virtual void UpdateUserInfo(char *userinfostring = nullptr);
|
||||
virtual void ParseStringCmd(NetPacket *packet);
|
||||
virtual void ParseNop(NetPacket *packet);
|
||||
virtual void ParseBad(NetPacket *packet);
|
||||
virtual void ParseMove(NetPacket *packet);
|
||||
virtual void ParseVoiceData(NetPacket *packet);
|
||||
virtual void ParseHLTV(NetPacket *packet);
|
||||
virtual void ParseDelta(NetPacket *packet);
|
||||
virtual void ParseCvarValue(NetPacket *packet);
|
||||
virtual void ParseCvarValue2(NetPacket *packet);
|
||||
virtual void ProcessMessage(NetPacket *packet);
|
||||
virtual bool ProcessStringCmd(char *string);
|
||||
|
||||
private:
|
||||
enum LocalCommandIDs {
|
||||
CMD_ID_NAME = 1,
|
||||
CMD_ID_SPAWN,
|
||||
CMD_ID_NEW,
|
||||
CMD_ID_FULLUPDATE,
|
||||
CMD_ID_DROPCLIENT,
|
||||
CMD_ID_DLFILE,
|
||||
CMD_ID_SETINFO,
|
||||
CMD_ID_SHOWINFO,
|
||||
CMD_ID_SENDENTS,
|
||||
CMD_ID_VMODENABLE,
|
||||
CMD_ID_VBAN,
|
||||
CMD_ID_SENDERS,
|
||||
CMD_ID_PING,
|
||||
CMD_ID_SPECTATE,
|
||||
CMD_ID_SPK,
|
||||
CMD_ID_PAUSE,
|
||||
CMD_ID_UNPAUSE,
|
||||
CMD_ID_SETPAUSE
|
||||
};
|
||||
|
||||
void CMD_Name(TokenLine *cmd);
|
||||
void CMD_Spawn(TokenLine *cmd);
|
||||
void CMD_New(TokenLine *cmd);
|
||||
void CMD_FullUpdate(TokenLine *cmd);
|
||||
void CMD_DropClient(TokenLine *cmd);
|
||||
void CMD_DownloadFile(TokenLine *cmd);
|
||||
void CMD_SetInfo(TokenLine *cmd);
|
||||
void CMD_ShowInfo(TokenLine *cmd);
|
||||
void CMD_SendEntities(TokenLine *cmd);
|
||||
void CMD_VoiceModEnable(TokenLine *cmd);
|
||||
void CMD_VoiceBan(TokenLine *cmd);
|
||||
void CMD_SendResources(TokenLine *cmd);
|
||||
void CMD_RequestPing(TokenLine *cmd);
|
||||
void CMD_Spectate(TokenLine *cmd);
|
||||
void CMD_Spk(TokenLine *cmd);
|
||||
void CMD_Pause(TokenLine *cmd);
|
||||
void CMD_UnPause(TokenLine *cmd);
|
||||
void CMD_SetPause(TokenLine *cmd);
|
||||
|
||||
struct LocalCommandID_s {
|
||||
char *name;
|
||||
LocalCommandIDs id;
|
||||
void (BaseClient::*pfnCmd)(TokenLine *cmd);
|
||||
};
|
||||
static LocalCommandID_s m_LocalCmdReg[];
|
||||
|
||||
protected:
|
||||
struct clc_func_s {
|
||||
clc_commands opcode;
|
||||
char *pszname;
|
||||
void (BaseClient::*func)(NetPacket *packet);
|
||||
};
|
||||
static clc_func_s m_ClientFuncs[];
|
||||
|
||||
IWorld *m_World;
|
||||
INetSocket *m_Socket;
|
||||
NetChannel m_ClientChannel;
|
||||
|
||||
int m_ClientType;
|
||||
int m_ClientState;
|
||||
char m_ClientName[32];
|
||||
|
||||
enum { MAX_USER_INFO = 256 };
|
||||
InfoString m_Userinfo;
|
||||
unsigned int m_LastFrameSeqNr;
|
||||
unsigned int m_DeltaFrameSeqNr;
|
||||
unsigned int m_ClientDelta;
|
||||
unsigned int m_SeqNrMap[256];
|
||||
|
||||
int m_CRC_Value;
|
||||
bool m_VoiceEnabled;
|
||||
bool m_VoiceQuery;
|
||||
|
||||
CPlayerBitVec m_SentGameRulesMask;
|
||||
CPlayerBitVec m_SentBanMask;
|
||||
CPlayerBitVec m_BanMask;
|
||||
};
|
887
rehlds/HLTV/common/BitBuffer.cpp
Normal file
887
rehlds/HLTV/common/BitBuffer.cpp
Normal file
@ -0,0 +1,887 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
const uint32 BITTABLE[] =
|
||||
{
|
||||
0x00000001, 0x00000002, 0x00000004, 0x00000008,
|
||||
0x00000010, 0x00000020, 0x00000040, 0x00000080,
|
||||
0x00000100, 0x00000200, 0x00000400, 0x00000800,
|
||||
0x00001000, 0x00002000, 0x00004000, 0x00008000,
|
||||
0x00010000, 0x00020000, 0x00040000, 0x00080000,
|
||||
0x00100000, 0x00200000, 0x00400000, 0x00800000,
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
||||
0x00000000,
|
||||
};
|
||||
|
||||
const uint32 ROWBITTABLE[] =
|
||||
{
|
||||
0x00000000, 0x00000001, 0x00000003, 0x00000007,
|
||||
0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
|
||||
0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
|
||||
0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
|
||||
0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
|
||||
0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
|
||||
0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
|
||||
0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
};
|
||||
|
||||
const uint32 INVBITTABLE[] =
|
||||
{
|
||||
0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFB, 0xFFFFFFF7,
|
||||
0xFFFFFFEF, 0xFFFFFFDF, 0xFFFFFFBF, 0xFFFFFF7F,
|
||||
0xFFFFFEFF, 0xFFFFFDFF, 0xFFFFFBFF, 0xFFFFF7FF,
|
||||
0xFFFFEFFF, 0xFFFFDFFF, 0xFFFFBFFF, 0xFFFF7FFF,
|
||||
0xFFFEFFFF, 0xFFFDFFFF, 0xFFFBFFFF, 0xFFF7FFFF,
|
||||
0xFFEFFFFF, 0xFFDFFFFF, 0xFFBFFFFF, 0xFF7FFFFF,
|
||||
0xFEFFFFFF, 0xFDFFFFFF, 0xFBFFFFFF, 0xF7FFFFFF,
|
||||
0xEFFFFFFF, 0xDFFFFFFF, 0xBFFFFFFF, 0x7FFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
};
|
||||
|
||||
BitBuffer::BitBuffer() : m_Data(nullptr),
|
||||
m_CurByte(nullptr),
|
||||
m_CurSize(0),
|
||||
m_MaxSize(0),
|
||||
m_Overflowed(false),
|
||||
m_LittleEndian(false),
|
||||
m_OwnData(false)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
BitBuffer::BitBuffer(void *newData, unsigned int size)
|
||||
{
|
||||
m_Data = (unsigned char *)newData;
|
||||
m_CurByte = m_Data;
|
||||
|
||||
m_CurSize = 0;
|
||||
m_MaxSize = size;
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = true;
|
||||
m_OwnData = false;
|
||||
}
|
||||
|
||||
BitBuffer::~BitBuffer()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
BitBuffer::BitBuffer(unsigned int size)
|
||||
{
|
||||
m_Data = nullptr;
|
||||
m_CurByte = nullptr;
|
||||
|
||||
m_CurSize = 0;
|
||||
m_MaxSize = size;
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = false;
|
||||
m_OwnData = false;
|
||||
|
||||
Resize(size);
|
||||
}
|
||||
|
||||
bool BitBuffer::Resize(unsigned int size)
|
||||
{
|
||||
Free();
|
||||
|
||||
m_Data = (unsigned char *)Mem_ZeroMalloc(size + 4);
|
||||
m_CurSize = 0;
|
||||
m_Overflowed = false;
|
||||
|
||||
if (m_Data)
|
||||
{
|
||||
m_CurByte = m_Data;
|
||||
m_MaxSize = size;
|
||||
|
||||
m_OwnData = true;
|
||||
m_LittleEndian = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_MaxSize = 0;
|
||||
m_OwnData = false;
|
||||
m_CurByte = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BitBuffer::Clear()
|
||||
{
|
||||
memset(m_Data, 0, m_MaxSize);
|
||||
|
||||
m_CurByte = m_Data;
|
||||
m_CurSize = 0;
|
||||
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = true;
|
||||
}
|
||||
|
||||
int BitBuffer::CurrentBit()
|
||||
{
|
||||
return m_CurSize + 8 * (m_CurByte - m_Data);
|
||||
}
|
||||
|
||||
void BitBuffer::Reset()
|
||||
{
|
||||
m_CurByte = m_Data;
|
||||
m_CurSize = 0;
|
||||
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = true;
|
||||
}
|
||||
|
||||
void BitBuffer::Free()
|
||||
{
|
||||
if (m_Data && m_OwnData) {
|
||||
free(m_Data);
|
||||
}
|
||||
|
||||
m_Data = nullptr;
|
||||
m_CurByte = nullptr;
|
||||
|
||||
m_CurSize = 0;
|
||||
m_MaxSize = 0;
|
||||
|
||||
m_OwnData = false;
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = true;
|
||||
}
|
||||
|
||||
unsigned int BitBuffer::ReadBits(int numbits)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
if (m_LittleEndian)
|
||||
{
|
||||
if (m_CurByte - m_Data >= m_MaxSize)
|
||||
{
|
||||
m_Overflowed = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bits = m_CurSize + numbits;
|
||||
if (bits <= 32)
|
||||
{
|
||||
result = (*(unsigned int *)m_CurByte >> m_CurSize) & ROWBITTABLE[numbits];
|
||||
|
||||
m_CurByte += numbits >> 3;
|
||||
m_CurSize += numbits & 7;
|
||||
|
||||
if (m_CurSize > 7)
|
||||
{
|
||||
m_CurSize &= 7;
|
||||
m_CurByte++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int data = *(unsigned int *)m_CurByte >> m_CurSize;
|
||||
m_CurByte += 4;
|
||||
result = ((ROWBITTABLE[bits & 7] & *(unsigned int *)m_CurByte) << (32 - m_CurSize)) | data;
|
||||
m_CurSize = bits & 7;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int d = numbits;
|
||||
while (d > 0)
|
||||
{
|
||||
--d;
|
||||
if (ReadBit()) {
|
||||
result |= (1 << d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int BitBuffer::ReadBit()
|
||||
{
|
||||
int result;
|
||||
if (m_CurByte - m_Data >= m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_LittleEndian)
|
||||
{
|
||||
if (m_CurSize == 7)
|
||||
{
|
||||
m_CurSize = 0;
|
||||
result = (*m_CurByte++ >> 7) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ((unsigned int)*m_CurByte >> m_CurSize++) & 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_CurSize == 7)
|
||||
{
|
||||
m_CurSize = 0;
|
||||
result = *m_CurByte++ & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ((unsigned int)*m_CurByte >> (7 - m_CurSize++)) & 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int BitBuffer::PeekBits(int numbits)
|
||||
{
|
||||
int oldcurrentBit = m_CurSize;
|
||||
unsigned char *oldcurrentByte = m_CurByte;
|
||||
unsigned int data = ReadBits(numbits);
|
||||
|
||||
m_CurSize = oldcurrentBit;
|
||||
m_CurByte = oldcurrentByte;
|
||||
return data;
|
||||
}
|
||||
|
||||
int BitBuffer::ReadChar()
|
||||
{
|
||||
return ReadBits(8);
|
||||
}
|
||||
|
||||
int BitBuffer::ReadByte()
|
||||
{
|
||||
return ReadBits(8);
|
||||
}
|
||||
|
||||
int BitBuffer::ReadShort()
|
||||
{
|
||||
return ReadBits(16);
|
||||
}
|
||||
|
||||
int BitBuffer::ReadWord()
|
||||
{
|
||||
return ReadBits(16);
|
||||
}
|
||||
|
||||
unsigned int BitBuffer::ReadLong()
|
||||
{
|
||||
return ReadBits(32);
|
||||
}
|
||||
|
||||
float BitBuffer::ReadFloat()
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
} dat;
|
||||
|
||||
dat.i = _LittleLong(ReadLong());
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
bool BitBuffer::ReadBuf(int iSize, void *pbuf)
|
||||
{
|
||||
if (m_CurByte - m_Data + iSize > m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_CurSize)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int *p = (unsigned int *)pbuf;
|
||||
for (i = 4; i < iSize; i += 4) {
|
||||
*p++ = ReadLong();
|
||||
}
|
||||
|
||||
for (j = 0; j < iSize - (i - 4); ++j) {
|
||||
*((unsigned char *)p + j) = ReadByte();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pbuf, m_CurByte, iSize);
|
||||
m_CurByte += iSize;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBuf(BitBuffer *buf, int length)
|
||||
{
|
||||
WriteBuf(buf->m_CurByte, length);
|
||||
buf->SkipBytes(length);
|
||||
}
|
||||
|
||||
char *BitBuffer::ReadString()
|
||||
{
|
||||
int c = 0, l = 0;
|
||||
static char string[8192];
|
||||
|
||||
while ((c = ReadChar(), c) && c != -1 && l < sizeof(string) - 1) {
|
||||
string[l++] = c;
|
||||
}
|
||||
|
||||
string[l] = '\0';
|
||||
return string;
|
||||
}
|
||||
|
||||
char *BitBuffer::ReadStringLine()
|
||||
{
|
||||
int c = 0, l = 0;
|
||||
static char string[2048];
|
||||
|
||||
while ((c = ReadChar(), c) && c != '\n' && c != -1 && l < sizeof(string) - 1) {
|
||||
string[l++] = c;
|
||||
}
|
||||
|
||||
string[l] = '\0';
|
||||
return string;
|
||||
}
|
||||
|
||||
float BitBuffer::ReadAngle()
|
||||
{
|
||||
int c = ReadChar();
|
||||
if (c == -1)
|
||||
{
|
||||
// FIXED: Added check for wrong value, but just return 0 instead of -1 * (360.0 / 256)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (float)(c * (360.0 / 256));
|
||||
}
|
||||
|
||||
float BitBuffer::ReadHiresAngle()
|
||||
{
|
||||
int c = ReadShort();
|
||||
if (c == -1)
|
||||
{
|
||||
// FIXED: Added check for wrong value, but just return 0 instead of -1 * (360.0 / 65536)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (float)(c * (360.0 / 65536));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBit(int c)
|
||||
{
|
||||
if (m_CurByte - m_Data >= m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_LittleEndian)
|
||||
{
|
||||
if (m_CurSize == 7)
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
m_CurByte[0] |= 0x80u;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurByte[0] &= 0x7Fu;
|
||||
}
|
||||
|
||||
m_CurByte++;
|
||||
m_CurSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
m_CurByte[0] |= BITTABLE[ m_CurSize ];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurByte[0] &= INVBITTABLE[ m_CurSize ];
|
||||
}
|
||||
|
||||
m_CurSize++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static unsigned char masks[] = { 0x80u, 0x40u, 0x20u, 0x10u, 0x8u, 0x4u, 0x2u, 0x1u };
|
||||
static unsigned char inv_masks[] = { 0x7Fu, 0xBFu, 0xDFu, 0xEFu, 0xF7u, 0xFBu, 0xFDu, 0xFEu };
|
||||
|
||||
if (c)
|
||||
m_CurByte[0] |= masks[ m_CurSize ];
|
||||
else
|
||||
m_CurByte[0] &= inv_masks[ m_CurSize ];
|
||||
|
||||
if (++m_CurSize == 8)
|
||||
{
|
||||
m_CurSize = 0;
|
||||
m_CurByte++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBits(unsigned int data, int numbits)
|
||||
{
|
||||
if (m_Overflowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_LittleEndian)
|
||||
{
|
||||
if (m_CurByte - m_Data + (numbits >> 8) > m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int bits = numbits + m_CurSize;
|
||||
if (bits <= 32)
|
||||
{
|
||||
*(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) << m_CurSize;
|
||||
|
||||
m_CurByte = &m_CurByte[numbits >> 3];
|
||||
m_CurSize = m_CurSize + (numbits & 7);
|
||||
|
||||
if (m_CurSize > 7)
|
||||
{
|
||||
m_CurSize = m_CurSize & 7;
|
||||
m_CurByte = m_CurByte + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) << m_CurSize;
|
||||
|
||||
int leftBits = (32 - m_CurSize);
|
||||
m_CurSize = (m_CurSize + numbits) & 7;
|
||||
|
||||
m_CurByte += 4;
|
||||
*(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) >> leftBits;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int nBitValue = data;
|
||||
if (numbits <= 31 && nBitValue >= (1 << numbits) && nBitValue != -1)
|
||||
nBitValue = (1 << numbits) - 1;
|
||||
|
||||
while (--numbits > 0)
|
||||
{
|
||||
if (m_CurByte - m_Data >= m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteBit(nBitValue & (1 << numbits));
|
||||
}
|
||||
}
|
||||
|
||||
void BitBuffer::WriteSBits(int data, int numbits)
|
||||
{
|
||||
int idata = data;
|
||||
if (numbits < 32)
|
||||
{
|
||||
int maxnum = (1 << (numbits - 1)) - 1;
|
||||
if (data > maxnum || (maxnum = -maxnum, data < maxnum))
|
||||
{
|
||||
idata = maxnum;
|
||||
}
|
||||
}
|
||||
|
||||
int sigbits = idata < 0;
|
||||
|
||||
WriteBit(sigbits);
|
||||
WriteBits(abs(idata), numbits - 1);
|
||||
}
|
||||
|
||||
void BitBuffer::WriteChar(int c)
|
||||
{
|
||||
WriteBits(c, 8 * sizeof(char));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteByte(int c)
|
||||
{
|
||||
WriteBits(c, 8 * sizeof(uint8));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteShort(int c)
|
||||
{
|
||||
WriteBits(c, 8 * sizeof(int16));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteWord(int c)
|
||||
{
|
||||
WriteBits(c, 8 * sizeof(uint16));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteLong(unsigned int c)
|
||||
{
|
||||
WriteBits(c, 8 * sizeof(uint32));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteFloat(float f)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
} dat;
|
||||
|
||||
dat.f = f;
|
||||
WriteBits(_LittleLong(dat.i), 8 * sizeof(float));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteString(const char *p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
WriteBuf(p, strlen(p) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteChar('\0');
|
||||
}
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBuf(const void *buf, int iSize)
|
||||
{
|
||||
if (!buf || m_Overflowed || !iSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_CurByte - m_Data + iSize > m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_CurSize)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int *p = (unsigned int *)buf;
|
||||
|
||||
for (i = 4; i < iSize; i += 4) {
|
||||
WriteLong(*p++);
|
||||
}
|
||||
|
||||
for (j = 0; j < (iSize - (i - 4)); j++) {
|
||||
WriteChar(*((unsigned char *)p + j));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(m_CurByte, buf, iSize);
|
||||
m_CurByte += iSize;
|
||||
}
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBitData(void *src, int length)
|
||||
{
|
||||
int i;
|
||||
unsigned char *p = (unsigned char *)src;
|
||||
for (i = 0; i < length; i++, p++)
|
||||
{
|
||||
WriteChar(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void BitBuffer::WriteAngle(float f)
|
||||
{
|
||||
WriteByte((int64)(fmod((double)f, 360.0) * 256.0 / 360.0) & 0xFF);
|
||||
}
|
||||
|
||||
void BitBuffer::WriteHiresAngle(float f)
|
||||
{
|
||||
WriteShort((int64)(fmod((double)f, 360.0) * 65536.0 / 360.0) & 0xFFFF);
|
||||
}
|
||||
|
||||
int BitBuffer::CurrentSize()
|
||||
{
|
||||
return (m_CurSize != 0) + m_CurByte - m_Data;
|
||||
}
|
||||
|
||||
unsigned char *BitBuffer::CurrentByte()
|
||||
{
|
||||
return m_CurByte;
|
||||
}
|
||||
|
||||
int BitBuffer::SpaceLeft()
|
||||
{
|
||||
return m_MaxSize + m_Data - m_CurByte;
|
||||
}
|
||||
|
||||
void BitBuffer::AlignByte()
|
||||
{
|
||||
if (m_CurSize)
|
||||
{
|
||||
m_CurByte++;
|
||||
m_CurSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int BitBuffer::ReadSBits(int numbits)
|
||||
{
|
||||
int nSignBit = ReadBit();
|
||||
int result = ReadBits(numbits - 1);
|
||||
|
||||
if (nSignBit)
|
||||
{
|
||||
result = -result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float BitBuffer::ReadBitAngle(int numbits)
|
||||
{
|
||||
return (float)(ReadBits(numbits) * (360.0 / (1 << numbits)));
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBitAngle(float fAngle, int numbits)
|
||||
{
|
||||
if (numbits >= 32) {
|
||||
m_Overflowed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int shift = (1 << numbits);
|
||||
unsigned int mask = shift - 1;
|
||||
|
||||
int d = (int)(shift * fmod((double)fAngle, 360.0)) / 360;
|
||||
d &= mask;
|
||||
|
||||
WriteBits(d, numbits);
|
||||
}
|
||||
|
||||
char *BitBuffer::ReadBitString()
|
||||
{
|
||||
static char buf[8192];
|
||||
buf[0] = '\0';
|
||||
|
||||
char *p = &buf[0];
|
||||
for (unsigned int c = ReadChar(); c; c = ReadChar())
|
||||
{
|
||||
// Prevent infinite cycle if m_Overflowed
|
||||
if (m_Overflowed) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
void BitBuffer::WriteBitString(const char *p)
|
||||
{
|
||||
const unsigned char *pch = (unsigned char *)p;
|
||||
while (*pch)
|
||||
{
|
||||
WriteChar(*pch++);
|
||||
}
|
||||
|
||||
WriteChar('\0');
|
||||
}
|
||||
|
||||
void BitBuffer::StartBitMode()
|
||||
{
|
||||
if (m_CurSize) {
|
||||
m_Overflowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BitBuffer::EndBitMode()
|
||||
{
|
||||
AlignByte();
|
||||
}
|
||||
|
||||
int BitBuffer::ReadBitData(void *dest, int length)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)dest;
|
||||
for (int i = 0; i < length; i++) {
|
||||
*p++ = ReadByte();
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void BitBuffer::SetBuffer(void *buffer, int size)
|
||||
{
|
||||
Free();
|
||||
|
||||
m_Data = (unsigned char *)buffer;
|
||||
m_CurByte = (unsigned char *)buffer;
|
||||
m_MaxSize = size;
|
||||
m_CurSize = 0;
|
||||
|
||||
m_OwnData = false;
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = true;
|
||||
}
|
||||
|
||||
void BitBuffer::ReadBitVec3Coord(float *fa)
|
||||
{
|
||||
int xflag = ReadBit();
|
||||
int yflag = ReadBit();
|
||||
int zflag = ReadBit();
|
||||
|
||||
if (xflag)
|
||||
fa[0] = ReadBitCoord();
|
||||
if (yflag)
|
||||
fa[1] = ReadBitCoord();
|
||||
if (zflag)
|
||||
fa[2] = ReadBitCoord();
|
||||
}
|
||||
|
||||
float BitBuffer::ReadBitCoord()
|
||||
{
|
||||
float value = 0;
|
||||
|
||||
int intval = ReadBit();
|
||||
int fractval = ReadBit();
|
||||
|
||||
if (intval || fractval)
|
||||
{
|
||||
int signbit = ReadBit();
|
||||
if (intval) {
|
||||
intval = ReadBits(12);
|
||||
}
|
||||
|
||||
if (fractval) {
|
||||
fractval = ReadBits(3);
|
||||
}
|
||||
|
||||
value = (float)(fractval / 8.0 + intval);
|
||||
if (signbit) {
|
||||
value = -value;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float BitBuffer::ReadCoord()
|
||||
{
|
||||
return (float)(ReadShort() * (1.0 / 8));
|
||||
}
|
||||
|
||||
void BitBuffer::SkipBytes(int numbits)
|
||||
{
|
||||
if (numbits + m_CurByte - m_Data > m_MaxSize) {
|
||||
m_Overflowed = true;
|
||||
}
|
||||
|
||||
m_CurByte += numbits;
|
||||
}
|
||||
|
||||
void BitBuffer::SkipBits(int numbits)
|
||||
{
|
||||
if (m_LittleEndian)
|
||||
{
|
||||
if (m_CurByte - m_Data >= m_MaxSize)
|
||||
{
|
||||
m_Overflowed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int bits = m_CurSize + numbits;
|
||||
if (bits <= 32)
|
||||
{
|
||||
m_CurByte += numbits >> 3;
|
||||
m_CurSize += numbits & 7;
|
||||
|
||||
if (m_CurSize > 7)
|
||||
{
|
||||
m_CurSize &= 7;
|
||||
m_CurByte++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurByte += 4;
|
||||
m_CurSize = bits & 7;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int d = numbits;
|
||||
while (d > 0)
|
||||
{
|
||||
--d;
|
||||
if (m_CurSize == 7)
|
||||
{
|
||||
m_CurByte++;
|
||||
m_CurSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurSize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BitBuffer::SkipString()
|
||||
{
|
||||
int c = 0, l = 1;
|
||||
const int maxString = 8192;
|
||||
|
||||
while ((c = ReadChar(), c) && c != -1 && l < maxString) {
|
||||
l++;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void BitBuffer::FastClear()
|
||||
{
|
||||
int iSize = CurrentSize() + 4;
|
||||
if (iSize > m_MaxSize) {
|
||||
iSize = m_MaxSize;
|
||||
}
|
||||
|
||||
memset(m_Data, 0, iSize);
|
||||
|
||||
m_CurByte = m_Data;
|
||||
m_CurSize = 0;
|
||||
|
||||
m_Overflowed = false;
|
||||
m_LittleEndian = true;
|
||||
}
|
||||
|
||||
void BitBuffer::ConcatBuffer(BitBuffer *buffer)
|
||||
{
|
||||
WriteBuf(buffer->m_Data, buffer->CurrentSize());
|
||||
}
|
||||
|
||||
void BitBuffer::WriteCoord(float f)
|
||||
{
|
||||
WriteShort((int)(f * 8.0));
|
||||
}
|
117
rehlds/HLTV/common/BitBuffer.h
Normal file
117
rehlds/HLTV/common/BitBuffer.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class BitBuffer {
|
||||
public:
|
||||
BitBuffer();
|
||||
BitBuffer(unsigned int size);
|
||||
BitBuffer(void *newData, unsigned int size);
|
||||
virtual ~BitBuffer();
|
||||
|
||||
unsigned int PeekBits(int numbits);
|
||||
int CurrentBit();
|
||||
int CurrentSize();
|
||||
unsigned char *CurrentByte();
|
||||
|
||||
int GetMaxSize() const { return m_MaxSize; }
|
||||
unsigned int GetCurSize() const { return m_CurSize; }
|
||||
unsigned char *GetData() const { return m_Data; }
|
||||
bool IsOverflowed() const { return m_Overflowed; }
|
||||
|
||||
void SetBuffer(void *buffer, int size);
|
||||
void Free();
|
||||
void Reset();
|
||||
void Clear();
|
||||
void FastClear();
|
||||
int SpaceLeft();
|
||||
void EndBitMode();
|
||||
void StartBitMode();
|
||||
bool Resize(unsigned int size);
|
||||
void ConcatBuffer(BitBuffer *buffer);
|
||||
int SkipString();
|
||||
|
||||
void SkipBits(int numbits);
|
||||
void SkipBytes(int numbits);
|
||||
|
||||
void AlignByte();
|
||||
|
||||
// function's read stuff
|
||||
unsigned int ReadBits(int numbits);
|
||||
int ReadBit();
|
||||
int ReadChar();
|
||||
int ReadByte();
|
||||
int ReadShort();
|
||||
int ReadWord();
|
||||
|
||||
unsigned int ReadLong();
|
||||
float ReadFloat();
|
||||
char *ReadString();
|
||||
char *ReadStringLine();
|
||||
char *ReadBitString();
|
||||
int ReadSBits(int numbits);
|
||||
float ReadBitAngle(int numbits);
|
||||
int ReadBitData(void *dest, int length);
|
||||
bool ReadBuf(int iSize, void *pbuf);
|
||||
float ReadAngle();
|
||||
float ReadHiresAngle();
|
||||
float ReadCoord();
|
||||
float ReadBitCoord();
|
||||
void ReadBitVec3Coord(float *fa);
|
||||
|
||||
// function's write stuff
|
||||
void WriteBits(unsigned int data, int numbits);
|
||||
void WriteBit(int c);
|
||||
void WriteChar(int c);
|
||||
void WriteByte(int c);
|
||||
void WriteShort(int c);
|
||||
void WriteWord(int c);
|
||||
void WriteLong(unsigned int c);
|
||||
void WriteFloat(float f);
|
||||
void WriteString(const char *p);
|
||||
void WriteBitString(const char *p);
|
||||
void WriteSBits(int data, int numbits);
|
||||
void WriteBitAngle(float fAngle, int numbits);
|
||||
void WriteBitData(void *src, int length);
|
||||
void WriteBuf(const void *buf, int iSize);
|
||||
void WriteBuf(BitBuffer *buf, int length);
|
||||
void WriteAngle(float f);
|
||||
void WriteHiresAngle(float f);
|
||||
void WriteCoord(float f);
|
||||
|
||||
bool m_Overflowed;
|
||||
unsigned char *m_Data;
|
||||
unsigned char *m_CurByte;
|
||||
int m_CurSize;
|
||||
int m_MaxSize;
|
||||
|
||||
protected:
|
||||
bool m_LittleEndian;
|
||||
bool m_OwnData;
|
||||
};
|
604
rehlds/HLTV/common/DemoFile.cpp
Normal file
604
rehlds/HLTV/common/DemoFile.cpp
Normal file
@ -0,0 +1,604 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
DemoFile::DemoFile() :
|
||||
m_FileSystem(nullptr),
|
||||
m_FileHandle(FILESYSTEM_INVALID_HANDLE),
|
||||
m_DemoChannel(nullptr),
|
||||
m_Entries(nullptr)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void DemoFile::Init(IWorld *world, IServer *server, NetChannel *channel)
|
||||
{
|
||||
m_World = world;
|
||||
m_Server = server;
|
||||
m_System = world->GetSystem();
|
||||
m_FileSystem = m_System->GetFileSystem();
|
||||
|
||||
m_DemoChannel = channel;
|
||||
m_Entries = nullptr;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void DemoFile::Reset()
|
||||
{
|
||||
memset(m_FileName, 0, sizeof(m_FileName));
|
||||
memset(&m_zeroDemoInfo, 0, sizeof(m_zeroDemoInfo));
|
||||
|
||||
CloseFile();
|
||||
m_Continuous = true;
|
||||
}
|
||||
|
||||
bool DemoFile::IsRecording()
|
||||
{
|
||||
return m_DemoState == DEMO_RECORDING;
|
||||
}
|
||||
|
||||
void DemoFile::CloseFile()
|
||||
{
|
||||
unsigned char c;
|
||||
float f;
|
||||
int curpos;
|
||||
int i;
|
||||
|
||||
if (m_FileSystem && m_FileHandle != FILESYSTEM_INVALID_HANDLE)
|
||||
{
|
||||
if (m_DemoState == DEMO_RECORDING)
|
||||
{
|
||||
c = 5;
|
||||
m_FileSystem->Write(&c, sizeof(unsigned char), m_FileHandle);
|
||||
|
||||
f = _LittleFloat(GetDemoTime());
|
||||
m_FileSystem->Write(&f, sizeof(float), m_FileHandle);
|
||||
|
||||
i = _LittleLong(m_frameCount);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
|
||||
curpos = m_FileSystem->Tell(m_FileHandle);
|
||||
|
||||
m_gameEntry.nFileLength = curpos - m_gameEntry.nOffset;
|
||||
m_gameEntry.fTrackTime = GetDemoTime();
|
||||
m_gameEntry.nFrames = m_frameCount;
|
||||
|
||||
i = 2;
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_loadEntry, sizeof(m_loadEntry), m_FileHandle);
|
||||
m_FileSystem->Write(&m_gameEntry, sizeof(m_gameEntry), m_FileHandle);
|
||||
|
||||
m_demoHeader.nDirectoryOffset = curpos;
|
||||
m_FileSystem->Seek(m_FileHandle, 0, FILESYSTEM_SEEK_HEAD);
|
||||
m_FileSystem->Write(&m_demoHeader, sizeof(m_demoHeader), m_FileHandle);
|
||||
m_System->Printf("Completed demo %s.\n", m_FileName);
|
||||
}
|
||||
|
||||
m_FileSystem->Close(m_FileHandle);
|
||||
}
|
||||
|
||||
if (m_Entries)
|
||||
{
|
||||
free(m_Entries);
|
||||
m_Entries = nullptr;
|
||||
}
|
||||
|
||||
m_FileHandle = FILESYSTEM_INVALID_HANDLE;
|
||||
m_DemoState = DEMO_IDLE;
|
||||
}
|
||||
|
||||
void DemoFile::WriteDemoInfo(demo_info_t *demoInfo)
|
||||
{
|
||||
m_FileSystem->Write(demoInfo, sizeof(*demoInfo), m_FileHandle);
|
||||
}
|
||||
|
||||
void DemoFile::WriteSequenceInfo()
|
||||
{
|
||||
m_FileSystem->Write(&m_DemoChannel->m_outgoing_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_DemoChannel->m_incoming_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_DemoChannel->m_last_reliable_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_DemoChannel->m_reliable_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_DemoChannel->m_incoming_acknowledged, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_DemoChannel->m_incoming_reliable_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(&m_DemoChannel->m_incoming_reliable_acknowledged, sizeof(int), m_FileHandle);
|
||||
}
|
||||
|
||||
void DemoFile::WriteDemoStartup(BitBuffer *buffer)
|
||||
{
|
||||
unsigned char c;
|
||||
int i;
|
||||
float f;
|
||||
|
||||
int len = buffer->CurrentSize();
|
||||
if (len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
c = 0;
|
||||
m_FileSystem->Write(&c, sizeof(unsigned char), m_FileHandle);
|
||||
|
||||
f = _LittleFloat(GetDemoTime());
|
||||
m_FileSystem->Write(&f, sizeof(float), m_FileHandle);
|
||||
|
||||
i = _LittleLong(m_frameCount);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
|
||||
WriteDemoInfo(&m_zeroDemoInfo);
|
||||
WriteSequenceInfo();
|
||||
|
||||
i = _LittleLong(len);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(buffer->GetData(), len, m_FileHandle);
|
||||
}
|
||||
|
||||
void DemoFile::WriteDemoMessage(BitBuffer *unreliableData, BitBuffer *reliableData)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
float f;
|
||||
unsigned char c;
|
||||
|
||||
len = reliableData->CurrentSize() + unreliableData->CurrentSize();
|
||||
if (len <= 0 || m_FileHandle == FILESYSTEM_INVALID_HANDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_FileSystem) {
|
||||
return;
|
||||
}
|
||||
|
||||
c = 1;
|
||||
m_frameCount++;
|
||||
|
||||
m_FileSystem->Write(&c, sizeof(unsigned char), m_FileHandle);
|
||||
|
||||
f = _LittleFloat(GetDemoTime());
|
||||
m_FileSystem->Write(&f, sizeof(float), m_FileHandle);
|
||||
|
||||
i = _LittleLong(m_frameCount);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
|
||||
WriteDemoInfo(&m_zeroDemoInfo);
|
||||
WriteSequenceInfo();
|
||||
|
||||
i = _LittleLong(len);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(unreliableData->GetData(), unreliableData->CurrentSize(), m_FileHandle);
|
||||
m_FileSystem->Write(reliableData->GetData(), reliableData->CurrentSize(), m_FileHandle);
|
||||
}
|
||||
|
||||
void DemoFile::WriteUpdateClientData(client_data_t *cdata)
|
||||
{
|
||||
if (!m_FileSystem || m_FileHandle == FILESYSTEM_INVALID_HANDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char cmd = 4;
|
||||
m_FileSystem->Write(&cmd, sizeof(unsigned char), m_FileHandle);
|
||||
|
||||
float f = _LittleFloat(GetDemoTime());
|
||||
m_FileSystem->Write(&f, sizeof(float), m_FileHandle);
|
||||
|
||||
int i = _LittleLong(m_frameCount);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Write(cdata, sizeof(*cdata), m_FileHandle);
|
||||
}
|
||||
|
||||
float DemoFile::GetDemoTime()
|
||||
{
|
||||
return m_System->GetTime() - m_startTime;
|
||||
}
|
||||
|
||||
void DemoFile::WriteSignonData()
|
||||
{
|
||||
BitBuffer buffer(MAX_POSSIBLE_MSG * 2);
|
||||
m_World->WriteNewData(&buffer);
|
||||
m_World->WriteSigonData(&buffer);
|
||||
|
||||
buffer.WriteByte(svc_time);
|
||||
buffer.WriteFloat(GetDemoTime());
|
||||
|
||||
for (int i = 0; i < m_World->GetMaxClients(); i++) {
|
||||
m_World->WriteClientUpdate(&buffer, i);
|
||||
}
|
||||
|
||||
m_World->WriteLightStyles(&buffer);
|
||||
|
||||
buffer.WriteByte(svc_signonnum);
|
||||
buffer.WriteByte(1);
|
||||
|
||||
WriteDemoStartup(&buffer);
|
||||
}
|
||||
|
||||
bool DemoFile::StartRecording(char *newName)
|
||||
{
|
||||
unsigned char b;
|
||||
int i;
|
||||
float f;
|
||||
|
||||
if (IsPlaying() || !m_FileSystem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_FileHandle != FILESYSTEM_INVALID_HANDLE) {
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
strcopy(m_FileName, newName);
|
||||
|
||||
m_FileHandle = m_FileSystem->Open(m_FileName, "wb");
|
||||
if (!m_FileHandle) {
|
||||
m_System->Printf("WARNING! DemoFile::StartRecording: coudn't open demo file %s.\n", m_FileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&m_demoHeader, 0, sizeof(m_demoHeader));
|
||||
strcopy(m_demoHeader.szFileStamp, "HLDEMO");
|
||||
|
||||
COM_FileBase(m_World->GetLevelName(), m_demoHeader.szMapName);
|
||||
COM_FileBase(m_World->GetGameDir(), m_demoHeader.szDllDir);
|
||||
|
||||
m_demoHeader.mapCRC = 0;
|
||||
m_demoHeader.nDemoProtocol = DEMO_VERSION;
|
||||
m_demoHeader.nNetProtocolVersion = PROTOCOL_VERSION;
|
||||
m_demoHeader.nDirectoryOffset = 0;
|
||||
m_FileSystem->Write(&m_demoHeader, sizeof(m_demoHeader), m_FileHandle);
|
||||
|
||||
memset(&m_loadEntry, 0, sizeof(m_loadEntry));
|
||||
strcopy(m_loadEntry.szDescription, "LOADING");
|
||||
|
||||
m_loadEntry.nEntryType = 0;
|
||||
m_loadEntry.nOffset = m_FileSystem->Tell(m_FileHandle);
|
||||
|
||||
m_frameCount = 0;
|
||||
m_startTime = m_System->GetTime();
|
||||
|
||||
WriteSignonData();
|
||||
|
||||
b = 5;
|
||||
m_FileSystem->Write(&b, sizeof(unsigned char), m_FileHandle);
|
||||
|
||||
f = _LittleFloat(GetDemoTime());
|
||||
m_FileSystem->Write(&f, sizeof(float), m_FileHandle);
|
||||
|
||||
i = _LittleLong(m_frameCount);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
|
||||
m_loadEntry.nFileLength = m_FileSystem->Tell(m_FileHandle) - m_loadEntry.nOffset;
|
||||
|
||||
memset(&m_gameEntry, 0, sizeof(m_gameEntry));
|
||||
_snprintf(m_gameEntry.szDescription, sizeof(m_gameEntry.szDescription), "Playback");
|
||||
m_gameEntry.nEntryType = 1;
|
||||
m_gameEntry.nOffset = m_FileSystem->Tell(m_FileHandle);
|
||||
|
||||
b = 2;
|
||||
m_FileSystem->Write(&b, sizeof(unsigned char), m_FileHandle);
|
||||
|
||||
f = _LittleFloat(GetDemoTime());
|
||||
m_FileSystem->Write(&f, sizeof(float), m_FileHandle);
|
||||
|
||||
i = _LittleLong(m_frameCount);
|
||||
m_FileSystem->Write(&i, sizeof(int), m_FileHandle);
|
||||
|
||||
m_DemoState = DEMO_RECORDING;
|
||||
m_System->Printf("Start recording to %s.\n", m_FileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DemoFile::IsPlaying()
|
||||
{
|
||||
return m_DemoState == DEMO_PLAYING;
|
||||
}
|
||||
|
||||
bool DemoFile::LoadDemo(char *demoname)
|
||||
{
|
||||
if (IsRecording()) {
|
||||
m_System->Printf("Cannot load demo, still recording.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_FileSystem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CloseFile();
|
||||
|
||||
strcopy(m_FileName, demoname);
|
||||
_strlwr(m_FileName);
|
||||
|
||||
if (!strstr(m_FileName, ".dem")) {
|
||||
strcat(m_FileName, ".dem");
|
||||
}
|
||||
|
||||
m_FileHandle = m_FileSystem->Open(m_FileName, "rb");
|
||||
if (!m_FileHandle) {
|
||||
m_System->Printf("Coudn't open demo file %s.\n", m_FileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&m_demoHeader, 0, sizeof(m_demoHeader));
|
||||
m_FileSystem->Read(&m_demoHeader, sizeof(m_demoHeader), m_FileHandle);
|
||||
|
||||
if (strcmp(m_demoHeader.szFileStamp, "HLDEMO") != 0) {
|
||||
m_System->Printf("%s is not a HL demo file.\n", m_FileName);
|
||||
m_FileSystem->Close(m_FileHandle);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_demoHeader.nNetProtocolVersion != PROTOCOL_VERSION || m_demoHeader.nDemoProtocol != DEMO_VERSION) {
|
||||
m_System->Printf("WARNING! %s has an outdated demo format.\n", m_FileName);
|
||||
}
|
||||
|
||||
int fileMarker = m_FileSystem->Tell(m_FileHandle);
|
||||
m_FileSystem->Seek(m_FileHandle, m_demoHeader.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
|
||||
m_FileSystem->Read(&m_EntryNumber, sizeof(int), m_FileHandle);
|
||||
m_CurrentEntry = 0;
|
||||
|
||||
if (m_EntryNumber > 0 && m_EntryNumber <= 1024)
|
||||
{
|
||||
m_Entries = (demoentry_t *)Mem_ZeroMalloc(m_EntryNumber * MAX_DEMO_ENTRY);
|
||||
m_FileSystem->Read(m_Entries, m_EntryNumber * MAX_DEMO_ENTRY, m_FileHandle);
|
||||
m_FileSystem->Seek(m_FileHandle, m_Entries[m_CurrentEntry].nOffset, FILESYSTEM_SEEK_HEAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EntryNumber = 2;
|
||||
m_Entries = nullptr;
|
||||
|
||||
m_System->Printf("WARNING! Demo had bogus number of directory entries!\n");
|
||||
m_FileSystem->Seek(m_FileHandle, fileMarker, FILESYSTEM_SEEK_HEAD);
|
||||
}
|
||||
|
||||
m_startTime = m_System->GetTime();
|
||||
m_nextReadTime = m_System->GetTime();
|
||||
|
||||
m_Continuous = true;
|
||||
memset(&m_ServerInfo, 0, sizeof(m_ServerInfo));
|
||||
|
||||
strcopy(m_ServerInfo.address, m_DemoChannel->m_remote_address.ToBaseString());
|
||||
strcopy(m_ServerInfo.name, m_FileName);
|
||||
strcopy(m_ServerInfo.map, m_demoHeader.szMapName);
|
||||
strcopy(m_ServerInfo.gamedir, m_demoHeader.szDllDir);
|
||||
strcopy(m_ServerInfo.description, "Demo Playback");
|
||||
|
||||
m_ServerInfo.activePlayers = 0;
|
||||
m_ServerInfo.maxPlayers = MAX_CLIENTS;
|
||||
m_ServerInfo.protocol = m_demoHeader.nNetProtocolVersion;
|
||||
m_ServerInfo.type = GetServerType(HLST_Dedicated)[0];
|
||||
m_ServerInfo.os = GetServerOS()[0];
|
||||
m_ServerInfo.pw = '\0';
|
||||
m_ServerInfo.mod = false;
|
||||
m_DemoState = DEMO_PLAYING;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DemoFile::StopPlayBack()
|
||||
{
|
||||
if (m_DemoState != DEMO_PLAYING) {
|
||||
return;
|
||||
}
|
||||
|
||||
CloseFile();
|
||||
if (m_Server) {
|
||||
m_Server->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void DemoFile::ReadDemoPacket(BitBuffer *demoData, demo_info_t *demoInfo)
|
||||
{
|
||||
if (!m_FileHandle || (m_nextReadTime > m_System->GetTime() && m_Continuous)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int msglen;
|
||||
unsigned char msgbuf[MAX_POSSIBLE_MSG];
|
||||
float time;
|
||||
unsigned char cmd;
|
||||
int frame;
|
||||
int channel;
|
||||
int sampleSize;
|
||||
|
||||
bool readNextCmd = true;
|
||||
while (readNextCmd)
|
||||
{
|
||||
unsigned int curpos = m_FileSystem->Tell(m_FileHandle);
|
||||
if (m_FileSystem->Read(&cmd, sizeof(unsigned char), m_FileHandle) != 1) {
|
||||
StopPlayBack();
|
||||
return;
|
||||
}
|
||||
|
||||
m_FileSystem->Read(&time, sizeof(float), m_FileHandle);
|
||||
time = _LittleFloat(time);
|
||||
|
||||
m_FileSystem->Read(&frame, sizeof(int), m_FileHandle);
|
||||
frame = _LittleLong(frame);
|
||||
|
||||
if (cmd && cmd != 5) {
|
||||
m_nextReadTime = m_startTime + time;
|
||||
}
|
||||
|
||||
if (m_nextReadTime > m_System->GetTime() && m_Continuous) {
|
||||
m_FileSystem->Seek(m_FileHandle, curpos, FILESYSTEM_SEEK_HEAD);
|
||||
return;
|
||||
}
|
||||
|
||||
msglen = 0;
|
||||
|
||||
// TODO: Find out or guess the names of the opcode
|
||||
switch (cmd)
|
||||
{
|
||||
case 2:
|
||||
m_startTime = (float)m_System->GetTime();
|
||||
break;
|
||||
case 3:
|
||||
msglen = 64;
|
||||
break;
|
||||
case 4:
|
||||
msglen = 32;
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
if (++m_CurrentEntry >= m_EntryNumber) {
|
||||
StopPlayBack();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Entries) {
|
||||
m_FileSystem->Seek(m_FileHandle, m_Entries[m_CurrentEntry].nOffset, FILESYSTEM_SEEK_HEAD);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
msglen = 84;
|
||||
break;
|
||||
case 7:
|
||||
msglen = 8;
|
||||
break;
|
||||
case 8:
|
||||
{
|
||||
m_FileSystem->Read(&channel, sizeof(int), m_FileHandle);
|
||||
channel = _LittleLong(channel);
|
||||
|
||||
m_FileSystem->Read(&sampleSize, sizeof(int), m_FileHandle);
|
||||
sampleSize = _LittleLong(sampleSize);
|
||||
msglen = sampleSize + 16;
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
m_FileSystem->Read(&msglen, sizeof(int), m_FileHandle);
|
||||
msglen = _LittleLong(msglen);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
readNextCmd = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (msglen)
|
||||
{
|
||||
m_FileSystem->Read(msgbuf, msglen, m_FileHandle);
|
||||
|
||||
demoData->WriteByte(cmd);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case 8:
|
||||
demoData->WriteLong(channel);
|
||||
demoData->WriteLong(sampleSize);
|
||||
break;
|
||||
case 9:
|
||||
demoData->WriteLong(msglen);
|
||||
break;
|
||||
}
|
||||
|
||||
demoData->WriteBuf(msgbuf, msglen);
|
||||
}
|
||||
}
|
||||
|
||||
ReadDemoInfo(demoInfo);
|
||||
ReadSequenceInfo();
|
||||
|
||||
int length;
|
||||
if (m_FileSystem->Read(&length, sizeof(int), m_FileHandle) != 4) {
|
||||
m_System->DPrintf("WARNING! DemoFile::ReadDemoPacket: Bad demo length.\n");
|
||||
StopPlayBack();
|
||||
return;
|
||||
}
|
||||
|
||||
length = _LittleLong(length);
|
||||
if (length < 0) {
|
||||
m_System->DPrintf("WARNING! DemoFile::ReadDemoPacket: Demo message length < 0.\n");
|
||||
StopPlayBack();
|
||||
return;
|
||||
}
|
||||
|
||||
if (length > MAX_POSSIBLE_MSG) {
|
||||
m_System->DPrintf("WARNING! DemoFile::ReadDemoPacket: message length > MAX_POSSIBLE_MSG\n");
|
||||
StopPlayBack();
|
||||
return;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
if (m_FileSystem->Read(msgbuf, length, m_FileHandle) != length) {
|
||||
m_System->DPrintf("WARNING! DemoFile::ReadDemoPacket: Error reading demo message data.\n");
|
||||
StopPlayBack();
|
||||
return;
|
||||
}
|
||||
|
||||
NetPacket *p = new NetPacket;
|
||||
|
||||
p->connectionless = false;
|
||||
p->time = m_System->GetTime();
|
||||
p->seqnr = m_DemoChannel->m_incoming_sequence;
|
||||
p->data.Resize(length);
|
||||
p->data.WriteBuf(msgbuf, length);
|
||||
p->data.Reset();
|
||||
|
||||
m_DemoChannel->m_incomingPackets.AddHead(p);
|
||||
}
|
||||
}
|
||||
|
||||
void DemoFile::ReadDemoInfo(demo_info_t *demoInfo)
|
||||
{
|
||||
m_FileSystem->Read(demoInfo, sizeof(*demoInfo), m_FileHandle);
|
||||
|
||||
demoInfo->rp.cmd = &demoInfo->cmd;
|
||||
demoInfo->rp.movevars = &demoInfo->movevars;
|
||||
}
|
||||
|
||||
void DemoFile::ReadSequenceInfo()
|
||||
{
|
||||
m_FileSystem->Read(&m_DemoChannel->m_incoming_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Read(&m_DemoChannel->m_incoming_acknowledged, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Read(&m_DemoChannel->m_incoming_reliable_acknowledged, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Read(&m_DemoChannel->m_incoming_reliable_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Read(&m_DemoChannel->m_outgoing_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Read(&m_DemoChannel->m_reliable_sequence, sizeof(int), m_FileHandle);
|
||||
m_FileSystem->Read(&m_DemoChannel->m_last_reliable_sequence, sizeof(int), m_FileHandle);
|
||||
}
|
||||
|
||||
char *DemoFile::GetFileName()
|
||||
{
|
||||
return m_FileName;
|
||||
}
|
||||
|
||||
bool DemoFile::IsContinuous()
|
||||
{
|
||||
return m_Continuous;
|
||||
}
|
||||
|
||||
void DemoFile::SetContinuous(bool state)
|
||||
{
|
||||
m_Continuous = state;
|
||||
}
|
135
rehlds/HLTV/common/DemoFile.h
Normal file
135
rehlds/HLTV/common/DemoFile.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/IWorld.h>
|
||||
#include <HLTV/IServer.h>
|
||||
|
||||
#include "usercmd.h"
|
||||
#include "ref_params.h"
|
||||
#include "common/ServerInfo.h"
|
||||
|
||||
#include "vmodes.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
#define DEMO_VERSION 5
|
||||
#define MAX_DEMO_ENTRY 92
|
||||
|
||||
typedef struct demoheader_s {
|
||||
char szFileStamp[6];
|
||||
int nDemoProtocol;
|
||||
int nNetProtocolVersion;
|
||||
char szMapName[260];
|
||||
char szDllDir[260];
|
||||
CRC32_t mapCRC;
|
||||
int nDirectoryOffset;
|
||||
|
||||
} demoheader_t;
|
||||
|
||||
typedef struct demoentry_s {
|
||||
int nEntryType;
|
||||
char szDescription[64];
|
||||
int nFlags;
|
||||
int nCDTrack;
|
||||
float fTrackTime;
|
||||
int nFrames;
|
||||
int nOffset;
|
||||
int nFileLength;
|
||||
} demoentry_t;
|
||||
|
||||
typedef struct demo_info_s {
|
||||
float timestamp;
|
||||
ref_params_t rp;
|
||||
usercmd_t cmd;
|
||||
movevars_t movevars;
|
||||
vec3_t view;
|
||||
int viewmodel;
|
||||
} demo_info_t;
|
||||
|
||||
class NetChannel;
|
||||
class DemoFile {
|
||||
public:
|
||||
DemoFile();
|
||||
virtual ~DemoFile() {}
|
||||
|
||||
void Init(IWorld *world, IServer *server, NetChannel *channel);
|
||||
bool LoadDemo(char *demoname);
|
||||
void StopPlayBack();
|
||||
bool StartRecording(char *newName);
|
||||
void CloseFile();
|
||||
void Reset();
|
||||
void SetContinuous(bool state);
|
||||
bool IsContinuous();
|
||||
bool IsPlaying();
|
||||
bool IsRecording();
|
||||
char *GetFileName();
|
||||
void ReadDemoPacket(BitBuffer *demoData, demo_info_t *demoInfo);
|
||||
void WriteDemoMessage(BitBuffer *unreliableData, BitBuffer *reliableData);
|
||||
void WriteUpdateClientData(client_data_t *cdata);
|
||||
float GetDemoTime();
|
||||
void ReadSequenceInfo();
|
||||
void ReadDemoInfo(demo_info_t *demoInfo);
|
||||
void WriteDemoStartup(BitBuffer *buffer);
|
||||
void WriteSequenceInfo();
|
||||
void WriteDemoInfo(demo_info_t *demoInfo);
|
||||
void WriteSignonData();
|
||||
|
||||
serverinfo_t m_ServerInfo;
|
||||
|
||||
private:
|
||||
char m_FileName[MAX_PATH];
|
||||
|
||||
enum DemoState {
|
||||
DEMO_IDLE,
|
||||
DEMO_PLAYING,
|
||||
DEMO_RECORDING
|
||||
};
|
||||
int m_DemoState;
|
||||
unsigned int m_frameCount;
|
||||
FileHandle_t m_FileHandle;
|
||||
demoheader_t m_demoHeader;
|
||||
demoentry_t m_loadEntry;
|
||||
demoentry_t m_gameEntry;
|
||||
demo_info_t m_zeroDemoInfo;
|
||||
|
||||
float m_startTime;
|
||||
float m_nextReadTime;
|
||||
|
||||
NetChannel *m_DemoChannel;
|
||||
int m_StartPos;
|
||||
int m_EntryNumber;
|
||||
int m_CurrentEntry;
|
||||
demoentry_t *m_Entries;
|
||||
bool m_Continuous;
|
||||
|
||||
IBaseSystem *m_System;
|
||||
IWorld *m_World;
|
||||
IServer *m_Server;
|
||||
IFileSystem *m_FileSystem;
|
||||
};
|
683
rehlds/HLTV/common/DirectorCmd.cpp
Normal file
683
rehlds/HLTV/common/DirectorCmd.cpp
Normal file
@ -0,0 +1,683 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
// define DRC_CMD_*
|
||||
char *DirectorCmd::m_CMD_Name[] =
|
||||
{
|
||||
"NONE",
|
||||
"START",
|
||||
"EVENT",
|
||||
"MODE",
|
||||
"CAMERA",
|
||||
"TIMESCALE",
|
||||
"MESSAGE",
|
||||
"SOUND",
|
||||
"STATUS",
|
||||
"BANNER",
|
||||
"STUFFTEXT",
|
||||
"CHASE",
|
||||
"INEYE",
|
||||
"MAP",
|
||||
"CAMPATH",
|
||||
"WAYPOINTS"
|
||||
};
|
||||
|
||||
DirectorCmd::DirectorCmd()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
DirectorCmd::~DirectorCmd()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetEventData(int &entity1, int &entity2, int &flags)
|
||||
{
|
||||
if (m_Type != DRC_CMD_EVENT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
entity1 = m_Data.ReadWord();
|
||||
entity2 = m_Data.ReadWord();
|
||||
flags = m_Data.ReadLong();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetModeData(int &mode)
|
||||
{
|
||||
if (m_Type != DRC_CMD_MODE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
mode = m_Data.ReadByte();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetChaseData(int &entity1, int &entity2, float &distance, int &flags)
|
||||
{
|
||||
if (m_Type != DRC_CMD_CHASE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
entity1 = m_Data.ReadByte();
|
||||
entity2 = m_Data.ReadByte();
|
||||
distance = m_Data.ReadFloat();
|
||||
flags = m_Data.ReadByte();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetInEyeData(int &player)
|
||||
{
|
||||
if (m_Type != DRC_CMD_INEYE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
player = m_Data.ReadByte();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetMapData(int &entity, float &angle, float &distance)
|
||||
{
|
||||
if (m_Type != DRC_CMD_MAP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
entity = m_Data.ReadByte();
|
||||
angle = m_Data.ReadFloat();
|
||||
distance = m_Data.ReadFloat();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetCameraData(vec_t *position, vec_t *angles, float &fov, int &entity)
|
||||
{
|
||||
if (m_Type != DRC_CMD_CAMERA) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
|
||||
position[0] = m_Data.ReadCoord();
|
||||
position[1] = m_Data.ReadCoord();
|
||||
position[2] = m_Data.ReadCoord();
|
||||
|
||||
angles[0] = m_Data.ReadCoord();
|
||||
angles[1] = m_Data.ReadCoord();
|
||||
angles[2] = m_Data.ReadCoord();
|
||||
|
||||
fov = (float)m_Data.ReadByte();
|
||||
entity = m_Data.ReadWord();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetCamPathData(vec_t *position, vec_t *angles, float &fov, int &flags)
|
||||
{
|
||||
if (m_Type != DRC_CMD_CAMPATH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
|
||||
position[0] = m_Data.ReadCoord();
|
||||
position[1] = m_Data.ReadCoord();
|
||||
position[2] = m_Data.ReadCoord();
|
||||
|
||||
angles[0] = m_Data.ReadCoord();
|
||||
angles[1] = m_Data.ReadCoord();
|
||||
angles[2] = m_Data.ReadCoord();
|
||||
|
||||
fov = (float)m_Data.ReadByte();
|
||||
flags = m_Data.ReadByte();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetSoundData(char *name, float &volume)
|
||||
{
|
||||
if (m_Type != DRC_CMD_SOUND) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
strcpy(name, m_Data.ReadString());
|
||||
volume = m_Data.ReadFloat();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float DirectorCmd::GetTime()
|
||||
{
|
||||
return m_Time;
|
||||
}
|
||||
|
||||
int DirectorCmd::GetType()
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
char *DirectorCmd::GetName()
|
||||
{
|
||||
return m_CMD_Name[m_Type];
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetTimeScaleData(float &factor)
|
||||
{
|
||||
if (m_Type != DRC_CMD_TIMESCALE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
factor = m_Data.ReadFloat();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetWayPointsData(int &number)
|
||||
{
|
||||
if (m_Type != DRC_CMD_WAYPOINTS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
number = m_Data.ReadByte();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetMessageData(int &effect, int &color, vec_t *position, float &fadein, float &fadeout, float &holdtime, float &fxtime, char *text)
|
||||
{
|
||||
if (m_Type != DRC_CMD_MESSAGE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
|
||||
effect = m_Data.ReadByte();
|
||||
color = m_Data.ReadLong();
|
||||
|
||||
position[0] = m_Data.ReadFloat();
|
||||
position[1] = m_Data.ReadFloat();
|
||||
|
||||
fadein = m_Data.ReadFloat();
|
||||
fadeout = m_Data.ReadFloat();
|
||||
holdtime = m_Data.ReadFloat();
|
||||
fxtime = m_Data.ReadFloat();
|
||||
strcpy(text, m_Data.ReadString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetStatusData(int &slots, int &spectators, int &proxies)
|
||||
{
|
||||
if (m_Type != DRC_CMD_STATUS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
slots = m_Data.ReadLong();
|
||||
spectators = m_Data.ReadLong();
|
||||
proxies = m_Data.ReadWord();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetBannerData(char *filename)
|
||||
{
|
||||
if (m_Type != DRC_CMD_BANNER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
strcpy(filename, m_Data.ReadString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectorCmd::GetStuffTextData(char *commands)
|
||||
{
|
||||
if (m_Type != DRC_CMD_STUFFTEXT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data.Reset();
|
||||
strcpy(commands, m_Data.ReadString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DirectorCmd::SetEventData(int entity1, int entity2, int flags)
|
||||
{
|
||||
m_Type = DRC_CMD_EVENT;
|
||||
Resize(8);
|
||||
|
||||
m_Data.WriteWord(entity1);
|
||||
m_Data.WriteWord(entity2);
|
||||
m_Data.WriteLong(flags);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetChaseData(int entity1, int entity2, float distance, int flags)
|
||||
{
|
||||
m_Type = DRC_CMD_CHASE;
|
||||
Resize(9);
|
||||
|
||||
m_Data.WriteWord(entity1);
|
||||
m_Data.WriteWord(entity2);
|
||||
m_Data.WriteFloat(distance);
|
||||
m_Data.WriteByte(flags);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetInEyeData(int entity)
|
||||
{
|
||||
m_Type = DRC_CMD_INEYE;
|
||||
Resize(2);
|
||||
|
||||
m_Data.WriteWord(entity);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetMapData(int entity, float angle, float distance)
|
||||
{
|
||||
m_Type = DRC_CMD_MAP;
|
||||
Resize(10);
|
||||
|
||||
m_Data.WriteWord(entity);
|
||||
m_Data.WriteFloat(angle);
|
||||
m_Data.WriteFloat(distance);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetStartData()
|
||||
{
|
||||
m_Type = DRC_CMD_START;
|
||||
Resize(0);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetModeData(int mode)
|
||||
{
|
||||
m_Type = DRC_CMD_MODE;
|
||||
Resize(1);
|
||||
|
||||
m_Data.WriteByte(mode);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetCameraData(vec_t *position, vec_t *angles, float fov, int entity)
|
||||
{
|
||||
m_Type = DRC_CMD_CAMERA;
|
||||
Resize(15);
|
||||
|
||||
m_Data.WriteCoord(position[0]);
|
||||
m_Data.WriteCoord(position[1]);
|
||||
m_Data.WriteCoord(position[2]);
|
||||
m_Data.WriteCoord(angles[0]);
|
||||
m_Data.WriteCoord(angles[1]);
|
||||
m_Data.WriteCoord(angles[2]);
|
||||
m_Data.WriteByte((int)fov);
|
||||
m_Data.WriteWord(entity);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetCamPathData(vec_t *position, vec_t *angles, float fov, int flags)
|
||||
{
|
||||
m_Type = DRC_CMD_CAMPATH;
|
||||
Resize(14);
|
||||
|
||||
m_Data.WriteCoord(position[0]);
|
||||
m_Data.WriteCoord(position[1]);
|
||||
m_Data.WriteCoord(position[2]);
|
||||
m_Data.WriteCoord(angles[0]);
|
||||
m_Data.WriteCoord(angles[1]);
|
||||
m_Data.WriteCoord(angles[2]);
|
||||
m_Data.WriteByte((int)fov);
|
||||
m_Data.WriteByte(flags);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetSoundData(char *name, float volume)
|
||||
{
|
||||
int len = strlen(name);
|
||||
m_Type = DRC_CMD_SOUND;
|
||||
Resize(len + 5);
|
||||
|
||||
m_Data.WriteString(name);
|
||||
m_Data.WriteFloat(volume);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetTimeScaleData(float factor)
|
||||
{
|
||||
m_Type = DRC_CMD_TIMESCALE;
|
||||
|
||||
Resize(sizeof(float));
|
||||
m_Data.WriteFloat(factor);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetTime(float time)
|
||||
{
|
||||
m_Time = time;
|
||||
}
|
||||
|
||||
void DirectorCmd::SetMessageData(int effect, unsigned int color, vec_t *position, float fadein, float fadeout, float holdtime, float fxtime, char *text)
|
||||
{
|
||||
int len = strlen(text);
|
||||
m_Type = DRC_CMD_MESSAGE;
|
||||
Resize(len + 30);
|
||||
|
||||
m_Data.WriteByte(effect);
|
||||
m_Data.WriteLong(color);
|
||||
m_Data.WriteFloat(position[0]);
|
||||
m_Data.WriteFloat(position[1]);
|
||||
m_Data.WriteFloat(fadein);
|
||||
m_Data.WriteFloat(fadeout);
|
||||
m_Data.WriteFloat(holdtime);
|
||||
m_Data.WriteFloat(fxtime);
|
||||
m_Data.WriteString(text);
|
||||
}
|
||||
|
||||
void DirectorCmd::Copy(DirectorCmd *cmd)
|
||||
{
|
||||
Clear();
|
||||
|
||||
m_Time = cmd->m_Time;
|
||||
m_Type = cmd->m_Type;
|
||||
m_Size = cmd->m_Size;
|
||||
m_Index = cmd->m_Index;
|
||||
|
||||
m_Data.Resize(m_Size);
|
||||
m_Data.WriteBuf(cmd->m_Data.GetData(), m_Size);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetStatusData(int slots, int spectators, int proxies)
|
||||
{
|
||||
m_Type = DRC_CMD_STATUS;
|
||||
Resize(10);
|
||||
|
||||
m_Data.WriteLong(slots);
|
||||
m_Data.WriteLong(spectators);
|
||||
m_Data.WriteWord(proxies);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetBannerData(char *filename)
|
||||
{
|
||||
m_Type = DRC_CMD_BANNER;
|
||||
|
||||
int len = strlen(filename);
|
||||
Resize(len + 1);
|
||||
m_Data.WriteString(filename);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetStuffTextData(char *commands)
|
||||
{
|
||||
m_Type = DRC_CMD_STUFFTEXT;
|
||||
|
||||
int len = strlen(commands);
|
||||
Resize(len + 1);
|
||||
m_Data.WriteString(commands);
|
||||
}
|
||||
|
||||
void DirectorCmd::SetWayPoints(int number)
|
||||
{
|
||||
m_Type = DRC_CMD_WAYPOINTS;
|
||||
|
||||
Resize(1);
|
||||
m_Data.WriteByte(number);
|
||||
}
|
||||
|
||||
bool DirectorCmd::ReadFromStream(BitBuffer *stream)
|
||||
{
|
||||
char *string;
|
||||
unsigned char *start;
|
||||
int length;
|
||||
|
||||
if (!stream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Clear();
|
||||
m_Type = stream->ReadByte();
|
||||
|
||||
switch (m_Type)
|
||||
{
|
||||
case DRC_CMD_START:
|
||||
Resize(0);
|
||||
break;
|
||||
case DRC_CMD_EVENT:
|
||||
Resize(8);
|
||||
m_Data.WriteBuf(stream, 8);
|
||||
break;
|
||||
case DRC_CMD_MODE:
|
||||
Resize(1);
|
||||
m_Data.WriteBuf(stream, 1);
|
||||
break;
|
||||
case DRC_CMD_CAMERA:
|
||||
Resize(15);
|
||||
m_Data.WriteBuf(stream, 15);
|
||||
break;
|
||||
case DRC_CMD_TIMESCALE:
|
||||
Resize(4);
|
||||
m_Data.WriteBuf(stream, 4);
|
||||
break;
|
||||
case DRC_CMD_MESSAGE:
|
||||
{
|
||||
start = stream->m_CurByte;
|
||||
stream->SkipBytes(29);
|
||||
|
||||
string = stream->ReadString();
|
||||
length = strlen(string);
|
||||
Resize(length + 30);
|
||||
|
||||
m_Data.WriteBuf(start, 29);
|
||||
m_Data.WriteBuf(string, length + 1);
|
||||
break;
|
||||
}
|
||||
case DRC_CMD_SOUND:
|
||||
{
|
||||
string = stream->ReadString();
|
||||
length = strlen(string);
|
||||
Resize(length + 5);
|
||||
|
||||
m_Data.WriteBuf(string, length + 1);
|
||||
m_Data.WriteFloat(stream->ReadFloat());
|
||||
|
||||
break;
|
||||
}
|
||||
case DRC_CMD_STATUS:
|
||||
Resize(10);
|
||||
m_Data.WriteBuf(stream, 10);
|
||||
break;
|
||||
case DRC_CMD_BANNER:
|
||||
{
|
||||
string = stream->ReadString();
|
||||
length = strlen(string) + 1;
|
||||
|
||||
Resize(length);
|
||||
m_Data.WriteBuf(string, length);
|
||||
break;
|
||||
}
|
||||
case DRC_CMD_STUFFTEXT:
|
||||
{
|
||||
string = stream->ReadString();
|
||||
length = strlen(string) + 1;
|
||||
|
||||
Resize(length);
|
||||
m_Data.WriteBuf(string, length);
|
||||
break;
|
||||
}
|
||||
case DRC_CMD_CHASE:
|
||||
Resize(7);
|
||||
m_Data.WriteBuf(stream, 7);
|
||||
break;
|
||||
case DRC_CMD_INEYE:
|
||||
Resize(1);
|
||||
m_Data.WriteBuf(stream, 1);
|
||||
break;
|
||||
case DRC_CMD_MAP:
|
||||
Resize(10);
|
||||
m_Data.WriteBuf(stream, 15);
|
||||
break;
|
||||
case DRC_CMD_CAMPATH:
|
||||
Resize(14);
|
||||
m_Data.WriteBuf(stream, 14);
|
||||
break;
|
||||
case DRC_CMD_WAYPOINTS:
|
||||
{
|
||||
Resize(1);
|
||||
length = stream->ReadByte();
|
||||
m_Data.WriteByte(length);
|
||||
stream->SkipBytes(length * 14);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case DRC_CMD_NONE:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DirectorCmd::WriteToStream(BitBuffer *stream)
|
||||
{
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_Type > DRC_CMD_NONE && m_Type <= DRC_CMD_LAST) && m_Size < 255)
|
||||
{
|
||||
stream->WriteByte(svc_director);
|
||||
stream->WriteByte(m_Size + 1);
|
||||
stream->WriteByte(m_Type);
|
||||
stream->WriteBuf(m_Data.GetData(), m_Size);
|
||||
}
|
||||
}
|
||||
|
||||
char *DirectorCmd::ToString()
|
||||
{
|
||||
int i1, i2, i3;
|
||||
float f1, f2, f3, f4;
|
||||
vec3_t v1, v2;
|
||||
|
||||
char *t1 = m_CMD_Name[m_Type];
|
||||
char t2[1024];
|
||||
|
||||
static char s[1024];
|
||||
memset(s, 0, sizeof(s));
|
||||
|
||||
switch (m_Type)
|
||||
{
|
||||
case DRC_CMD_START:
|
||||
sprintf(s, "%s", t1);
|
||||
break;
|
||||
case DRC_CMD_EVENT:
|
||||
GetEventData(i1, i2, i3);
|
||||
sprintf(s, "%s %i %i %i", t1, i1, i2, i3);
|
||||
break;
|
||||
case DRC_CMD_MODE:
|
||||
GetModeData(i1);
|
||||
sprintf(s, "%s %i", t1, i1);
|
||||
break;
|
||||
case DRC_CMD_CAMERA:
|
||||
GetCameraData(v1, v2, f1, i1);
|
||||
sprintf(s, "%s (%.1f %.1f %.1f) (%.1f %.1f %.1f) %.1f %i", t1, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], f1, i1);
|
||||
break;
|
||||
case DRC_CMD_TIMESCALE:
|
||||
GetTimeScaleData(f1);
|
||||
sprintf(s, "%s %.2f", t1, f1);
|
||||
break;
|
||||
case DRC_CMD_MESSAGE:
|
||||
GetMessageData(i1, i2, v1, f1, f2, f3, f4, t2);
|
||||
sprintf(s, "%s \"%s\" %i %x (%.2f %.2f) %.1f, %.1f %.1f %.1f", t1, t2, i1, i2, v1[0], v1[1], f1, f2, f3, f4);
|
||||
break;
|
||||
case DRC_CMD_SOUND:
|
||||
GetSoundData(t2, f1);
|
||||
sprintf(s, "%s \"%s\" %.2f", t1, t2, f1);
|
||||
break;
|
||||
case DRC_CMD_STATUS:
|
||||
GetStatusData(i1, i2, i3);
|
||||
sprintf(s, "%s %i %i %i", t1, i1, i2, i3);
|
||||
break;
|
||||
case DRC_CMD_BANNER:
|
||||
GetBannerData(t2);
|
||||
sprintf(s, "%s \"%s\"", t1, t2);
|
||||
break;
|
||||
case DRC_CMD_STUFFTEXT:
|
||||
GetStuffTextData(t2);
|
||||
sprintf(s, "%s \"%s\"", t1, t2);
|
||||
break;
|
||||
case DRC_CMD_CHASE:
|
||||
GetChaseData(i1, i2, f1, i3);
|
||||
sprintf(s, "%s %i %i %.1f %i", t1, i1, i2, f1, i3);
|
||||
break;
|
||||
case DRC_CMD_INEYE:
|
||||
GetInEyeData(i1);
|
||||
sprintf(s, "%s %i", t1, i1);
|
||||
break;
|
||||
case DRC_CMD_MAP:
|
||||
GetMapData(i1, f1, f2);
|
||||
sprintf(s, "%s %i %.1f %.1f", t1, i1, f1, f2);
|
||||
break;
|
||||
case DRC_CMD_CAMPATH:
|
||||
GetCamPathData(v1, v2, f1, i1);
|
||||
sprintf(s, "%s (%.1f %.1f %.1f) (%.1f %.1f %.1f) %.1f %i", t1, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], f1, i1);
|
||||
break;
|
||||
case DRC_CMD_WAYPOINTS:
|
||||
GetWayPointsData(i1);
|
||||
sprintf(s, "%s %i", t1, i1);
|
||||
break;
|
||||
default:
|
||||
case DRC_CMD_NONE:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void DirectorCmd::FromString(char *string)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void DirectorCmd::Clear()
|
||||
{
|
||||
m_Type = 0;
|
||||
m_Time = 0;
|
||||
|
||||
m_Data.Free();
|
||||
}
|
||||
|
||||
void DirectorCmd::Resize(int size)
|
||||
{
|
||||
m_Data.Resize(size);
|
||||
m_Size = size;
|
||||
}
|
89
rehlds/HLTV/common/DirectorCmd.h
Normal file
89
rehlds/HLTV/common/DirectorCmd.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hltv.h"
|
||||
#include "BitBuffer.h"
|
||||
|
||||
class DirectorCmd {
|
||||
public:
|
||||
DirectorCmd();
|
||||
virtual ~DirectorCmd();
|
||||
|
||||
void Clear();
|
||||
void Copy(DirectorCmd *cmd);
|
||||
void Resize(int size);
|
||||
void FromString(char *string);
|
||||
char *ToString();
|
||||
void WriteToStream(BitBuffer *stream);
|
||||
bool ReadFromStream(BitBuffer *stream);
|
||||
int GetType();
|
||||
char *GetName();
|
||||
float GetTime();
|
||||
void SetTime(float time);
|
||||
void SetStartData();
|
||||
void SetEventData(int entity1, int entity2, int flags);
|
||||
void SetChaseData(int entity1, int entity2, float distance, int flags);
|
||||
void SetModeData(int mode);
|
||||
void SetInEyeData(int entity);
|
||||
void SetMapData(int entity, float angle, float distance);
|
||||
void SetCameraData(vec_t *position, vec_t *angles, float fov, int entity);
|
||||
void SetCamPathData(vec_t *position, vec_t *angles, float fov, int flags);
|
||||
void SetTimeScaleData(float factor);
|
||||
void SetMessageData(int effect, unsigned int color, vec_t *position, float fadein, float fadeout, float holdtime, float fxtime, char *text);
|
||||
void SetSoundData(char *name, float volume);
|
||||
void SetStatusData(int slots, int spectators, int proxies);
|
||||
void SetBannerData(char *filename);
|
||||
void SetStuffTextData(char *commands);
|
||||
void SetWayPoints(int number);
|
||||
|
||||
bool GetEventData(int &entity1, int &entity2, int &flags);
|
||||
bool GetChaseData(int &entity1, int &entity2, float &distance, int &flags);
|
||||
bool GetInEyeData(int &player);
|
||||
bool GetMapData(int &entity, float &angle, float &distance);
|
||||
bool GetCameraData(vec_t *position, vec_t *angles, float &fov, int &entity);
|
||||
bool GetCamPathData(vec_t *position, vec_t *angles, float &fov, int &flags);
|
||||
bool GetTimeScaleData(float &factor);
|
||||
bool GetMessageData(int &effect, int &color, vec_t *position, float &fadein, float &fadeout, float &holdtime, float &fxtime, char *text);
|
||||
bool GetSoundData(char *name, float &volume);
|
||||
bool GetModeData(int &mode);
|
||||
bool GetStatusData(int &slots, int &spectators, int &proxies);
|
||||
bool GetBannerData(char *filename);
|
||||
bool GetStuffTextData(char *commands);
|
||||
bool GetWayPointsData(int &number);
|
||||
|
||||
public:
|
||||
static char *m_CMD_Name[];
|
||||
|
||||
float m_Time;
|
||||
int m_Type;
|
||||
int m_Size;
|
||||
BitBuffer m_Data;
|
||||
int m_Index;
|
||||
};
|
431
rehlds/HLTV/common/InfoString.cpp
Normal file
431
rehlds/HLTV/common/InfoString.cpp
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
InfoString::InfoString(char *string, unsigned int maxSize)
|
||||
: m_String(nullptr), m_MaxSize(0)
|
||||
{
|
||||
unsigned int len = strlen(string) + 1;
|
||||
if (len < maxSize) {
|
||||
len = maxSize;
|
||||
}
|
||||
|
||||
SetMaxSize(len);
|
||||
SetString(string);
|
||||
}
|
||||
|
||||
InfoString::InfoString()
|
||||
: m_String(nullptr), m_MaxSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
InfoString::InfoString(unsigned int maxSize)
|
||||
: m_String(nullptr), m_MaxSize(0)
|
||||
{
|
||||
SetMaxSize(maxSize);
|
||||
}
|
||||
|
||||
InfoString::InfoString(char *string)
|
||||
: m_String(nullptr), m_MaxSize(0)
|
||||
{
|
||||
unsigned int len = strlen(string) + 1;
|
||||
if (len < MAX_INFO_LEN) {
|
||||
len = MAX_INFO_LEN;
|
||||
}
|
||||
|
||||
SetMaxSize(len);
|
||||
SetString(string);
|
||||
}
|
||||
|
||||
InfoString::~InfoString()
|
||||
{
|
||||
if (m_String) {
|
||||
free(m_String);
|
||||
m_String = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool InfoString::SetString(char *string)
|
||||
{
|
||||
if (!m_String || !string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen(string) >= m_MaxSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
strncpy(m_String, string, m_MaxSize - 1);
|
||||
m_String[m_MaxSize - 1] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
void InfoString::SetMaxSize(unsigned int maxSize)
|
||||
{
|
||||
char *newBuffer = (char *)Mem_ZeroMalloc(maxSize);
|
||||
if (!newBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_String)
|
||||
{
|
||||
if (maxSize > strlen(m_String)) {
|
||||
strncpy(newBuffer, m_String, maxSize - 1);
|
||||
newBuffer[maxSize - 1] = '\0';
|
||||
}
|
||||
|
||||
free(m_String);
|
||||
}
|
||||
|
||||
m_MaxSize = maxSize;
|
||||
m_String = newBuffer;
|
||||
}
|
||||
|
||||
int InfoString::GetMaxSize()
|
||||
{
|
||||
return m_MaxSize;
|
||||
}
|
||||
|
||||
int InfoString::GetCurrentSize()
|
||||
{
|
||||
return strlen(m_String);
|
||||
}
|
||||
|
||||
void InfoString::Clear()
|
||||
{
|
||||
if (m_String) {
|
||||
memset(m_String, 0, m_MaxSize);
|
||||
}
|
||||
}
|
||||
|
||||
char *InfoString::GetString()
|
||||
{
|
||||
return m_String;
|
||||
}
|
||||
|
||||
// Searches the string for the given key and returns the associated value, or an empty string.
|
||||
char *InfoString::ValueForKey(const char *key)
|
||||
{
|
||||
// use two buffers so compares work without stomping on each other
|
||||
static char value[MAX_INFO_VALUES][MAX_INFO_VALUE];
|
||||
static int valueindex;
|
||||
char pkey[MAX_INFO_KEY];
|
||||
char *c;
|
||||
char *s = m_String;
|
||||
int nCount;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
if (*s == '\\') {
|
||||
// skip the slash
|
||||
s++;
|
||||
}
|
||||
|
||||
// Copy a key
|
||||
nCount = 0;
|
||||
c = pkey;
|
||||
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s)
|
||||
{
|
||||
// key should end with a \, not a nullptr, but suppose its value as absent
|
||||
return "";
|
||||
}
|
||||
|
||||
if (nCount >= MAX_INFO_KEY)
|
||||
{
|
||||
s++;
|
||||
// skip oversized key chars till the slash or EOL
|
||||
continue;
|
||||
}
|
||||
|
||||
*c++ = *s++;
|
||||
nCount++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
|
||||
// skip the slash
|
||||
s++;
|
||||
|
||||
// Copy a value
|
||||
nCount = 0;
|
||||
c = value[valueindex];
|
||||
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s)
|
||||
{
|
||||
// allow value to be ended with nullptr
|
||||
break;
|
||||
}
|
||||
|
||||
if (nCount >= MAX_INFO_VALUE)
|
||||
{
|
||||
s++;
|
||||
// skip oversized value chars till the slash or EOL
|
||||
continue;
|
||||
}
|
||||
|
||||
*c++ = *s++;
|
||||
nCount++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
|
||||
if (!strcmp(key, pkey))
|
||||
{
|
||||
c = value[valueindex];
|
||||
valueindex = (valueindex + 1) % MAX_INFO_VALUES;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool InfoString::RemoveKey(const char *key)
|
||||
{
|
||||
char *start;
|
||||
char pkey[MAX_INFO_KEY];
|
||||
char value[MAX_INFO_VALUE];
|
||||
char *c;
|
||||
char *s;
|
||||
int cmpsize;
|
||||
int nCount;
|
||||
|
||||
s = m_String;
|
||||
|
||||
if (strchr(key, '\\')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmpsize = strlen(key);
|
||||
if (cmpsize > MAX_INFO_LEN - 1) {
|
||||
cmpsize = MAX_INFO_LEN - 1;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
while (*s)
|
||||
{
|
||||
start = s;
|
||||
if (*s == '\\') {
|
||||
// skip the slash
|
||||
s++;
|
||||
}
|
||||
|
||||
// Copy a key
|
||||
nCount = 0;
|
||||
c = pkey;
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s) {
|
||||
// key should end with a \, not a nullptr, but allow to remove it
|
||||
break;
|
||||
}
|
||||
|
||||
if (nCount >= MAX_INFO_KEY)
|
||||
{
|
||||
s++;
|
||||
// skip oversized key chars till the slash or EOL
|
||||
continue;
|
||||
}
|
||||
|
||||
*c++ = *s++;
|
||||
nCount++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
if (*s) {
|
||||
// skip the slash
|
||||
s++;
|
||||
}
|
||||
|
||||
// Copy a value
|
||||
nCount = 0;
|
||||
c = value;
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s) {
|
||||
// allow value to be ended with nullptr
|
||||
break;
|
||||
}
|
||||
|
||||
if (nCount >= MAX_INFO_VALUE)
|
||||
{
|
||||
s++;
|
||||
// skip oversized value chars till the slash or EOL
|
||||
continue;
|
||||
}
|
||||
|
||||
*c++ = *s++;
|
||||
nCount++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
|
||||
// Compare keys
|
||||
if (!strncmp(key, pkey, cmpsize) )
|
||||
{
|
||||
found = true;
|
||||
strcpy_safe(start, s); // remove this part
|
||||
s = start; // continue searching
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void InfoString::RemovePrefixedKeys(char prefix)
|
||||
{
|
||||
char pkey[MAX_INFO_KEY];
|
||||
char value[MAX_INFO_VALUE];
|
||||
char *start;
|
||||
char *c;
|
||||
char *s;
|
||||
int nCount;
|
||||
|
||||
s = m_String;
|
||||
while (*s)
|
||||
{
|
||||
start = s;
|
||||
|
||||
if (*s == '\\') {
|
||||
// skip the slash
|
||||
s++;
|
||||
}
|
||||
|
||||
// Copy a key
|
||||
nCount = 0;
|
||||
c = pkey;
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s) {
|
||||
// key should end with a \, not a nullptr, but allow to remove it
|
||||
break;
|
||||
}
|
||||
|
||||
if (nCount >= MAX_INFO_KEY)
|
||||
{
|
||||
s++;
|
||||
// skip oversized key chars till the slash or EOL
|
||||
continue;
|
||||
}
|
||||
|
||||
*c++ = *s++;
|
||||
nCount++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
if (*s) {
|
||||
// skip the slash
|
||||
s++;
|
||||
}
|
||||
|
||||
// Copy a value
|
||||
nCount = 0;
|
||||
c = value;
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s) {
|
||||
// allow value to be ended with nullptr
|
||||
break;
|
||||
}
|
||||
|
||||
if (nCount >= MAX_INFO_VALUE) {
|
||||
s++;
|
||||
// skip oversized value chars till the slash or EOL
|
||||
continue;
|
||||
}
|
||||
|
||||
*c++ = *s++;
|
||||
nCount++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
|
||||
// Compare prefix
|
||||
if (pkey[0] == prefix)
|
||||
{
|
||||
strcpy_safe(start, s); // remove this part
|
||||
s = start; // continue searching
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool InfoString::SetValueForStarKey(const char *key, const char *value)
|
||||
{
|
||||
char newtoken[MAX_INFO_LEN + 4];
|
||||
if (strstr(key, "\\") || strstr(value, "\\")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strstr(key, "\"") || strstr(value, "\"")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen(key) > MAX_INFO_KEY || strlen(value) > MAX_INFO_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove current key/value and return if we doesn't specified to set a value
|
||||
RemoveKey(key);
|
||||
|
||||
if (!value || !strlen(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create key/value pair
|
||||
_snprintf(newtoken, sizeof(newtoken), "\\%s\\%s", key, value);
|
||||
|
||||
int length = strlen(m_String);
|
||||
if ((length + strlen(newtoken)) < m_MaxSize)
|
||||
{
|
||||
char *v = newtoken;
|
||||
char *s = m_String + length;
|
||||
unsigned char c;
|
||||
|
||||
while (*v)
|
||||
{
|
||||
c = (unsigned char)*v++;
|
||||
*s++ = c;
|
||||
}
|
||||
|
||||
*s = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InfoString::SetValueForKey(const char *key, const char *value)
|
||||
{
|
||||
return SetValueForStarKey(key, value);
|
||||
}
|
65
rehlds/HLTV/common/InfoString.h
Normal file
65
rehlds/HLTV/common/InfoString.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class InfoString {
|
||||
public:
|
||||
InfoString();
|
||||
InfoString(unsigned int maxSize);
|
||||
InfoString(char *string);
|
||||
InfoString(char *string, unsigned int maxSize);
|
||||
|
||||
virtual ~InfoString();
|
||||
|
||||
void SetMaxSize(unsigned int maxSize);
|
||||
bool SetString(char *string);
|
||||
char *GetString();
|
||||
|
||||
void Clear();
|
||||
int GetMaxSize();
|
||||
int GetCurrentSize();
|
||||
|
||||
bool SetValueForStarKey(const char *key, const char *value);
|
||||
char *ValueForKey(const char *key);
|
||||
bool RemoveKey(const char *key);
|
||||
void RemovePrefixedKeys(char prefix);
|
||||
bool SetValueForKey(const char *key, const char *value);
|
||||
|
||||
protected:
|
||||
enum {
|
||||
MAX_INFO_KEY = 512,
|
||||
MAX_INFO_VALUE = 512,
|
||||
|
||||
MAX_INFO_LEN = 256,
|
||||
MAX_INFO_VALUES = 4
|
||||
};
|
||||
|
||||
unsigned int m_MaxSize;
|
||||
char *m_String;
|
||||
};
|
170
rehlds/HLTV/common/NetAddress.cpp
Normal file
170
rehlds/HLTV/common/NetAddress.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
NetAddress::NetAddress()
|
||||
{
|
||||
memset(this, 0, sizeof(NetAddress));
|
||||
}
|
||||
|
||||
void NetAddress::SetPort_(int16 port)
|
||||
{
|
||||
m_Port = htons(port);
|
||||
}
|
||||
|
||||
void NetAddress::ToSockadr(sockaddr *s)
|
||||
{
|
||||
s->sa_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&m_IP;
|
||||
((struct sockaddr_in *)s)->sin_port = m_Port;
|
||||
}
|
||||
|
||||
bool NetAddress::FromSockadr(sockaddr *s)
|
||||
{
|
||||
if (s->sa_family != AF_INET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*(int *)&m_IP = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
||||
m_Port = ((struct sockaddr_in *)s)->sin_port;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAddress::Equal(NetAddress *a)
|
||||
{
|
||||
if (*(int *)&m_IP == *(int *)&a->m_IP && m_Port == a->m_Port) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetAddress::EqualBase(NetAddress *a)
|
||||
{
|
||||
if (*(int *)&m_IP == *(int *)&a->m_IP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetAddress::ToStream(BitBuffer *stream)
|
||||
{
|
||||
stream->WriteByte(m_IP[0]);
|
||||
stream->WriteByte(m_IP[1]);
|
||||
stream->WriteByte(m_IP[2]);
|
||||
stream->WriteByte(m_IP[3]);
|
||||
stream->WriteShort(m_Port);
|
||||
}
|
||||
|
||||
void NetAddress::FromStream(BitBuffer *stream)
|
||||
{
|
||||
m_IP[0] = stream->ReadByte();
|
||||
m_IP[1] = stream->ReadByte();
|
||||
m_IP[2] = stream->ReadByte();
|
||||
m_IP[3] = stream->ReadByte();
|
||||
m_Port = stream->ReadShort();
|
||||
}
|
||||
|
||||
char *NetAddress::ToString()
|
||||
{
|
||||
_snprintf(m_String, sizeof(m_String), "%i.%i.%i.%i:%i", m_IP[0], m_IP[1], m_IP[2], m_IP[3], ntohs(m_Port));
|
||||
return m_String;
|
||||
}
|
||||
|
||||
char *NetAddress::ToBaseString()
|
||||
{
|
||||
_snprintf(m_String, sizeof(m_String), "%i.%i.%i.%i", m_IP[0], m_IP[1], m_IP[2], m_IP[3]);
|
||||
return m_String;
|
||||
}
|
||||
|
||||
void NetAddress::FromNetAddress(NetAddress *adr)
|
||||
{
|
||||
if (!adr) {
|
||||
memset(m_IP, 0, sizeof(m_IP));
|
||||
m_Port = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*(int *)&m_IP[0] = *(int *)&adr->m_IP[0];
|
||||
m_Port = adr->m_Port;
|
||||
}
|
||||
|
||||
netadr_t *NetAddress::ToOldNetAdr()
|
||||
{
|
||||
static netadr_t adr;
|
||||
|
||||
adr.type = NA_IP;
|
||||
adr.port = m_Port;
|
||||
*(int *)&adr.ip[0] = *(int *)&m_IP[0];
|
||||
|
||||
return &adr;
|
||||
}
|
||||
|
||||
bool NetAddress::FromOldNetAdr(netadr_t *adr)
|
||||
{
|
||||
if (adr->type != NA_IP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*(int *)&m_IP[0] = *(int *)&adr->ip[0];
|
||||
m_Port = adr->port;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAddress::IsValid()
|
||||
{
|
||||
return m_Port && (m_IP[0] || m_IP[1] || m_IP[2] || m_IP[3]);
|
||||
}
|
||||
|
||||
void NetAddress::Clear()
|
||||
{
|
||||
m_IP[3] = 0;
|
||||
m_IP[2] = 0;
|
||||
m_IP[1] = 0;
|
||||
m_IP[0] = 0;
|
||||
m_Port = 0;
|
||||
|
||||
memset(m_String, 0, sizeof(m_String));
|
||||
}
|
||||
|
||||
bool NetAddress::IsSubAdress(NetAddress *adr)
|
||||
{
|
||||
if ((!m_IP[0] || m_IP[0] == adr->m_IP[0])
|
||||
&& (!m_IP[1] || m_IP[1] == adr->m_IP[1])
|
||||
&& (!m_IP[2] || m_IP[2] == adr->m_IP[2])
|
||||
&& (!m_IP[3] || m_IP[3] == adr->m_IP[3])
|
||||
&& (m_IP[0] || m_IP[1] || m_IP[2] || m_IP[3]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
74
rehlds/HLTV/common/NetAddress.h
Normal file
74
rehlds/HLTV/common/NetAddress.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "netadr.h"
|
||||
#include "BitBuffer.h"
|
||||
|
||||
class NetAddress {
|
||||
public:
|
||||
NetAddress();
|
||||
|
||||
bool IsValid();
|
||||
bool IsSubAdress(NetAddress *adr);
|
||||
|
||||
void Clear();
|
||||
|
||||
bool FromOldNetAdr(netadr_t *adr);
|
||||
netadr_t *ToOldNetAdr();
|
||||
|
||||
void FromNetAddress(NetAddress *adr);
|
||||
char *ToBaseString();
|
||||
char *ToString();
|
||||
|
||||
bool EqualBase(NetAddress *a);
|
||||
bool Equal(NetAddress *a);
|
||||
bool FromSockadr(struct sockaddr *s);
|
||||
void ToSockadr(struct sockaddr *s);
|
||||
void SetPort_(int16 port);
|
||||
void ToStream(BitBuffer *stream);
|
||||
void FromStream(BitBuffer *stream);
|
||||
|
||||
virtual ~NetAddress() {}
|
||||
|
||||
public:
|
||||
unsigned char m_IP[4];
|
||||
short unsigned int m_Port;
|
||||
char m_String[32];
|
||||
};
|
||||
|
||||
class NetPacket {
|
||||
public:
|
||||
NetAddress address;
|
||||
BitBuffer data;
|
||||
double time;
|
||||
bool connectionless;
|
||||
unsigned int seqnr;
|
||||
bool hasReliableData;
|
||||
};
|
1286
rehlds/HLTV/common/NetChannel.cpp
Normal file
1286
rehlds/HLTV/common/NetChannel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
237
rehlds/HLTV/common/NetChannel.h
Normal file
237
rehlds/HLTV/common/NetChannel.h
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <HLTV/INetSocket.h>
|
||||
#include <HLTV/INetChannel.h>
|
||||
|
||||
#include "bzip2/bzlib.h"
|
||||
#include "ObjectList.h"
|
||||
|
||||
// 0 == regular, 1 == file stream
|
||||
enum
|
||||
{
|
||||
FRAG_NORMAL_STREAM = 0,
|
||||
FRAG_FILE_STREAM,
|
||||
|
||||
MAX_STREAMS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FLOW_OUTGOING = 0,
|
||||
FLOW_INCOMING,
|
||||
|
||||
MAX_FLOWS
|
||||
};
|
||||
|
||||
#define MAX_LATENT 32
|
||||
#define FRAGMENT_MAX_SIZE 1400 // Size of fragmentation buffer internal buffers
|
||||
|
||||
#define UDP_HEADER_SIZE 28
|
||||
#define MAX_RELIABLE_PAYLOAD 1200
|
||||
|
||||
#define MAKE_FRAGID(id, count) (((id & 0xffff) << 16) | (count & 0xffff))
|
||||
#define FRAG_GETID(fragid) ((fragid >> 16) & 0xffff)
|
||||
#define FRAG_GETCOUNT(fragid) (fragid & 0xffff)
|
||||
|
||||
// Max length of a reliable message
|
||||
#define MAX_MSGLEN 3990 // 10 reserved for fragheader?
|
||||
#define MAX_POSSIBLE_MSG 65536
|
||||
|
||||
#define MAX_ROUTEABLE_PACKET 1400
|
||||
#define MIN_ROUTEABLE_PACKET 16
|
||||
|
||||
#define SPLIT_SIZE (MAX_ROUTEABLE_PACKET - sizeof(SPLITPACKET))
|
||||
|
||||
// Pad this to next higher 16 byte boundary
|
||||
// This is the largest packet that can come in/out over the wire, before processing the header
|
||||
// bytes will be stripped by the networking channel layer
|
||||
// #define NET_MAX_MESSAGE PAD_NUMBER( ( MAX_MSGLEN + HEADER_BYTES ), 16 )
|
||||
// This is currently used value in the engine. TODO: define above gives 4016, check it why.
|
||||
#define NET_MAX_MESSAGE 4037
|
||||
#define NET_HEADER_FLAG_SPLITPACKET -2
|
||||
|
||||
class IBaseSystem;
|
||||
|
||||
// Network Connection Channel
|
||||
class NetChannel: public INetChannel {
|
||||
public:
|
||||
NetChannel();
|
||||
virtual ~NetChannel() {}
|
||||
|
||||
virtual bool Create(IBaseSystem *system, INetSocket *netsocket = nullptr, NetAddress *adr = nullptr);
|
||||
virtual bool IsConnected();
|
||||
virtual bool IsReadyToSend();
|
||||
virtual bool IsCrashed();
|
||||
virtual bool IsTimedOut();
|
||||
virtual bool IsFakeChannel();
|
||||
virtual bool KeepAlive();
|
||||
virtual NetAddress *GetTargetAddress();
|
||||
virtual void Close();
|
||||
virtual void Clear();
|
||||
virtual void Reset();
|
||||
virtual void TransmitOutgoing();
|
||||
virtual void ProcessIncoming(unsigned char *data, int size);
|
||||
virtual void OutOfBandPrintf(const char *format, ...);
|
||||
virtual void FakeAcknowledgement();
|
||||
virtual void SetUpdateRate(int newupdaterate);
|
||||
virtual void SetRate(int newRate);
|
||||
virtual void SetKeepAlive(bool flag);
|
||||
virtual void SetTimeOut(float time);
|
||||
virtual float GetIdleTime();
|
||||
virtual int GetRate();
|
||||
virtual int GetUpdateRate();
|
||||
virtual float GetLoss();
|
||||
|
||||
enum { FRAGMENT_C2S_MIN_SIZE = 16, FRAGMENT_S2C_MIN_SIZE = 256, FRAGMENT_S2C_MAX_SIZE = 1024 };
|
||||
|
||||
// Message data
|
||||
typedef struct flowstats_s
|
||||
{
|
||||
int size; // Size of message sent/received
|
||||
double time; // Time that message was sent/received
|
||||
} flowstats_t;
|
||||
|
||||
typedef struct flow_s
|
||||
{
|
||||
flowstats_t stats[MAX_LATENT]; // Data for last MAX_LATENT messages
|
||||
int current; // Current message position
|
||||
double nextcompute; // Time when we should recompute k/sec data
|
||||
|
||||
// Average data
|
||||
float kbytespersec;
|
||||
float avgkbytespersec;
|
||||
} flow_t;
|
||||
|
||||
// Generic fragment structure
|
||||
typedef struct fragbuf_s
|
||||
{
|
||||
struct fragbuf_s *next; // Next buffer in chain
|
||||
int bufferId; // Id of this buffer
|
||||
byte data[FRAGMENT_MAX_SIZE]; // The actual data sits here
|
||||
|
||||
int size; // Size of data to read at that offset
|
||||
bool isfile; // Is this a file buffer?
|
||||
bool isbuffer; // Is this file buffer from memory ( custom decal, etc. ).
|
||||
char fileName[MAX_PATH]; // Name of the file to save out on remote host
|
||||
int fOffset; // Offset in file from which to read data
|
||||
} fragbuf_t;
|
||||
|
||||
// Waiting list of fragbuf chains
|
||||
typedef struct fragbufwaiting_s
|
||||
{
|
||||
struct fragbufwaiting_s *next; // Next chain in waiting list
|
||||
int fragbufcount; // Number of buffers in this chain
|
||||
fragbuf_t *fragbufs; // The actual buffers
|
||||
} fragbufwaiting_t;
|
||||
|
||||
bool CreateFragmentsFromFile(char *fileName);
|
||||
bool CopyFileFragments();
|
||||
void GetFlowStats(float *avgInKBSec, float *avgOutKBSec);
|
||||
void SetConnected(bool flag);
|
||||
void FlushOutgoing();
|
||||
void CopyNormalFragments();
|
||||
void UpdateFlow(int stream);
|
||||
void FlushIncoming(int stream);
|
||||
void ClearFragments();
|
||||
void ClearFragbufs(fragbuf_t **ppbuf);
|
||||
void UnlinkFragment(fragbuf_t *buf, int stream);
|
||||
NetPacket *GetPacket();
|
||||
void FreePacket(NetPacket *packet);
|
||||
void AddFragbufToTail(fragbufwaiting_t *wait, fragbuf_t *buf);
|
||||
bool CreateFragmentsFromBuffer(void *buffer, int size, int streamtype, char *filename = nullptr);
|
||||
void AddBufferToList(fragbuf_t ** pplist, fragbuf_t *pbuf);
|
||||
void FragSend();
|
||||
bool CheckForCompletion(int stream, int intotalbuffers);
|
||||
fragbuf_t *FindBufferById(fragbuf_t **pplist, int id, bool allocate);
|
||||
|
||||
public:
|
||||
IBaseSystem *m_System;
|
||||
INetSocket *m_Socket;
|
||||
|
||||
NetAddress m_remote_address; // Address this channel is talking to.
|
||||
double m_last_received;
|
||||
double m_last_send;
|
||||
double m_connect_time; // Time when channel was connected.
|
||||
float m_timeout;
|
||||
int m_max_bandwidth_rate;
|
||||
double m_send_interval;
|
||||
int m_updaterate; // Bandwidth choke, bytes per second
|
||||
double m_cleartime; // If realtime > cleartime, free to send next packet
|
||||
|
||||
bool m_keep_alive;
|
||||
bool m_crashed;
|
||||
bool m_connected;
|
||||
|
||||
// Sequencing variables
|
||||
int m_incoming_sequence; // Increasing count of sequence numbers
|
||||
int m_incoming_acknowledged; // # of last outgoing message that has been ack'd.
|
||||
int m_incoming_reliable_acknowledged; // Toggles T/F as reliable messages are received.
|
||||
int m_incoming_reliable_sequence; // single bit, maintained local
|
||||
int m_outgoing_sequence; // Message we are sending to remote
|
||||
int m_reliable_sequence; // Whether the message contains reliable payload, single bit
|
||||
int m_last_reliable_sequence; // Outgoing sequence number of last send that had reliable data
|
||||
|
||||
void *m_connection_status;
|
||||
|
||||
int m_blocksize;
|
||||
BitBuffer m_reliableStream;
|
||||
BitBuffer m_unreliableStream;
|
||||
ObjectList m_incomingPackets;
|
||||
|
||||
// Reliable message buffer.
|
||||
// We keep adding to it until reliable is acknowledged. Then we clear it.
|
||||
int m_reliableOutSize;
|
||||
unsigned char m_reliableOutBuffer[MAX_MSGLEN + 20];
|
||||
|
||||
fragbufwaiting_t *m_waitlist[MAX_STREAMS]; // Waiting list of buffered fragments to go onto queue. Multiple outgoing buffers can be queued in succession.
|
||||
|
||||
int m_reliable_fragment[MAX_STREAMS]; // Is reliable waiting buf a fragment?
|
||||
size_t m_reliable_fragid[MAX_STREAMS]; // Buffer id for each waiting fragment
|
||||
|
||||
fragbuf_t *m_fragbufs[MAX_STREAMS]; // The current fragment being set
|
||||
int m_fragbufcount[MAX_STREAMS]; // The total number of fragments in this stream
|
||||
|
||||
int16 m_frag_startpos[MAX_STREAMS]; // Position in outgoing buffer where frag data starts
|
||||
int16 m_frag_length[MAX_STREAMS]; // Length of frag data in the buffer
|
||||
|
||||
fragbuf_t *m_incomingbufs[MAX_STREAMS]; // Incoming fragments are stored here
|
||||
|
||||
// Only referenced by the FRAG_FILE_STREAM component
|
||||
// Name of file being downloaded
|
||||
char m_incomingfilename[MAX_PATH];
|
||||
|
||||
void *m_tempBuffer;
|
||||
int m_tempBufferSize;
|
||||
|
||||
// Incoming and outgoing flow metrics
|
||||
flow_t m_flow[MAX_FLOWS];
|
||||
float m_loss;
|
||||
};
|
85
rehlds/HLTV/common/ServerInfo.h
Normal file
85
rehlds/HLTV/common/ServerInfo.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct serverinfo_s
|
||||
{
|
||||
char address[64];
|
||||
char name[80];
|
||||
char map[16];
|
||||
char gamedir[256];
|
||||
char description[256];
|
||||
|
||||
int activePlayers;
|
||||
int maxPlayers;
|
||||
|
||||
char type; // HLServerType
|
||||
char os;
|
||||
char pw;
|
||||
bool mod;
|
||||
|
||||
char url_info[256];
|
||||
char url_dl[256];
|
||||
char hlversion[256];
|
||||
|
||||
int ver;
|
||||
int size;
|
||||
|
||||
bool svonly;
|
||||
bool cldll;
|
||||
|
||||
unsigned char protocol;
|
||||
} serverinfo_t;
|
||||
|
||||
enum HLServerType {
|
||||
HLST_Dedicated,
|
||||
HLST_NonDedicated,
|
||||
HLST_TV,
|
||||
};
|
||||
|
||||
inline const char *GetServerType(HLServerType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HLST_Dedicated: return "d";
|
||||
case HLST_NonDedicated: return "l";
|
||||
case HLST_TV: return "p";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
inline const char *GetServerOS()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return "w";
|
||||
#else
|
||||
return "l";
|
||||
#endif
|
||||
}
|
89
rehlds/HLTV/common/byteorder.cpp
Normal file
89
rehlds/HLTV/common/byteorder.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
short _BigShort(short l)
|
||||
{
|
||||
return bswap(l);
|
||||
}
|
||||
|
||||
short _LittleShort(short l)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
int _BigLong(int l)
|
||||
{
|
||||
return bswap(l);
|
||||
}
|
||||
|
||||
int _LittleLong(int l)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
float _BigFloat(float l)
|
||||
{
|
||||
return bswap(l);
|
||||
}
|
||||
|
||||
float _LittleFloat(float l)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
int _LongSwap(int l)
|
||||
{
|
||||
return bswap(l);
|
||||
}
|
||||
|
||||
int _LongNoSwap(int l)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
short _ShortSwap(short l)
|
||||
{
|
||||
return bswap(l);
|
||||
}
|
||||
|
||||
short _ShortNoSwap(short l)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
float _FloatSwap(float f)
|
||||
{
|
||||
return bswap(f);
|
||||
}
|
||||
|
||||
float _FloatNoSwap(float f)
|
||||
{
|
||||
return f;
|
||||
}
|
42
rehlds/HLTV/common/byteorder.h
Normal file
42
rehlds/HLTV/common/byteorder.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
short _BigShort(short l);
|
||||
short _LittleShort(short l);
|
||||
int _BigLong(int l);
|
||||
int _LittleLong(int l);
|
||||
float _BigFloat(float l);
|
||||
float _LittleFloat(float l);
|
||||
int _LongSwap(int l);
|
||||
int _LongNoSwap(int l);
|
||||
short _ShortSwap(short l);
|
||||
short _ShortNoSwap(short l);
|
||||
float _FloatSwap(float f);
|
||||
float _FloatNoSwap(float f);
|
468
rehlds/HLTV/common/common.cpp
Normal file
468
rehlds/HLTV/common/common.cpp
Normal file
@ -0,0 +1,468 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
static char *date = __DATE__;
|
||||
static char *mon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
static char mond[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
int COM_BuildNumber()
|
||||
{
|
||||
int m = 0;
|
||||
int d = 0;
|
||||
int y = 0;
|
||||
static int b = 0;
|
||||
|
||||
if (b != 0)
|
||||
return b;
|
||||
|
||||
for (m = 0; m < 11; m++)
|
||||
{
|
||||
if (_strnicmp(&date[0], mon[m], 3) == 0)
|
||||
break;
|
||||
d += mond[m];
|
||||
}
|
||||
|
||||
d += atoi(&date[4]) - 1;
|
||||
y = atoi(&date[7]) - 1900;
|
||||
b = d + (int)((y - 1) * 365.25);
|
||||
|
||||
if (((y % 4) == 0) && m > 1)
|
||||
{
|
||||
b += 1;
|
||||
}
|
||||
|
||||
// return days since initial commit on Apr 12 2014 (Happy Cosmonautics Day!)
|
||||
b -= 41374;
|
||||
return b;
|
||||
}
|
||||
|
||||
char *COM_TimeString()
|
||||
{
|
||||
static char timedate[16];
|
||||
time_t ltime = time(nullptr);
|
||||
tm *now = localtime(<ime);
|
||||
|
||||
strftime(timedate, sizeof(timedate), "%y%m%d%H%M", now);
|
||||
return timedate;
|
||||
}
|
||||
|
||||
char *COM_SkipPath(char *pathname)
|
||||
{
|
||||
char *last = pathname;
|
||||
while (*pathname)
|
||||
{
|
||||
if (*pathname == '/' || *pathname == '\\') {
|
||||
last = pathname + 1;
|
||||
}
|
||||
|
||||
pathname++;
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
char *COM_GetBaseDir()
|
||||
{
|
||||
static char basedir[MAX_PATH];
|
||||
basedir[0] = '\0';
|
||||
|
||||
if (GetModuleFileName((HMODULE)nullptr, basedir, sizeof(basedir)))
|
||||
{
|
||||
char *pBuffer = strrchr(basedir, '\\');
|
||||
|
||||
if (pBuffer && *pBuffer)
|
||||
pBuffer[1] = '\0';
|
||||
|
||||
int j = strlen(basedir);
|
||||
if (j > 0 && (basedir[j - 1] == '\\' || basedir[j - 1] == '/'))
|
||||
basedir[j - 1] = '\0';
|
||||
}
|
||||
|
||||
return basedir;
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
char g_szEXEName[256];
|
||||
char *COM_GetBaseDir()
|
||||
{
|
||||
static char basedir[MAX_PATH];
|
||||
basedir[0] = '\0';
|
||||
|
||||
strcpy(basedir, g_szEXEName);
|
||||
char *pBuffer = strrchr(basedir, '/');
|
||||
|
||||
if (pBuffer && *pBuffer)
|
||||
pBuffer[1] = '\0';
|
||||
|
||||
int j = strlen(basedir);
|
||||
if (j > 0 && (basedir[j - 1] == '\\' || basedir[j - 1] == '/'))
|
||||
basedir[j - 1] = '\0';
|
||||
|
||||
return basedir;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
void COM_FixSlashes(char *pname)
|
||||
{
|
||||
while (*pname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (*pname == '/')
|
||||
{
|
||||
*pname = '\\';
|
||||
}
|
||||
#else
|
||||
if (*pname == '\\')
|
||||
{
|
||||
*pname = '/';
|
||||
}
|
||||
#endif
|
||||
|
||||
pname++;
|
||||
}
|
||||
}
|
||||
|
||||
// Fills "out" with the file name without path and extension.
|
||||
void COM_FileBase(char *in, char *out)
|
||||
{
|
||||
*out = '\0';
|
||||
|
||||
int len = strlen(in);
|
||||
if (len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *start = in + len - 1;
|
||||
const char *end = in + len;
|
||||
|
||||
while (start >= in && *start != '/' && *start != '\\')
|
||||
{
|
||||
if (*start == '.') {
|
||||
end = start;
|
||||
}
|
||||
|
||||
start--;
|
||||
}
|
||||
start++;
|
||||
|
||||
len = end - start;
|
||||
strncpy(out, start, len);
|
||||
out[len] = '\0';
|
||||
}
|
||||
|
||||
char com_token[COM_TOKEN_LEN];
|
||||
qboolean s_com_token_unget = FALSE;
|
||||
|
||||
void COM_UngetToken()
|
||||
{
|
||||
s_com_token_unget = TRUE;
|
||||
}
|
||||
|
||||
char *COM_Parse(char *data)
|
||||
{
|
||||
int c;
|
||||
int len;
|
||||
|
||||
if (s_com_token_unget)
|
||||
{
|
||||
s_com_token_unget = FALSE;
|
||||
return data;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
com_token[0] = '\0';
|
||||
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
skipwhite:
|
||||
while (*data <= 32)
|
||||
{
|
||||
if (!*data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
data++;
|
||||
}
|
||||
|
||||
c = *data;
|
||||
|
||||
// skip // comments till the next line
|
||||
if (c == '/' && data[1] == '/')
|
||||
{
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
|
||||
// start over new line
|
||||
goto skipwhite;
|
||||
}
|
||||
|
||||
// handle quoted strings specially: copy till the end or another quote
|
||||
if (c == '\"')
|
||||
{
|
||||
// skip starting quote
|
||||
data++;
|
||||
while (true)
|
||||
{
|
||||
c = *data++; // get char and advance
|
||||
if (c == '\"') // closing quote
|
||||
{
|
||||
com_token[len] = '\0';
|
||||
return data;
|
||||
}
|
||||
|
||||
if (!c || len == COM_TOKEN_LEN - 1) // check if buffer is full
|
||||
{
|
||||
com_token[len] = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
com_token[len++] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// parse single characters
|
||||
if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ',')
|
||||
{
|
||||
com_token[len++] = c;
|
||||
com_token[len] = '\0';
|
||||
return data + 1;
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
com_token[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
c = *data;
|
||||
if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ',')
|
||||
break;
|
||||
}
|
||||
while (len < COM_TOKEN_LEN - 1 && (c < 0 || c > 32));
|
||||
}
|
||||
|
||||
com_token[len] = '\0';
|
||||
return data;
|
||||
}
|
||||
|
||||
char *COM_VarArgs(char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, format);
|
||||
_vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
unsigned char COM_Nibble(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
return (unsigned char)(c - '0');
|
||||
}
|
||||
|
||||
if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
return (unsigned char)(c - 'A' + 0x0A);
|
||||
}
|
||||
|
||||
if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
return (unsigned char)(c - 'a' + 0x0A);
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
|
||||
void COM_HexConvert(const char *pszInput, int nInputLength, unsigned char *pOutput)
|
||||
{
|
||||
const char *pIn;
|
||||
unsigned char *p = pOutput;
|
||||
for (int i = 0; i < nInputLength - 1; i += 2)
|
||||
{
|
||||
pIn = &pszInput[i];
|
||||
if (!pIn[0] || !pIn[1])
|
||||
break;
|
||||
|
||||
*p++ = ((COM_Nibble(pIn[0]) << 4) | COM_Nibble(pIn[1]));
|
||||
}
|
||||
}
|
||||
|
||||
char *COM_BinPrintf(unsigned char *buf, int length)
|
||||
{
|
||||
char szChunk[10];
|
||||
static char szReturn[4096];
|
||||
memset(szReturn, 0, sizeof(szReturn));
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
_snprintf(szChunk, sizeof(szChunk), "%02x", buf[i]);
|
||||
strncat(szReturn, szChunk, sizeof(szReturn) - strlen(szReturn) - 1);
|
||||
}
|
||||
|
||||
return szReturn;
|
||||
}
|
||||
|
||||
char *COM_FormatTime(float seconds)
|
||||
{
|
||||
|
||||
static char time[32];
|
||||
int hours = (int)seconds / 3600;
|
||||
if (hours > 0)
|
||||
{
|
||||
_snprintf(time, sizeof(time), "%02i:%2i:%02i", hours, (int)seconds / 60, (int)seconds % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
_snprintf(time, sizeof(time), "%02i:%02i", (int)seconds / 60, (int)seconds % 60);
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void COM_RemoveEvilChars(char *string)
|
||||
{
|
||||
char *c = string;
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (*c)
|
||||
{
|
||||
if (*c < ' ' || *c > '~' || *c == '%' || *c == ';') {
|
||||
*c = ' ';
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
int COM_FileNameCmp(const char *file1, const char *file2)
|
||||
{
|
||||
while (*file1 && *file2)
|
||||
{
|
||||
if ((*file1 != '/' || *file2 != '\\') && (*file2 != '/' || *file1 != '\\'))
|
||||
{
|
||||
if (tolower(*file1) != tolower(*file2))
|
||||
return -1;
|
||||
|
||||
if (!*file1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
file1++;
|
||||
file2++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool COM_IsWhiteSpace(char space)
|
||||
{
|
||||
switch (space) {
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case ' ':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void COM_TrimSpace(const char *source, char *dest)
|
||||
{
|
||||
int start = 0;
|
||||
while (source[start] && COM_IsWhiteSpace(source[start])) {
|
||||
start++;
|
||||
}
|
||||
|
||||
int end = strlen(source) - 1;
|
||||
while (end > 0 && COM_IsWhiteSpace(source[end])) {
|
||||
end--;
|
||||
}
|
||||
|
||||
end++;
|
||||
|
||||
int length = end - start;
|
||||
if (length > 0) {
|
||||
strncpy(dest, &source[start], length);
|
||||
}
|
||||
else
|
||||
length = 0;
|
||||
|
||||
dest[length] = '\0';
|
||||
}
|
||||
|
||||
void COM_UnpackRGB(unsigned char &r, unsigned char &g, unsigned char &b, unsigned int color)
|
||||
{
|
||||
r = (color >> 16) & 0xFF;
|
||||
g = (color >> 8) & 0xFF;
|
||||
b = (color) & 0xFF;
|
||||
}
|
||||
|
||||
unsigned int COM_PackRGB(unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
unsigned int COM_PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
||||
{
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
void NORETURN HLTV_SysError(const char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[8192];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
printf("%s\n", string);
|
||||
|
||||
FILE* fl = fopen("hltv_error.txt", "w");
|
||||
fprintf(fl, "%s\n", string);
|
||||
fclose(fl);
|
||||
|
||||
int *null = 0;
|
||||
*null = 0;
|
||||
exit(-1);
|
||||
}
|
55
rehlds/HLTV/common/common_hltv.h
Normal file
55
rehlds/HLTV/common/common_hltv.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
int COM_BuildNumber();
|
||||
char *COM_TimeString();
|
||||
char *COM_SkipPath(char *pathname);
|
||||
char *COM_GetBaseDir();
|
||||
void COM_FixSlashes(char *pname);
|
||||
void COM_FileBase(char *in, char *out);
|
||||
void COM_UngetToken();
|
||||
char *COM_Parse(char *data);
|
||||
char *COM_VarArgs(char *format, ...);
|
||||
unsigned char COM_Nibble(char c);
|
||||
void COM_HexConvert(const char *pszInput, int nInputLength, unsigned char *pOutput);
|
||||
char *COM_BinPrintf(unsigned char *buf, int length);
|
||||
char *COM_FormatTime(float seconds);
|
||||
void COM_RemoveEvilChars(char *string);
|
||||
int COM_FileNameCmp(const char *file1, const char *file2);
|
||||
bool COM_IsWhiteSpace(char space);
|
||||
void COM_TrimSpace(const char *source, char *dest);
|
||||
void COM_UnpackRGB(unsigned char &r, unsigned char &g, unsigned char &b, unsigned int color);
|
||||
unsigned int COM_PackRGB(unsigned char r, unsigned char g, unsigned char b);
|
||||
unsigned int COM_PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
|
||||
void NORETURN HLTV_SysError(const char *fmt, ...);
|
||||
|
||||
#ifdef LINUX
|
||||
extern char g_szEXEName[256];
|
||||
#endif // LINUX
|
390
rehlds/HLTV/common/mathlib.cpp
Normal file
390
rehlds/HLTV/common/mathlib.cpp
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
vec3_t vec3_origin;
|
||||
|
||||
float TriangleDiameter(const vec_t *v1, vec_t *v2, vec_t *v3)
|
||||
{
|
||||
vec3_t e1, e2, e3;
|
||||
float l1, l2, l3;
|
||||
int i;
|
||||
|
||||
l1 = 0;
|
||||
l2 = 0;
|
||||
l3 = 0;
|
||||
|
||||
VectorSubtract(v2, v1, e1);
|
||||
VectorSubtract(v3, v2, e2);
|
||||
VectorSubtract(v1, v3, e3);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
l3 = e1[i] * e1[i] + l3;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
l2 = e2[i] * e2[i] + l2;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
l1 = e3[i] * e3[i] + l1;
|
||||
}
|
||||
|
||||
if (l3 > l2 && l3 > l1) {
|
||||
return sqrt(l3);
|
||||
}
|
||||
|
||||
if (l2 > l3 && l2 > l1) {
|
||||
return sqrt(l2);
|
||||
}
|
||||
|
||||
return sqrt(l1);
|
||||
}
|
||||
|
||||
float VectorNormalize(vec_t *v)
|
||||
{
|
||||
float length = Length(v);
|
||||
if (length)
|
||||
{
|
||||
float ilength = 1 / length;
|
||||
|
||||
v[0] *= ilength;
|
||||
v[1] *= ilength;
|
||||
v[2] *= ilength;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
float VectorDistance(const vec_t *v1, const vec_t *v2)
|
||||
{
|
||||
vec3_t t;
|
||||
VectorSubtract(v1, v2, t);
|
||||
return Length(t);
|
||||
}
|
||||
|
||||
void VectorAngles(const float *forward, float *angles)
|
||||
{
|
||||
float tmp, yaw, pitch;
|
||||
if (forward[1] == 0 && forward[0] == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
if (forward[2] > 0)
|
||||
pitch = 90;
|
||||
else
|
||||
pitch = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = float(atan2(forward[1], forward[0]) * 180 / M_PI);
|
||||
if (yaw < 0)
|
||||
yaw += 360;
|
||||
|
||||
tmp = sqrt(forward[0] * forward[0] + forward[1] * forward[1]);
|
||||
pitch = float(atan2(forward[2], tmp) * 180 / M_PI);
|
||||
if (pitch < 0)
|
||||
pitch += 360;
|
||||
}
|
||||
|
||||
angles[0] = pitch;
|
||||
angles[1] = yaw;
|
||||
angles[2] = 0;
|
||||
}
|
||||
|
||||
void VectorRAngles(const float *v, float *a)
|
||||
{
|
||||
a[0] = atan2(v[2], sqrt(v[0] * v[0] + v[1] * v[1]));
|
||||
a[1] = atan2(v[1], v[0]);
|
||||
NormalizeRAngles(a);
|
||||
}
|
||||
|
||||
int BoxOnPlaneSide(vec_t *emins, vec_t *emaxs, mplane_t *p)
|
||||
{
|
||||
// From sources
|
||||
float dist1, dist2;
|
||||
int sides = 0;
|
||||
|
||||
// general case
|
||||
switch (p->signbits)
|
||||
{
|
||||
case 0:
|
||||
dist1 = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2];
|
||||
dist2 = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2];
|
||||
break;
|
||||
case 1:
|
||||
dist1 = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2];
|
||||
dist2 = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2];
|
||||
break;
|
||||
case 2:
|
||||
dist1 = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2];
|
||||
dist2 = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2];
|
||||
break;
|
||||
case 3:
|
||||
dist1 = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2];
|
||||
dist2 = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2];
|
||||
break;
|
||||
case 4:
|
||||
dist1 = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2];
|
||||
dist2 = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2];
|
||||
break;
|
||||
case 5:
|
||||
dist1 = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2];
|
||||
dist2 = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2];
|
||||
break;
|
||||
case 6:
|
||||
dist1 = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2];
|
||||
dist2 = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2];
|
||||
break;
|
||||
case 7:
|
||||
dist1 = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2];
|
||||
dist2 = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2];
|
||||
break;
|
||||
default:
|
||||
dist1 = dist2 = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dist1 >= p->dist)
|
||||
sides = 1;
|
||||
if (dist2 < p->dist)
|
||||
sides |= 2;
|
||||
|
||||
return sides;
|
||||
}
|
||||
|
||||
float AngleBetweenVectors(const vec_t *angle1, const vec_t *angle2)
|
||||
{
|
||||
float angle;
|
||||
float d1 = Length(angle1);
|
||||
float d2 = Length(angle2);
|
||||
|
||||
if (!d1 || !d2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
angle = acos(DotProduct(angle1, angle2) / (d1 * d2));
|
||||
angle = angle * float(180.0f / M_PI);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
float RAngleBetweenVectors(const vec_t *angle1, const vec_t *angle2)
|
||||
{
|
||||
float d1, d2, d3;
|
||||
|
||||
d1 = Length(angle1);
|
||||
d2 = Length(angle2);
|
||||
|
||||
if (!d1 || !d2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
d3 = DotProduct(angle1, angle2) / (d1 * d2);
|
||||
if (d3 > 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (d3 < -1) {
|
||||
return (float)M_PI;
|
||||
}
|
||||
|
||||
return acosf(d3);
|
||||
}
|
||||
|
||||
void NormalizeAngles(vec_t *angles)
|
||||
{
|
||||
// Normalize angles
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (angles[i] > 180.0)
|
||||
{
|
||||
angles[i] -= 360.0;
|
||||
}
|
||||
else if (angles[i] < -180.0)
|
||||
{
|
||||
angles[i] += 360.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NormalizeRAngles(vec_t *a)
|
||||
{
|
||||
if (a[0] > M_PI) {
|
||||
a[0] -= float(M_PI * 2);
|
||||
}
|
||||
else if (a[0] < -M_PI) {
|
||||
a[0] += float(M_PI * 2);
|
||||
}
|
||||
|
||||
if (a[1] > M_PI) {
|
||||
a[1] -= float(M_PI * 2);
|
||||
}
|
||||
else if (a[1] < -M_PI) {
|
||||
a[1] += float(M_PI * 2);
|
||||
}
|
||||
|
||||
a[2] = 0;
|
||||
}
|
||||
|
||||
void AngleVectors(const vec_t *angles, vec_t *forward, vec_t *right, vec_t *up)
|
||||
{
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
float angle;
|
||||
angle = (float)(angles[YAW] * (M_PI * 2 / 360));
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = (float)(angles[PITCH] * (M_PI * 2 / 360));
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
angle = (float)(angles[ROLL] * (M_PI * 2 / 360));
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
if (forward)
|
||||
{
|
||||
forward[0] = cp * cy;
|
||||
forward[1] = cp * sy;
|
||||
forward[2] = -sp;
|
||||
}
|
||||
|
||||
if (right)
|
||||
{
|
||||
right[0] = (-1 * sr * sp * cy + -1 * cr * -sy);
|
||||
right[1] = (-1 * sr * sp * sy + -1 * cr * cy);
|
||||
right[2] = -1 * sr * cp;
|
||||
}
|
||||
|
||||
if (up)
|
||||
{
|
||||
up[0] = (cr * sp * cy + -sr * -sy);
|
||||
up[1] = (cr * sp * sy + -sr * cy);
|
||||
up[2] = cr * cp;
|
||||
}
|
||||
}
|
||||
|
||||
int AngleLeftOfOther(const vec_t *v1, const vec_t *v2)
|
||||
{
|
||||
float a = v1[1];
|
||||
float b = v2[1];
|
||||
|
||||
if (a >= 180)
|
||||
return (b >= a) || ((a - 180) > b);
|
||||
else
|
||||
return (b > a) && ((a + 180) >= b);
|
||||
}
|
||||
|
||||
float RadiusFromBounds(const vec_t *mins, const vec_t *maxs)
|
||||
{
|
||||
vec3_t corner;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
float fmin = fabs(mins[i]);
|
||||
float fmax = fabs(mins[i]);
|
||||
|
||||
if (fmin > fmax)
|
||||
corner[i] = fmin;
|
||||
else
|
||||
corner[i] = fmax;
|
||||
}
|
||||
|
||||
return Length(corner);
|
||||
}
|
||||
|
||||
bool SolveLSE(vec_t *v0, vec_t *v1, vec_t *v2, vec_t *v3, float *x, float *y, float *z)
|
||||
{
|
||||
float d = v1[2] * (v2[0] * v3[1] - v2[1] * v3[0]) + v1[1] * (v3[0] * v2[2] - v2[0] * v3[2]) + v1[0] * (v2[1] * v3[2] - v3[1] * v2[2]);
|
||||
if (!d) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x) *x = ((v2[0] * v3[1] - v2[1] * v3[0]) * v0[2] + (v3[0] * v2[2] - v2[0] * v3[2]) * v0[1] + (v2[1] * v3[2] - v3[1] * v2[2]) * v0[0]) / d;
|
||||
if (y) *y = ((v0[0] * v3[1] - v0[1] * v3[0]) * v1[2] + (v3[0] * v0[2] - v0[0] * v3[2]) * v1[1] + (v0[1] * v3[2] - v3[1] * v0[2]) * v1[0]) / d;
|
||||
if (z) *z = ((v2[0] * v0[1] - v2[1] * v0[0]) * v1[2] + (v0[0] * v2[2] - v2[0] * v0[2]) * v1[1] + (v2[1] * v0[2] - v0[1] * v2[2]) * v1[0]) / d;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NormalizePoints(vec_t *v0, vec_t *v1)
|
||||
{
|
||||
vec3_t a;
|
||||
VectorSubtract(v1, v0, a);
|
||||
|
||||
if (Length(a))
|
||||
{
|
||||
VectorNormalize(a);
|
||||
VectorAdd(a, v0, v1);
|
||||
}
|
||||
}
|
||||
|
||||
void Normal2Plane(vec_t *v1, vec_t *v2, vec_t *v3)
|
||||
{
|
||||
if (v1[0])
|
||||
{
|
||||
v2[0] = -v1[1] / v1[0];
|
||||
v2[1] = 1;
|
||||
v2[2] = 0;
|
||||
|
||||
v3[0] = -v1[2] / v1[0];
|
||||
v3[1] = 0;
|
||||
v3[2] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (v1[1])
|
||||
{
|
||||
v2[0] = 1;
|
||||
v2[1] = -v1[0] / v1[1];
|
||||
v2[2] = 0;
|
||||
|
||||
v3[0] = 0;
|
||||
v3[1] = -v1[2] / v1[1];
|
||||
v3[2] = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
v2[0] = 1;
|
||||
v2[1] = 0;
|
||||
v2[2] = -v1[0] / v1[2];
|
||||
|
||||
v3[0] = 0;
|
||||
v3[1] = 1;
|
||||
v3[2] = -v1[1] / v1[2];
|
||||
}
|
||||
|
||||
float Length(const vec_t *v)
|
||||
{
|
||||
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
}
|
||||
|
||||
float DotProduct(const vec_t *v1, const vec_t *v2)
|
||||
{
|
||||
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
||||
}
|
65
rehlds/HLTV/common/mathlib_internal.h
Normal file
65
rehlds/HLTV/common/mathlib_internal.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#define PITCH 0 // up / down
|
||||
#define YAW 1 // left / right
|
||||
#define ROLL 2 // fall over
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
|
||||
static const int nanmask = 0x7F800000;
|
||||
#define IS_NAN(fvar) ((*reinterpret_cast<int*>(&(fvar)) & nanmask) == nanmask)
|
||||
|
||||
#define VectorScale(a,b,c) {(c)[0]=(b)*(a)[0];(c)[1]=(b)*(a)[1];(c)[2]=(b)*(a)[2];}
|
||||
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
||||
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
|
||||
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
|
||||
#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;}
|
||||
|
||||
float DotProduct(const vec_t *v1, const vec_t *v2);
|
||||
float TriangleDiameter(const vec_t *v1, vec_t *v2, vec_t *v3);
|
||||
float VectorNormalize(vec_t *v);
|
||||
float VectorDistance(const vec_t *v1, const vec_t *v2);
|
||||
void VectorAngles(const float *forward, float *angles);
|
||||
void VectorRAngles(const float *v, float *a);
|
||||
int BoxOnPlaneSide(vec_t *emins, vec_t *emaxs, struct mplane_s *p);
|
||||
float AngleBetweenVectors(const vec_t *angle1, const vec_t *angle2);
|
||||
float RAngleBetweenVectors(const vec_t *angle1, const vec_t *angle2);
|
||||
void NormalizeAngles(vec_t *angles);
|
||||
void NormalizeRAngles(vec_t *a);
|
||||
void AngleVectors(const vec_t *angles, vec_t *forward, vec_t *right = nullptr, vec_t *up = nullptr);
|
||||
int AngleLeftOfOther(const vec_t *v1, const vec_t *v2);
|
||||
float RadiusFromBounds(const vec_t *mins, const vec_t *maxs);
|
||||
bool SolveLSE(vec_t *v0, vec_t *v1, vec_t *v2, vec_t *v3, float *x, float *y, float *z);
|
||||
void NormalizePoints(vec_t *v0, vec_t *v1);
|
||||
void Normal2Plane(vec_t *v1, vec_t *v2, vec_t *v3);
|
||||
float Length(const vec_t *v);
|
317
rehlds/HLTV/common/md5.cpp
Normal file
317
rehlds/HLTV/common/md5.cpp
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
static unsigned char PADDING[64] =
|
||||
{
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* F, G and H are basic MD5 functions: selection, majority, parity */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += F ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += G ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += H ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += I ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
void MD5_Init(MD5Context_t *ctx)
|
||||
{
|
||||
ctx->bits[0] = ctx->bits[1] = 0;
|
||||
|
||||
// Load magic initialization constants.
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void MD5_Transform(unsigned int *buf, const unsigned int *in)
|
||||
{
|
||||
uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
|
||||
|
||||
// Round 1
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
FF(a, b, c, d, in[0], S11, 3614090360); /* 1 */
|
||||
FF(d, a, b, c, in[1], S12, 3905402710); /* 2 */
|
||||
FF(c, d, a, b, in[2], S13, 606105819); /* 3 */
|
||||
FF(b, c, d, a, in[3], S14, 3250441966); /* 4 */
|
||||
FF(a, b, c, d, in[4], S11, 4118548399); /* 5 */
|
||||
FF(d, a, b, c, in[5], S12, 1200080426); /* 6 */
|
||||
FF(c, d, a, b, in[6], S13, 2821735955); /* 7 */
|
||||
FF(b, c, d, a, in[7], S14, 4249261313); /* 8 */
|
||||
FF(a, b, c, d, in[8], S11, 1770035416); /* 9 */
|
||||
FF(d, a, b, c, in[9], S12, 2336552879); /* 10 */
|
||||
FF(c, d, a, b, in[10], S13, 4294925233); /* 11 */
|
||||
FF(b, c, d, a, in[11], S14, 2304563134); /* 12 */
|
||||
FF(a, b, c, d, in[12], S11, 1804603682); /* 13 */
|
||||
FF(d, a, b, c, in[13], S12, 4254626195); /* 14 */
|
||||
FF(c, d, a, b, in[14], S13, 2792965006); /* 15 */
|
||||
FF(b, c, d, a, in[15], S14, 1236535329); /* 16 */
|
||||
|
||||
// Round 2
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
GG(a, b, c, d, in[1], S21, 4129170786); /* 17 */
|
||||
GG(d, a, b, c, in[6], S22, 3225465664); /* 18 */
|
||||
GG(c, d, a, b, in[11], S23, 643717713); /* 19 */
|
||||
GG(b, c, d, a, in[0], S24, 3921069994); /* 20 */
|
||||
GG(a, b, c, d, in[5], S21, 3593408605); /* 21 */
|
||||
GG(d, a, b, c, in[10], S22, 38016083); /* 22 */
|
||||
GG(c, d, a, b, in[15], S23, 3634488961); /* 23 */
|
||||
GG(b, c, d, a, in[4], S24, 3889429448); /* 24 */
|
||||
GG(a, b, c, d, in[9], S21, 568446438); /* 25 */
|
||||
GG(d, a, b, c, in[14], S22, 3275163606); /* 26 */
|
||||
GG(c, d, a, b, in[3], S23, 4107603335); /* 27 */
|
||||
GG(b, c, d, a, in[8], S24, 1163531501); /* 28 */
|
||||
GG(a, b, c, d, in[13], S21, 2850285829); /* 29 */
|
||||
GG(d, a, b, c, in[2], S22, 4243563512); /* 30 */
|
||||
GG(c, d, a, b, in[7], S23, 1735328473); /* 31 */
|
||||
GG(b, c, d, a, in[12], S24, 2368359562); /* 32 */
|
||||
|
||||
// Round 3
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
HH(a, b, c, d, in[5], S31, 4294588738); /* 33 */
|
||||
HH(d, a, b, c, in[8], S32, 2272392833); /* 34 */
|
||||
HH(c, d, a, b, in[11], S33, 1839030562); /* 35 */
|
||||
HH(b, c, d, a, in[14], S34, 4259657740); /* 36 */
|
||||
HH(a, b, c, d, in[1], S31, 2763975236); /* 37 */
|
||||
HH(d, a, b, c, in[4], S32, 1272893353); /* 38 */
|
||||
HH(c, d, a, b, in[7], S33, 4139469664); /* 39 */
|
||||
HH(b, c, d, a, in[10], S34, 3200236656); /* 40 */
|
||||
HH(a, b, c, d, in[13], S31, 681279174); /* 41 */
|
||||
HH(d, a, b, c, in[0], S32, 3936430074); /* 42 */
|
||||
HH(c, d, a, b, in[3], S33, 3572445317); /* 43 */
|
||||
HH(b, c, d, a, in[6], S34, 76029189); /* 44 */
|
||||
HH(a, b, c, d, in[9], S31, 3654602809); /* 45 */
|
||||
HH(d, a, b, c, in[12], S32, 3873151461); /* 46 */
|
||||
HH(c, d, a, b, in[15], S33, 530742520); /* 47 */
|
||||
HH(b, c, d, a, in[2], S34, 3299628645); /* 48 */
|
||||
|
||||
// Round 4
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
II(a, b, c, d, in[0], S41, 4096336452); /* 49 */
|
||||
II(d, a, b, c, in[7], S42, 1126891415); /* 50 */
|
||||
II(c, d, a, b, in[14], S43, 2878612391); /* 51 */
|
||||
II(b, c, d, a, in[5], S44, 4237533241); /* 52 */
|
||||
II(a, b, c, d, in[12], S41, 1700485571); /* 53 */
|
||||
II(d, a, b, c, in[3], S42, 2399980690); /* 54 */
|
||||
II(c, d, a, b, in[10], S43, 4293915773); /* 55 */
|
||||
II(b, c, d, a, in[1], S44, 2240044497); /* 56 */
|
||||
II(a, b, c, d, in[8], S41, 1873313359); /* 57 */
|
||||
II(d, a, b, c, in[15], S42, 4264355552); /* 58 */
|
||||
II(c, d, a, b, in[6], S43, 2734768916); /* 59 */
|
||||
II(b, c, d, a, in[13], S44, 1309151649); /* 60 */
|
||||
II(a, b, c, d, in[4], S41, 4149444226); /* 61 */
|
||||
II(d, a, b, c, in[11], S42, 3174756917); /* 62 */
|
||||
II(c, d, a, b, in[2], S43, 718787259); /* 63 */
|
||||
II(b, c, d, a, in[9], S44, 3951481745); /* 64 */
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
void MD5_Update(MD5Context_t *ctx, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
uint32 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
|
||||
// Compute number of bytes mod 64
|
||||
mdi = (int)((ctx->bits[0] >> 3) & 0x3F);
|
||||
|
||||
// Update number of bits
|
||||
if ((ctx->bits[0] + ((uint32)len << 3)) < ctx->bits[0])
|
||||
{
|
||||
ctx->bits[1]++;
|
||||
}
|
||||
|
||||
ctx->bits[0] += ((uint32)len << 3);
|
||||
ctx->bits[1] += ((uint32)len >> 29);
|
||||
|
||||
while (len--)
|
||||
{
|
||||
// Add new character to buffer, increment mdi
|
||||
ctx->in[mdi++] = *buf++;
|
||||
|
||||
// Transform if necessary
|
||||
if (mdi == 0x40)
|
||||
{
|
||||
for (i = 0, ii = 0; i < 16; i++, ii += 4)
|
||||
in[i] = (((uint32)ctx->in[ii + 3]) << 24) |
|
||||
(((uint32)ctx->in[ii + 2]) << 16) |
|
||||
(((uint32)ctx->in[ii + 1]) << 8) |
|
||||
((uint32)ctx->in[ii]);
|
||||
MD5_Transform(ctx->buf, in);
|
||||
mdi = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MD5_Final(unsigned char *digest, MD5Context_t *ctx)
|
||||
{
|
||||
uint32 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
unsigned int padLen;
|
||||
|
||||
// save number of bits
|
||||
in[14] = ctx->bits[0];
|
||||
in[15] = ctx->bits[1];
|
||||
|
||||
// Compute number of bytes mod 64
|
||||
mdi = (int)((ctx->bits[0] >> 3) & 0x3F);
|
||||
|
||||
// Pad out to 56 mod 64
|
||||
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
|
||||
MD5_Update(ctx, PADDING, padLen);
|
||||
|
||||
// Append length in bits and transform
|
||||
for (i = 0, ii = 0; i < 14; i++, ii += 4)
|
||||
in[i] = (((uint32)ctx->in[ii + 3]) << 24) |
|
||||
(((uint32)ctx->in[ii + 2]) << 16) |
|
||||
(((uint32)ctx->in[ii + 1]) << 8) |
|
||||
((uint32)ctx->in[ii]);
|
||||
MD5_Transform(ctx->buf, in);
|
||||
|
||||
// Store buffer in digest
|
||||
for (i = 0, ii = 0; i < 4; i++, ii += 4)
|
||||
{
|
||||
digest[ii] = (unsigned char)(ctx->buf[i] & 0xFF);
|
||||
digest[ii + 1] = (unsigned char)((ctx->buf[i] >> 8) & 0xFF);
|
||||
digest[ii + 2] = (unsigned char)((ctx->buf[i] >> 16) & 0xFF);
|
||||
digest[ii + 3] = (unsigned char)((ctx->buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
char *MD5_Print(unsigned char *hash)
|
||||
{
|
||||
static char szReturn[64];
|
||||
char szChunk[10];
|
||||
int i;
|
||||
|
||||
memset(szReturn, 0, sizeof(szReturn));
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
_snprintf(szChunk, sizeof(szChunk), "%02x", hash[i]);
|
||||
strncat(szReturn, szChunk, sizeof(szReturn) - strlen(szReturn) - 1);
|
||||
}
|
||||
|
||||
return szReturn;
|
||||
}
|
||||
|
||||
char *MD5_GetCDKeyHash(const char *key)
|
||||
{
|
||||
static char szHashedKeyBuffer[256];
|
||||
|
||||
char szKeyBuffer[256];
|
||||
int nKeyLength = strlen(key);
|
||||
if (nKeyLength <= 0 || nKeyLength > 255) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
strncpy(szKeyBuffer, key, sizeof(szKeyBuffer) - 1);
|
||||
szKeyBuffer[sizeof(szKeyBuffer) - 1] = '\0';
|
||||
szKeyBuffer[nKeyLength] = '\0';
|
||||
|
||||
MD5Context_t ctx;
|
||||
unsigned char digest[16];
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(szHashedKeyBuffer, 0, sizeof(szHashedKeyBuffer));
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, (unsigned char *)szKeyBuffer, nKeyLength);
|
||||
MD5_Final(digest, &ctx);
|
||||
|
||||
strncpy(szHashedKeyBuffer, MD5_Print(digest), sizeof(szHashedKeyBuffer) - 1);
|
||||
szHashedKeyBuffer[sizeof(szHashedKeyBuffer) - 1] = '\0';
|
||||
|
||||
return szHashedKeyBuffer;
|
||||
}
|
||||
|
||||
void MD5_Hash_Mem(unsigned char *digest, unsigned char *mem, int size)
|
||||
{
|
||||
MD5Context_t ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, mem, size);
|
||||
MD5_Final(digest, &ctx);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user