Compare commits
1 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21f4d1486c |
@@ -5,7 +5,6 @@ packages:
|
||||
- freetype-dev
|
||||
- fontconfig-dev
|
||||
- opus-dev
|
||||
- bzip2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -7,7 +7,6 @@ packages:
|
||||
- libfreetype-dev
|
||||
- libfontconfig-dev
|
||||
- libopus-dev
|
||||
- libbz2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,7 +6,6 @@ packages:
|
||||
- libfreetype-dev
|
||||
- libfontconfig-dev
|
||||
- libopus-dev
|
||||
- libbz2-dev
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,7 +6,6 @@ packages:
|
||||
- print/freetype2
|
||||
- x11-fonts/fontconfig
|
||||
- audio/opus
|
||||
- archivers/bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -6,7 +6,6 @@ packages:
|
||||
- fontconfig
|
||||
- libopus
|
||||
- pkgconf
|
||||
- bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
@@ -3,7 +3,6 @@ packages:
|
||||
- python3
|
||||
- sdl2
|
||||
- opus
|
||||
- bzip2
|
||||
sources:
|
||||
- https://git.sr.ht/~a1batross/xash3d-fwgs
|
||||
tasks:
|
||||
|
||||
23
.cirrus.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
task:
|
||||
name: freebsd-14-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-0
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
|
||||
task:
|
||||
name: freebsd-15-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-15-0-snap
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
113
.clang-format
@@ -1,113 +0,0 @@
|
||||
Language: Cpp
|
||||
Standard: c++17
|
||||
UseTab: ForContinuationAndIndentation
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
IndentCaseLabels: false
|
||||
IndentPPDirectives: None
|
||||
NamespaceIndentation: None
|
||||
AccessModifierOffset: -4
|
||||
IndentAccessModifiers: false
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: Always
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeWhile: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
MaxEmptyLinesToKeep: 2
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
KeepEmptyLinesAtEOF: false
|
||||
SeparateDefinitionBlocks: Always
|
||||
InsertNewlineAtEOF: true
|
||||
LineEnding: LF
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
PointerAlignment: Right
|
||||
DerivePointerAlignment: false
|
||||
ReferenceAlignment: Pointer
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpacesInParens: Custom
|
||||
SpacesInParensOptions:
|
||||
ExceptDoubleParentheses: true
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: true
|
||||
InEmptyParentheses: false
|
||||
Other: true
|
||||
# XashCollapseParens: true
|
||||
SpaceBeforeParens: Never
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInSquareBrackets: false
|
||||
Cpp11BracedListStyle: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
ColumnLimit: 0
|
||||
ReflowComments: false
|
||||
SortIncludes: Never
|
||||
SortUsingDeclarations: false
|
||||
InsertBraces: false
|
||||
RemoveBracesLLVM: false
|
||||
FixNamespaceComments: false
|
||||
83
.github/workflows/c-cpp.yml
vendored
@@ -15,34 +15,19 @@ jobs:
|
||||
include:
|
||||
# Linux build specifically want oldest Ubuntu as possible
|
||||
# to be crossdistribution compatible, otherwise use ubuntu-latest
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: amd64
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: i386
|
||||
- os: ubuntu-22.04-arm
|
||||
targetos: linux
|
||||
targetarch: arm64
|
||||
- os: ubuntu-22.04-arm
|
||||
targetos: linux
|
||||
targetarch: armhf
|
||||
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
||||
targetos: linux
|
||||
targetarch: riscv64
|
||||
cross: true
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: ppc64el
|
||||
cross: true
|
||||
# - os: ubuntu-latest
|
||||
# - os: ubuntu-aarch64-20.04
|
||||
# targetos: linux
|
||||
# targetarch: e2k-8c
|
||||
# cross: true
|
||||
- os: ubuntu-latest
|
||||
# targetarch: aarch64
|
||||
- os: ubuntu-20.04
|
||||
targetos: android
|
||||
targetarch: multiarch
|
||||
# - os: ubuntu-22.04
|
||||
# - os: ubuntu-20.04
|
||||
# targetos: motomagx
|
||||
# targetarch: armv6
|
||||
|
||||
@@ -55,28 +40,21 @@ jobs:
|
||||
- os: windows-latest
|
||||
targetos: win32
|
||||
targetarch: amd64
|
||||
- os: windows-2022 # always use the oldest possible for 32-bit because of older compilers, and better support of certain legacy OSes
|
||||
- os: windows-2019 # always use the oldest possible for 32-bit because of older compilers, and better support of certain legacy OSes
|
||||
targetos: win32
|
||||
targetarch: i386
|
||||
- os: macos-14 # arm64 as per github documentation
|
||||
- os: macos-14 # in GitHub documentation, it's an ARM64 machine
|
||||
targetos: apple
|
||||
targetarch: arm64
|
||||
- os: macos-latest
|
||||
targetos: ios
|
||||
targetarch: arm64
|
||||
- os: macos-15-intel
|
||||
- os: macos-12 # in GitHub documentation, it's an x86 machine
|
||||
targetos: apple
|
||||
targetarch: amd64
|
||||
env:
|
||||
SDL_VERSION: 2.32.10
|
||||
FFMPEG_VERSION: 8.1
|
||||
YY_THUNKS_VERSION: v1.2.1
|
||||
SDL_VERSION: 2.30.3
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GH_CPU_OS: ${{ matrix.targetos }}
|
||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install dependencies
|
||||
@@ -86,27 +64,26 @@ jobs:
|
||||
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
||||
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
||||
- name: Upload engine (artifacts)
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
||||
path: artifacts/*
|
||||
flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- app: su.xash.Engine.Compat.i386
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
|
||||
image: bilelmoussaoui/flatpak-github-actions:freedesktop-23.08
|
||||
options: --privileged
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build flatpak (Compat.i386)
|
||||
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.5
|
||||
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3
|
||||
with:
|
||||
bundle: ${{ matrix.app }}.flatpak
|
||||
manifest-path: scripts/flatpak/${{ matrix.app }}.yml
|
||||
@@ -116,10 +93,32 @@ jobs:
|
||||
needs: [build, flatpak]
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- name: Remove old release, fetch artifacts, repackage binaries and upload new release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BASE_BUILDNUM_DATE: "2015-04-01"
|
||||
run: bash scripts/gha/make_release.sh "Xash3D FWGS" "${{ github.ref_name }}"
|
||||
RELEASE_TAG: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
|
||||
run: |
|
||||
gh release delete "$RELEASE_TAG" \
|
||||
--yes \
|
||||
--cleanup-tag \
|
||||
--repo "$GITHUB_REPOSITORY" || true
|
||||
sleep 20s
|
||||
gh run download "$GITHUB_RUN_ID" \
|
||||
--dir artifacts/ \
|
||||
--repo "$GITHUB_REPOSITORY"
|
||||
pushd artifacts/
|
||||
echo "Found artifacts:"
|
||||
ls
|
||||
for i in $(find -mindepth 1 -maxdepth 1 -type d); do
|
||||
mv "$i"/* .
|
||||
rm -rf "$i"
|
||||
done
|
||||
echo "Repackaged artifacts:"
|
||||
ls -R
|
||||
popd
|
||||
sleep 20s
|
||||
gh release create "$RELEASE_TAG" artifacts/* \
|
||||
--title "Xash3D FWGS Continuous ${{ github.ref_name }} Build" \
|
||||
--target $GITHUB_SHA \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--prerelease
|
||||
|
||||
34
.gitignore
vendored
@@ -222,7 +222,7 @@ publish/
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
@@ -318,12 +318,6 @@ build-*
|
||||
*.includes
|
||||
*.files
|
||||
|
||||
# ios
|
||||
ios/cl_dlls/*
|
||||
ios/dlls/*
|
||||
ios/*.framework
|
||||
scripts/ios/mod-build
|
||||
|
||||
# Waf
|
||||
build_current
|
||||
*waf-*/
|
||||
@@ -345,32 +339,6 @@ __pycache__
|
||||
.history/*
|
||||
.cache/*
|
||||
enc_temp_folder/
|
||||
Taskfile.yml
|
||||
|
||||
# KDevelop4
|
||||
*.kdev4
|
||||
|
||||
# ccls langauge server
|
||||
.ccls-*
|
||||
|
||||
# JetBrains
|
||||
.idea/
|
||||
cmake-build-*
|
||||
|
||||
# some Android-specific build stuff
|
||||
3rdparty/SDL
|
||||
3rdparty/hlsdk-portable
|
||||
!scripts/build-ninja.py
|
||||
|
||||
# slop
|
||||
CLAUDE.md
|
||||
AGENTS.md
|
||||
GEMINI.md
|
||||
.claude/
|
||||
.gemini/
|
||||
.cursor*
|
||||
.windsurf*
|
||||
.aider*
|
||||
.continue/
|
||||
.codeium/
|
||||
.github/copilot-instructions.md
|
||||
|
||||
24
.gitmodules
vendored
@@ -22,27 +22,3 @@
|
||||
[submodule "3rdparty/bzip2/bzip2"]
|
||||
path = 3rdparty/bzip2/bzip2
|
||||
url = https://gitlab.com/bzip2/bzip2
|
||||
[submodule "3rdparty/MultiEmulator"]
|
||||
path = 3rdparty/MultiEmulator
|
||||
url = https://github.com/FWGS/MultiEmulator
|
||||
[submodule "3rdparty/libogg/libogg"]
|
||||
path = 3rdparty/libogg/libogg
|
||||
url = https://github.com/xiph/ogg.git
|
||||
[submodule "3rdparty/vorbis/vorbis-src"]
|
||||
path = 3rdparty/vorbis/vorbis-src
|
||||
url = https://github.com/xiph/vorbis.git
|
||||
[submodule "3rdparty/opusfile/opusfile"]
|
||||
path = 3rdparty/opusfile/opusfile
|
||||
url = https://github.com/xiph/opusfile.git
|
||||
[submodule "3rdparty/libbacktrace/libbacktrace"]
|
||||
path = 3rdparty/libbacktrace/libbacktrace
|
||||
url = https://github.com/ianlancetaylor/libbacktrace
|
||||
[submodule "3rdparty/maintui"]
|
||||
path = 3rdparty/maintui
|
||||
url = https://github.com/FWGS/xash3d-maintui.git
|
||||
[submodule "3rdparty/library_suffix"]
|
||||
path = 3rdparty/library_suffix
|
||||
url = https://github.com/FWGS/library-suffix.git
|
||||
[submodule "3rdparty/mbedtls/mbedtls"]
|
||||
path = 3rdparty/mbedtls/mbedtls
|
||||
url = https://github.com/FWGS/mbedtls-releases.git
|
||||
|
||||
1
3rdparty/MultiEmulator
vendored
21
3rdparty/MultiEmulator/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2018 Alexander Belkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
25
3rdparty/MultiEmulator/README.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# MultiEmulator
|
||||
|
||||
**MultiEmulator** - project for GoldSource Engine, which provides ability to generate tickets with a specific SteamID key, using all available emulators for this engine.
|
||||
|
||||
Ticket is processed by the game server of Half-Life 1 and modifications using **DProto** or **ReUnion** modules. If the server does not have these modules, then MultiEmulator won't work.
|
||||
|
||||
# Ticket generators
|
||||
|
||||
Currently available ticket generators:
|
||||
* OldRevEmu
|
||||
* AVSMP
|
||||
* Setti
|
||||
* SteamEmu
|
||||
* RevEmu
|
||||
* SC2009
|
||||
* RevEmu2013
|
||||
|
||||
Currently under development generators:
|
||||
* SmartSteamEmu (SSE3)
|
||||
|
||||
# How to use?
|
||||
Each file in the **MultiEmulator\Source\Emulators** folder contains a **Generate** function that writes a ticket to the **pDest** argument for the emulator of the same name as a header file. As a result of the function, the size of the written ticket is returned. If the generator can set an arbitrary SteamID, the function will have the **nSteamID** argument, in which the required SteamID is specified.
|
||||
|
||||
# Examples
|
||||
As an example, the DLL was developed that searches InitiateGameConnection method in ISteamUser interface, which generates Steam ticket, and inserts in its place own generator, which creates RevEmu2013 ticket with SteamID equal to 3333333. You can find this project in **Example** folder, you just need to compile it and perform DLL injection in hl.exe process with any known injection method.
|
||||
37
3rdparty/MultiEmulator/include/multi_emulator.h
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef MULTI_EMULATOR_H
|
||||
#define MULTI_EMULATOR_H
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#if defined( __i386__ )
|
||||
#define ME_EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
||||
#else
|
||||
#define ME_EXPORT __attribute__(( visibility ( "default" )))
|
||||
#endif
|
||||
#else
|
||||
#if defined( _MSC_VER )
|
||||
#define ME_EXPORT __declspec( dllexport )
|
||||
#else
|
||||
#define ME_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int ME_EXPORT GenerateRevEmu2013( void *pDest, int nSteamID );
|
||||
int ME_EXPORT GenerateSC2009( void *pDest, int nSteamID );
|
||||
int ME_EXPORT GenerateOldRevEmu( void *pDest, int nSteamID );
|
||||
int ME_EXPORT GenerateSteamEmu( void *pDest, int nSteamID );
|
||||
int ME_EXPORT GenerateRevEmu( void *pDest, int nSteamID );
|
||||
int ME_EXPORT GenerateSetti( void *pDest );
|
||||
int ME_EXPORT GenerateAVSMP( void *pDest, int nSteamID, int bUniverse );
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MULTI_EMULATOR_H
|
||||
13
3rdparty/MultiEmulator/src/AVSMP.cpp
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "multi_emulator.h"
|
||||
|
||||
/* bUniverse param is "y" value in "STEAM_x:y:z" */
|
||||
int GenerateAVSMP(void *pDest, int nSteamID, int bUniverse)
|
||||
{
|
||||
auto pTicket = (int *)pDest;
|
||||
|
||||
pTicket[0] = 0x14; // +0, header
|
||||
pTicket[3] = (nSteamID << 1) | (bUniverse ? 1 : 0); // +12, SteamId, Low part
|
||||
pTicket[4] = 0x01100001; // +16, SteamId, High part
|
||||
|
||||
return 28;
|
||||
}
|
||||
1376
3rdparty/MultiEmulator/src/CRijndael.cpp
vendored
Normal file
187
3rdparty/MultiEmulator/src/CRijndael.h
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
#ifndef __RIJNDAEL_H__
|
||||
#define __RIJNDAEL_H__
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//Rijndael (pronounced Reindaal) is a block cipher, designed by Joan Daemen and Vincent Rijmen as a candidate algorithm for the AES.
|
||||
//The cipher has a variable block length and key length. The authors currently specify how to use keys with a length
|
||||
//of 128, 192, or 256 bits to encrypt blocks with al length of 128, 192 or 256 bits (all nine combinations of
|
||||
//key length and block length are possible). Both block length and key length can be extended very easily to
|
||||
// multiples of 32 bits.
|
||||
//Rijndael can be implemented very efficiently on a wide range of processors and in hardware.
|
||||
//This implementation is based on the Java Implementation used with the Cryptix toolkit found at:
|
||||
//http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael.zip
|
||||
//Java code authors: Raif S. Naffah, Paulo S. L. M. Barreto
|
||||
//This Implementation was tested against KAT test published by the authors of the method and the
|
||||
//results were identical.
|
||||
class CRijndael
|
||||
{
|
||||
public:
|
||||
//Operation Modes
|
||||
//The Electronic Code Book (ECB), Cipher Block Chaining (CBC) and Cipher Feedback Block (CFB) modes
|
||||
//are implemented.
|
||||
//In ECB mode if the same block is encrypted twice with the same key, the resulting
|
||||
//ciphertext blocks are the same.
|
||||
//In CBC Mode a ciphertext block is obtained by first xoring the
|
||||
//plaintext block with the previous ciphertext block, and encrypting the resulting value.
|
||||
//In CFB mode a ciphertext block is obtained by encrypting the previous ciphertext block
|
||||
//and xoring the resulting value with the plaintext.
|
||||
enum { ECB = 0, CBC = 1, CFB = 2 };
|
||||
|
||||
private:
|
||||
enum { DEFAULT_BLOCK_SIZE = 16 };
|
||||
enum { MAX_BLOCK_SIZE = 32, MAX_ROUNDS = 14, MAX_KC = 8, MAX_BC = 8 };
|
||||
|
||||
//Auxiliary Functions
|
||||
//Multiply two elements of GF(2^m)
|
||||
static int Mul(int a, int b)
|
||||
{
|
||||
return (a != 0 && b != 0) ? sm_alog[(sm_log[a & 0xFF] + sm_log[b & 0xFF]) % 255] : 0;
|
||||
}
|
||||
|
||||
//Convenience method used in generating Transposition Boxes
|
||||
static int Mul4(int a, char b[])
|
||||
{
|
||||
if (a == 0)
|
||||
return 0;
|
||||
a = sm_log[a & 0xFF];
|
||||
int a0 = (b[0] != 0) ? sm_alog[(a + sm_log[b[0] & 0xFF]) % 255] & 0xFF : 0;
|
||||
int a1 = (b[1] != 0) ? sm_alog[(a + sm_log[b[1] & 0xFF]) % 255] & 0xFF : 0;
|
||||
int a2 = (b[2] != 0) ? sm_alog[(a + sm_log[b[2] & 0xFF]) % 255] & 0xFF : 0;
|
||||
int a3 = (b[3] != 0) ? sm_alog[(a + sm_log[b[3] & 0xFF]) % 255] & 0xFF : 0;
|
||||
return a0 << 24 | a1 << 16 | a2 << 8 | a3;
|
||||
}
|
||||
|
||||
public:
|
||||
//CONSTRUCTOR
|
||||
CRijndael();
|
||||
|
||||
//DESTRUCTOR
|
||||
virtual ~CRijndael();
|
||||
|
||||
//Expand a user-supplied key material into a session key.
|
||||
// key - The 128/192/256-bit user-key to use.
|
||||
// chain - initial chain block for CBC and CFB modes.
|
||||
// keylength - 16, 24 or 32 bytes
|
||||
// blockSize - The block size in bytes of this Rijndael (16, 24 or 32 bytes).
|
||||
void MakeKey(char const* key, char const* chain, int keylength = DEFAULT_BLOCK_SIZE, int blockSize = DEFAULT_BLOCK_SIZE);
|
||||
|
||||
private:
|
||||
//Auxiliary Function
|
||||
void Xor(char* buff, char const* chain)
|
||||
{
|
||||
if (false == m_bKeyInit)
|
||||
throw runtime_error(sm_szErrorMsg1);
|
||||
for (int i = 0; i<m_blockSize; i++)
|
||||
*(buff++) ^= *(chain++);
|
||||
}
|
||||
|
||||
//Convenience method to encrypt exactly one block of plaintext, assuming
|
||||
//Rijndael's default block size (128-bit).
|
||||
// in - The plaintext
|
||||
// result - The ciphertext generated from a plaintext using the key
|
||||
void DefEncryptBlock(char const* in, char* result);
|
||||
|
||||
//Convenience method to decrypt exactly one block of plaintext, assuming
|
||||
//Rijndael's default block size (128-bit).
|
||||
// in - The ciphertext.
|
||||
// result - The plaintext generated from a ciphertext using the session key.
|
||||
void DefDecryptBlock(char const* in, char* result);
|
||||
|
||||
public:
|
||||
//Encrypt exactly one block of plaintext.
|
||||
// in - The plaintext.
|
||||
// result - The ciphertext generated from a plaintext using the key.
|
||||
void EncryptBlock(char const* in, char* result);
|
||||
|
||||
//Decrypt exactly one block of ciphertext.
|
||||
// in - The ciphertext.
|
||||
// result - The plaintext generated from a ciphertext using the session key.
|
||||
void DecryptBlock(char const* in, char* result);
|
||||
|
||||
void Encrypt(char const* in, char* result, size_t n, int iMode = ECB);
|
||||
|
||||
void Decrypt(char const* in, char* result, size_t n, int iMode = ECB);
|
||||
|
||||
//Get Key Length
|
||||
int GetKeyLength()
|
||||
{
|
||||
if (false == m_bKeyInit)
|
||||
throw runtime_error(sm_szErrorMsg1);
|
||||
return m_keylength;
|
||||
}
|
||||
|
||||
//Block Size
|
||||
int GetBlockSize()
|
||||
{
|
||||
if (false == m_bKeyInit)
|
||||
throw runtime_error(sm_szErrorMsg1);
|
||||
return m_blockSize;
|
||||
}
|
||||
|
||||
//Number of Rounds
|
||||
int GetRounds()
|
||||
{
|
||||
if (false == m_bKeyInit)
|
||||
throw runtime_error(sm_szErrorMsg1);
|
||||
return m_iROUNDS;
|
||||
}
|
||||
|
||||
void ResetChain()
|
||||
{
|
||||
memcpy(m_chain, m_chain0, m_blockSize);
|
||||
}
|
||||
|
||||
public:
|
||||
//Null chain
|
||||
static char const* sm_chain0;
|
||||
|
||||
private:
|
||||
static const int sm_alog[256];
|
||||
static const int sm_log[256];
|
||||
static const char sm_S[256];
|
||||
static const char sm_Si[256];
|
||||
static const int sm_T1[256];
|
||||
static const int sm_T2[256];
|
||||
static const int sm_T3[256];
|
||||
static const int sm_T4[256];
|
||||
static const int sm_T5[256];
|
||||
static const int sm_T6[256];
|
||||
static const int sm_T7[256];
|
||||
static const int sm_T8[256];
|
||||
static const int sm_U1[256];
|
||||
static const int sm_U2[256];
|
||||
static const int sm_U3[256];
|
||||
static const int sm_U4[256];
|
||||
static const char sm_rcon[30];
|
||||
static const int sm_shifts[3][4][2];
|
||||
//Error Messages
|
||||
static char const* sm_szErrorMsg1;
|
||||
static char const* sm_szErrorMsg2;
|
||||
//Key Initialization Flag
|
||||
bool m_bKeyInit;
|
||||
//Encryption (m_Ke) round key
|
||||
int m_Ke[MAX_ROUNDS + 1][MAX_BC];
|
||||
//Decryption (m_Kd) round key
|
||||
int m_Kd[MAX_ROUNDS + 1][MAX_BC];
|
||||
//Key Length
|
||||
int m_keylength;
|
||||
//Block Size
|
||||
int m_blockSize;
|
||||
//Number of Rounds
|
||||
int m_iROUNDS;
|
||||
//Chain Block
|
||||
char m_chain0[MAX_BLOCK_SIZE];
|
||||
char m_chain[MAX_BLOCK_SIZE];
|
||||
//Auxiliary private use buffers
|
||||
int tk[MAX_KC];
|
||||
int a[MAX_BC];
|
||||
int t[MAX_BC];
|
||||
};
|
||||
|
||||
#endif // __RIJNDAEL_H__
|
||||
128
3rdparty/MultiEmulator/src/DoubleBuffering.cpp
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
//DoubleBuffering.cpp Source File
|
||||
|
||||
#include "DoubleBuffering.h"
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
CDoubleBuffering::CDoubleBuffering(ifstream& in, char* pcBuff, int iSize, int iDataLen) : m_rin(in),
|
||||
m_iDataLen(iDataLen), m_bEOF(false), m_iSize(iSize), m_iSize2(iSize >> 1), m_pcBuff(pcBuff)
|
||||
{
|
||||
//m_iSize should be even
|
||||
if(m_iSize%2 != 0)
|
||||
throw runtime_error("CDoubleBuffering: m_iSize should be Even Number!");
|
||||
//Check file
|
||||
if(!in.is_open() || in.bad())
|
||||
throw runtime_error("CDoubleBuffering: Referenced File not Opened or in Bad State!");
|
||||
//Check construction data
|
||||
if(m_iDataLen<1 || m_iSize2<m_iDataLen)
|
||||
throw runtime_error("CDoubleBuffering: Illegal Construction Data!");
|
||||
in.read(m_pcBuff, m_iSize2);
|
||||
m_iEnd = m_rin.gcount();
|
||||
m_iCurPos = 0;
|
||||
m_iBuf = 0;
|
||||
}
|
||||
|
||||
int CDoubleBuffering::GetData(char* pszDataBuf, int iDataLen)
|
||||
{
|
||||
if(-1 == iDataLen)
|
||||
iDataLen = m_iDataLen;
|
||||
if(iDataLen<1 || m_iSize2<iDataLen)
|
||||
throw runtime_error("CDoubleBuffering::GetData(): Illegal iDataLen!");
|
||||
if(true == m_bEOF)
|
||||
return 0;
|
||||
//Estimate the next position
|
||||
int iCurPos = m_iCurPos + iDataLen;
|
||||
if(0 == m_iBuf) //First Buffer
|
||||
{
|
||||
if(iCurPos >= m_iEnd)
|
||||
{
|
||||
//Read the next buffer
|
||||
if(m_rin.eof())
|
||||
{
|
||||
m_bEOF = true;
|
||||
//Take everything remained
|
||||
int iRead = m_iEnd-m_iCurPos;
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iRead);
|
||||
return iRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rin.read(m_pcBuff+m_iEnd, m_iSize2);
|
||||
m_iEnd += m_rin.gcount();
|
||||
if(iCurPos > m_iEnd) //Still greater, then EOF attained
|
||||
{
|
||||
assert(m_rin.eof());
|
||||
m_bEOF = true;
|
||||
//Take everything remained
|
||||
int iRead = m_iEnd-m_iCurPos;
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iRead);
|
||||
return iRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iDataLen);
|
||||
m_iCurPos = iCurPos;
|
||||
assert(m_iCurPos >= m_iSize2);
|
||||
m_iBuf = 1;
|
||||
return iDataLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iDataLen);
|
||||
m_iCurPos = iCurPos;
|
||||
return iDataLen;
|
||||
}
|
||||
}
|
||||
else //1 == m_iBuf, Second Buffer
|
||||
{
|
||||
if(iCurPos >= m_iEnd)
|
||||
{
|
||||
//Read the next buffer
|
||||
if(m_rin.eof())
|
||||
{
|
||||
m_bEOF = true;
|
||||
//Take everything remained
|
||||
int iRead = m_iEnd-m_iCurPos;
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iRead);
|
||||
return iRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rin.read(m_pcBuff, m_iSize2);
|
||||
m_iEnd = m_rin.gcount();
|
||||
iCurPos %= m_iSize;
|
||||
if(iCurPos > m_iEnd) //Still greater, then EOF attained
|
||||
{
|
||||
assert(m_rin.eof());
|
||||
m_bEOF = true;
|
||||
//Take everything remained
|
||||
int iRead = m_iSize-m_iCurPos;
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iRead);
|
||||
memcpy(pszDataBuf+iRead, m_pcBuff, m_iEnd);
|
||||
return iRead + m_iEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
int iRead = m_iSize-m_iCurPos;
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iRead);
|
||||
memcpy(pszDataBuf+iRead, m_pcBuff, iDataLen-iRead);
|
||||
m_iCurPos = iCurPos;
|
||||
assert(m_iCurPos < m_iSize2);
|
||||
m_iBuf = 0;
|
||||
return iDataLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pszDataBuf, m_pcBuff+m_iCurPos, iDataLen);
|
||||
m_iCurPos = iCurPos;
|
||||
return iDataLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
3rdparty/MultiEmulator/src/DoubleBuffering.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
//DoubleBuffering.h Header File
|
||||
|
||||
#ifndef __DOUBLEBUFFERING_H__
|
||||
#define __DOUBLEBUFFERING_H__
|
||||
|
||||
//Typical DISCLAIMER:
|
||||
//The code in this project is Copyright (C) 2003 by George Anescu. You have the right to
|
||||
//use and distribute the code in any way you see fit as long as this paragraph is included
|
||||
//with the distribution. No warranties or claims are made as to the validity of the
|
||||
//information and code contained herein, so use it at your own risk.
|
||||
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CDoubleBuffering
|
||||
{
|
||||
public:
|
||||
//Constructor
|
||||
CDoubleBuffering(ifstream& in, char* pcBuff, int iSize, int iDataLen);
|
||||
//Get Next Data Buffer
|
||||
int GetData(char* pszDataBuf, int iDataLen=-1);
|
||||
|
||||
private:
|
||||
ifstream& m_rin;
|
||||
int m_iSize;
|
||||
int m_iSize2; //m_iSize/2
|
||||
int m_iDataLen;
|
||||
//Current Position
|
||||
int m_iCurPos;
|
||||
//End Position
|
||||
int m_iEnd;
|
||||
//Which Buffer
|
||||
int m_iBuf;
|
||||
char* m_pcBuff;
|
||||
//EOF attained
|
||||
bool m_bEOF;
|
||||
};
|
||||
|
||||
#endif //__DOUBLEBUFFERING_H__
|
||||
38
3rdparty/MultiEmulator/src/MessageDigest.cpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
//MessageDigest.cpp
|
||||
|
||||
#include "MessageDigest.h"
|
||||
#include "DoubleBuffering.h"
|
||||
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <strstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//Digesting a Full File
|
||||
void IMessageDigest::DigestFile(string const& rostrFileIn, char* pcDigest)
|
||||
{
|
||||
//Is the User's responsability to ensure that pcDigest is appropriately allocated
|
||||
//Open Input File
|
||||
ifstream in(rostrFileIn.c_str(), ios::binary);
|
||||
if(!in)
|
||||
{
|
||||
ostrstream ostr;
|
||||
ostr << "FileDigest ERROR: in IMessageDigest::DigestFile(): Cannot open File " << rostrFileIn << "!" << ends;
|
||||
string ostrMsg = ostr.str();
|
||||
ostr.freeze(false);
|
||||
throw runtime_error(ostrMsg);
|
||||
}
|
||||
//Resetting first
|
||||
Reset();
|
||||
//Reading from file
|
||||
char szLargeBuff[BUFF_LEN+1] = {0};
|
||||
char szBuff[DATA_LEN+1] = {0};
|
||||
CDoubleBuffering oDoubleBuffering(in, szLargeBuff, BUFF_LEN, DATA_LEN);
|
||||
int iRead;
|
||||
while((iRead=oDoubleBuffering.GetData(szBuff)) > 0)
|
||||
AddData(szBuff, iRead);
|
||||
in.close();
|
||||
//Final Step
|
||||
FinalDigest(pcDigest);
|
||||
}
|
||||
47
3rdparty/MultiEmulator/src/MessageDigest.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
//MessageDigest.h
|
||||
|
||||
#ifndef __MESSAGEDIGEST_H__
|
||||
#define __MESSAGEDIGEST_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//Typical DISCLAIMER:
|
||||
//The code in this project is Copyright (C) 2003 by George Anescu. You have the right to
|
||||
//use and distribute the code in any way you see fit as long as this paragraph is included
|
||||
//with the distribution. No warranties or claims are made as to the validity of the
|
||||
//information and code contained herein, so use it at your own risk.
|
||||
|
||||
//General Message Digest Interface
|
||||
class IMessageDigest
|
||||
{
|
||||
public:
|
||||
//CONSTRUCTOR
|
||||
IMessageDigest() : m_bAddData(false) {}
|
||||
//DESTRUCTOR
|
||||
virtual ~IMessageDigest() {}
|
||||
//Update context to reflect the concatenation of another buffer of bytes
|
||||
virtual void AddData(char const* pcData, int iDataLength) = 0;
|
||||
//Final wrapup - pad to BLOCKSIZE-byte boundary with the bit pattern
|
||||
//10000...(64-bit count of bits processed, MSB-first)
|
||||
virtual void FinalDigest(char* pcDigest) = 0;
|
||||
//Reset current operation in order to prepare for a new one
|
||||
virtual void Reset() = 0;
|
||||
//Digesting a Full File
|
||||
void DigestFile(string const& rostrFileIn, char* pcDigest);
|
||||
|
||||
protected:
|
||||
enum { BLOCKSIZE=64 };
|
||||
//Control Flag
|
||||
bool m_bAddData;
|
||||
//The core of the MessageDigest algorithm, this alters an existing MessageDigest hash to
|
||||
//reflect the addition of 64 bytes of new data
|
||||
virtual void Transform() = 0;
|
||||
|
||||
private:
|
||||
enum { DATA_LEN=384, BUFF_LEN=1024 };
|
||||
};
|
||||
|
||||
#endif // __MESSAGEDIGEST_H__
|
||||
|
||||
13
3rdparty/MultiEmulator/src/OldRevEmu.cpp
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "multi_emulator.h"
|
||||
|
||||
int GenerateOldRevEmu(void* pDest, int nSteamID)
|
||||
{
|
||||
auto pTicket = (int*)pDest;
|
||||
auto pbTicket = (unsigned char*)pDest;
|
||||
|
||||
pTicket[0] = 0xFFFF; // +0, header
|
||||
pTicket[1] = (nSteamID ^ 0xC9710266) << 1; // +4, SteamId
|
||||
*(short *)&pbTicket[8] = 0; // +8, unknown, in original emulator must be 0
|
||||
|
||||
return 10;
|
||||
}
|
||||
27
3rdparty/MultiEmulator/src/RevEmu.cpp
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "multi_emulator.h"
|
||||
#include "StrUtils.h"
|
||||
#include "RevSpoofer.h"
|
||||
|
||||
int GenerateRevEmu(void *pDest, int nSteamID)
|
||||
{
|
||||
char szhwid[64];
|
||||
|
||||
CreateRandomString(szhwid, 16);
|
||||
if (!RevSpoofer::Spoof(szhwid, nSteamID))
|
||||
return 0;
|
||||
|
||||
auto pTicket = (int *)pDest;
|
||||
auto revHash = RevSpoofer::Hash(szhwid);
|
||||
|
||||
pTicket[0] = 'J'; // +0, header
|
||||
pTicket[1] = revHash; // +4, hash of string at +24 offset
|
||||
pTicket[2] = 'r' << 16 | 'e' << 8 | 'v';// +8, magic number
|
||||
pTicket[3] = 0; // +12, unknown number, must always be 0
|
||||
|
||||
pTicket[4] = revHash << 1; // +16, SteamId, Low part
|
||||
pTicket[5] = 0x01100001; // +20, SteamId, High part
|
||||
|
||||
strcpy((char *)&pTicket[6], szhwid); // +24, string for hash
|
||||
|
||||
return 152;
|
||||
}
|
||||
55
3rdparty/MultiEmulator/src/RevEmu2013.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "multi_emulator.h"
|
||||
#include "StrUtils.h"
|
||||
#include "RevSpoofer.h"
|
||||
#include "CRijndael.h"
|
||||
#include "SHA.h"
|
||||
#include <time.h>
|
||||
|
||||
int GenerateRevEmu2013(void *pDest, int nSteamID)
|
||||
{
|
||||
char szhwid[64];
|
||||
|
||||
CreateRandomString(szhwid, 32);
|
||||
if (!RevSpoofer::Spoof(szhwid, nSteamID))
|
||||
return 0;
|
||||
|
||||
auto pTicket = (int *)pDest;
|
||||
auto pbTicket = (unsigned char *)pDest;
|
||||
|
||||
auto revHash = RevSpoofer::Hash(szhwid);
|
||||
|
||||
pTicket[0] = 'S'; // +0
|
||||
pTicket[1] = revHash; // +4
|
||||
pTicket[2] = 'r' << 16 | 'e' << 8 | 'v';;// +8
|
||||
pTicket[3] = 0; // +12
|
||||
pTicket[4] = revHash << 1; // +16
|
||||
pTicket[5] = 0x01100001; // +20
|
||||
pTicket[6] = (int)time(0) + 90123; // +24
|
||||
pbTicket[27] = ~(pbTicket[27] + pbTicket[24]);
|
||||
pTicket[7] = ~(int)time(0); // +28
|
||||
pTicket[8] = revHash * 2 >> 3; // +32
|
||||
pTicket[9] = 0; // +36
|
||||
|
||||
static const char c_szAESKeyRand[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
|
||||
|
||||
char szAESHashRand[32];
|
||||
auto AESRand = CRijndael();
|
||||
AESRand.MakeKey(c_szAESKeyRand, CRijndael::sm_chain0, 32, 32);
|
||||
AESRand.EncryptBlock(szhwid, szAESHashRand);
|
||||
memcpy(&pbTicket[40], szAESHashRand, 32);
|
||||
|
||||
static const char c_szAESKeyRev[] = "_YOU_SERIOUSLY_NEED_TO_GET_LAID_";
|
||||
char AESHashRev[32];
|
||||
auto AESRev = CRijndael();
|
||||
AESRev.MakeKey(c_szAESKeyRev, CRijndael::sm_chain0, 32, 32);
|
||||
AESRev.EncryptBlock(c_szAESKeyRand, AESHashRev);
|
||||
memcpy(&pbTicket[72], AESHashRev, 32);
|
||||
|
||||
char szSHAHash[32];
|
||||
auto sha = CSHA(CSHA::SHA256);
|
||||
sha.AddData(szhwid, 32);
|
||||
sha.FinalDigest(szSHAHash);
|
||||
memcpy(&pbTicket[104], szSHAHash, 32);
|
||||
|
||||
return 194;
|
||||
}
|
||||
96
3rdparty/MultiEmulator/src/RevSpoofer.cpp
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "RevSpoofer.h"
|
||||
#include <string.h>
|
||||
|
||||
#define astrlen(x) sizeof(x) - 1
|
||||
|
||||
static char s_szDictionary[] = { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
|
||||
|
||||
static int iInputLen;
|
||||
static unsigned int uTreasure;
|
||||
|
||||
bool ScanLast3(char *pszInput, unsigned int uPrevHash)
|
||||
{
|
||||
unsigned int h1, h2, h3, hh;
|
||||
for (int i1 = 0; i1 < astrlen(s_szDictionary); i1++)
|
||||
{
|
||||
h1 = uPrevHash ^ ((uPrevHash >> 2) + (uPrevHash << 5) + s_szDictionary[i1]);
|
||||
hh = h1 ^ ((h1 >> 2) + (h1 << 5));
|
||||
hh = hh ^ ((hh >> 2) + (hh << 5));
|
||||
|
||||
if ((hh ^ uTreasure) >> (8 + 5 + 3))
|
||||
continue;
|
||||
|
||||
for (int i2 = 0; i2 < astrlen(s_szDictionary); i2++)
|
||||
{
|
||||
h2 = h1 ^ ((h1 >> 2) + (h1 << 5) + s_szDictionary[i2]);
|
||||
hh = h2 ^ ((h2 >> 2) + (h2 << 5));
|
||||
if ((hh ^ uTreasure) >> (8 + 3))
|
||||
continue;
|
||||
|
||||
for (int i3 = 0; i3 < astrlen(s_szDictionary); i3++)
|
||||
{
|
||||
h3 = h2 ^ ((h2 >> 2) + (h2 << 5) + s_szDictionary[i3]);
|
||||
if (h3 == uTreasure)
|
||||
{
|
||||
pszInput[iInputLen - 3] = s_szDictionary[i1];
|
||||
pszInput[iInputLen - 2] = s_szDictionary[i2];
|
||||
pszInput[iInputLen - 1] = s_szDictionary[i3];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScanNext(char* pszInput, int uIndex, unsigned int uPrevHash)
|
||||
{
|
||||
bool res;
|
||||
|
||||
for (int i = 0; i < astrlen(s_szDictionary); i++)
|
||||
{
|
||||
auto h = uPrevHash ^ ((uPrevHash >> 2) + (uPrevHash << 5) + s_szDictionary[i]);
|
||||
|
||||
if (uIndex + 1 < iInputLen - 3)
|
||||
res = ScanNext(pszInput, uIndex + 1, h);
|
||||
else
|
||||
res = ScanLast3(pszInput, h);
|
||||
|
||||
if (res)
|
||||
{
|
||||
pszInput[uIndex] = s_szDictionary[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace RevSpoofer
|
||||
{
|
||||
bool Spoof(char *pszDest, int uSID)
|
||||
{
|
||||
uTreasure = uSID;
|
||||
iInputLen = strlen(pszDest);
|
||||
|
||||
auto i = iInputLen - 7;
|
||||
i = (i < 0) ? 0 : i;
|
||||
pszDest[i] = '\0';
|
||||
auto h = Hash(pszDest);
|
||||
return ScanNext(pszDest, i, h);
|
||||
}
|
||||
|
||||
unsigned int Hash(char *pszString)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int nHash = 0x4E67C6A7;
|
||||
int c = pszString[i++];
|
||||
|
||||
while (c)
|
||||
{
|
||||
nHash = nHash ^ ((nHash >> 2) + (nHash << 5) + c);
|
||||
c = pszString[i++];
|
||||
}
|
||||
|
||||
return nHash;
|
||||
}
|
||||
}
|
||||
7
3rdparty/MultiEmulator/src/RevSpoofer.h
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace RevSpoofer
|
||||
{
|
||||
bool Spoof(char *pszDest, int uSID);
|
||||
unsigned int Hash(char *pszString);
|
||||
}
|
||||
52
3rdparty/MultiEmulator/src/SC2009.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "multi_emulator.h"
|
||||
#include "StrUtils.h"
|
||||
#include "RevSpoofer.h"
|
||||
#include "CRijndael.h"
|
||||
#include "SHA.h"
|
||||
|
||||
int GenerateSC2009(void* pDest, int nSteamID)
|
||||
{
|
||||
char hwid[64];
|
||||
|
||||
CreateRandomString(hwid, 32);
|
||||
if (!RevSpoofer::Spoof(hwid, nSteamID))
|
||||
return 0;
|
||||
|
||||
auto pTicket = (int*)pDest;
|
||||
auto pbTicket = (unsigned char*)pDest;
|
||||
|
||||
auto revHash = RevSpoofer::Hash(hwid);
|
||||
|
||||
pTicket[0] = 'S'; // +0
|
||||
pTicket[1] = revHash; // +4
|
||||
pTicket[2] = 'r' << 16 | 'e' << 8 | 'v';;// +8
|
||||
pTicket[3] = 0; // +12
|
||||
pTicket[4] = revHash << 1; // +16
|
||||
pTicket[5] = 0x01100001; // +20
|
||||
|
||||
/* Encrypt HWID with AESKeyRand key and save it in the ticket. */
|
||||
static const char AESKeyRand[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
|
||||
char AESHashRand[32];
|
||||
auto AESRand = CRijndael();
|
||||
AESRand.MakeKey(AESKeyRand, CRijndael::sm_chain0, 32, 32);
|
||||
AESRand.EncryptBlock(hwid, AESHashRand);
|
||||
memcpy(&pbTicket[24], AESHashRand, 32);
|
||||
|
||||
/* Encrypt AESKeyRand with AESKeyRev key and save it in the ticket.
|
||||
* AESKeyRev key is identical to the key in dproto/reunion. */
|
||||
static const char AESKeyRev[] = "_YOU_SERIOUSLY_NEED_TO_GET_LAID_";
|
||||
char AESHashRev[32];
|
||||
auto AESRev = CRijndael();
|
||||
AESRev.MakeKey(AESKeyRev, CRijndael::sm_chain0, 32, 32);
|
||||
AESRev.EncryptBlock(AESKeyRand, AESHashRev);
|
||||
memcpy(&pbTicket[56], AESHashRev, 32);
|
||||
|
||||
/* Perform HWID hashing and save hash to the ticket. */
|
||||
char SHAHash[32];
|
||||
auto sha = CSHA(CSHA::SHA256);
|
||||
sha.AddData(hwid, 32);
|
||||
sha.FinalDigest(SHAHash);
|
||||
memcpy(&pbTicket[88], SHAHash, 32);
|
||||
|
||||
return 178;
|
||||
}
|
||||
734
3rdparty/MultiEmulator/src/SHA.cpp
vendored
Normal file
@@ -0,0 +1,734 @@
|
||||
//SHA.cpp
|
||||
#include "SHA.h"
|
||||
#include <exception>
|
||||
#include <strstream>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const unsigned int CSHA::sm_K160[4] =
|
||||
{
|
||||
0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
|
||||
};
|
||||
|
||||
const unsigned int CSHA::sm_H160[SHA160LENGTH] =
|
||||
{
|
||||
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
|
||||
};
|
||||
|
||||
const unsigned int CSHA::sm_K256[64] =
|
||||
{
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
const unsigned int CSHA::sm_H256[SHA256LENGTH] =
|
||||
{
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
};
|
||||
|
||||
const SUI64 CSHA::sm_H384[SHA512LENGTH] =
|
||||
{
|
||||
{0xcbbb9d5d, 0xc1059ed8},
|
||||
{0x629a292a, 0x367cd507},
|
||||
{0x9159015a, 0x3070dd17},
|
||||
{0x152fecd8, 0xf70e5939},
|
||||
{0x67332667, 0xffc00b31},
|
||||
{0x8eb44a87, 0x68581511},
|
||||
{0xdb0c2e0d, 0x64f98fa7},
|
||||
{0x47b5481d, 0xbefa4fa4}
|
||||
};
|
||||
|
||||
const SUI64 CSHA::sm_K512[80] =
|
||||
{
|
||||
{0x428a2f98, 0xd728ae22}, {0x71374491, 0x23ef65cd},
|
||||
{0xb5c0fbcf, 0xec4d3b2f}, {0xe9b5dba5, 0x8189dbbc},
|
||||
{0x3956c25b, 0xf348b538}, {0x59f111f1, 0xb605d019},
|
||||
{0x923f82a4, 0xaf194f9b}, {0xab1c5ed5, 0xda6d8118},
|
||||
{0xd807aa98, 0xa3030242}, {0x12835b01, 0x45706fbe},
|
||||
{0x243185be, 0x4ee4b28c}, {0x550c7dc3, 0xd5ffb4e2},
|
||||
{0x72be5d74, 0xf27b896f}, {0x80deb1fe, 0x3b1696b1},
|
||||
{0x9bdc06a7, 0x25c71235}, {0xc19bf174, 0xcf692694},
|
||||
{0xe49b69c1, 0x9ef14ad2}, {0xefbe4786, 0x384f25e3},
|
||||
{0x0fc19dc6, 0x8b8cd5b5}, {0x240ca1cc, 0x77ac9c65},
|
||||
{0x2de92c6f, 0x592b0275}, {0x4a7484aa, 0x6ea6e483},
|
||||
{0x5cb0a9dc, 0xbd41fbd4}, {0x76f988da, 0x831153b5},
|
||||
{0x983e5152, 0xee66dfab}, {0xa831c66d, 0x2db43210},
|
||||
{0xb00327c8, 0x98fb213f}, {0xbf597fc7, 0xbeef0ee4},
|
||||
{0xc6e00bf3, 0x3da88fc2}, {0xd5a79147, 0x930aa725},
|
||||
{0x06ca6351, 0xe003826f}, {0x14292967, 0x0a0e6e70},
|
||||
{0x27b70a85, 0x46d22ffc}, {0x2e1b2138, 0x5c26c926},
|
||||
{0x4d2c6dfc, 0x5ac42aed}, {0x53380d13, 0x9d95b3df},
|
||||
{0x650a7354, 0x8baf63de}, {0x766a0abb, 0x3c77b2a8},
|
||||
{0x81c2c92e, 0x47edaee6}, {0x92722c85, 0x1482353b},
|
||||
{0xa2bfe8a1, 0x4cf10364}, {0xa81a664b, 0xbc423001},
|
||||
{0xc24b8b70, 0xd0f89791}, {0xc76c51a3, 0x0654be30},
|
||||
{0xd192e819, 0xd6ef5218}, {0xd6990624, 0x5565a910},
|
||||
{0xf40e3585, 0x5771202a}, {0x106aa070, 0x32bbd1b8},
|
||||
{0x19a4c116, 0xb8d2d0c8}, {0x1e376c08, 0x5141ab53},
|
||||
{0x2748774c, 0xdf8eeb99}, {0x34b0bcb5, 0xe19b48a8},
|
||||
{0x391c0cb3, 0xc5c95a63}, {0x4ed8aa4a, 0xe3418acb},
|
||||
{0x5b9cca4f, 0x7763e373}, {0x682e6ff3, 0xd6b2b8a3},
|
||||
{0x748f82ee, 0x5defb2fc}, {0x78a5636f, 0x43172f60},
|
||||
{0x84c87814, 0xa1f0ab72}, {0x8cc70208, 0x1a6439ec},
|
||||
{0x90befffa, 0x23631e28}, {0xa4506ceb, 0xde82bde9},
|
||||
{0xbef9a3f7, 0xb2c67915}, {0xc67178f2, 0xe372532b},
|
||||
{0xca273ece, 0xea26619c}, {0xd186b8c7, 0x21c0c207},
|
||||
{0xeada7dd6, 0xcde0eb1e}, {0xf57d4f7f, 0xee6ed178},
|
||||
{0x06f067aa, 0x72176fba}, {0x0a637dc5, 0xa2c898a6},
|
||||
{0x113f9804, 0xbef90dae}, {0x1b710b35, 0x131c471b},
|
||||
{0x28db77f5, 0x23047d84}, {0x32caab7b, 0x40c72493},
|
||||
{0x3c9ebe0a, 0x15c9bebc}, {0x431d67c4, 0x9c100d4c},
|
||||
{0x4cc5d4be, 0xcb3e42b6}, {0x597f299c, 0xfc657e2a},
|
||||
{0x5fcb6fab, 0x3ad6faec}, {0x6c44198c, 0x4a475817}
|
||||
};
|
||||
|
||||
const SUI64 CSHA::sm_H512[SHA512LENGTH] =
|
||||
{
|
||||
{0x6a09e667, 0xf3bcc908},
|
||||
{0xbb67ae85, 0x84caa73b},
|
||||
{0x3c6ef372, 0xfe94f82b},
|
||||
{0xa54ff53a, 0x5f1d36f1},
|
||||
{0x510e527f, 0xade682d1},
|
||||
{0x9b05688c, 0x2b3e6c1f},
|
||||
{0x1f83d9ab, 0xfb41bd6b},
|
||||
{0x5be0cd19, 0x137e2179}
|
||||
};
|
||||
|
||||
//CONSTRUCTOR
|
||||
CSHA::CSHA(int iMethod)
|
||||
{
|
||||
//Check the method
|
||||
switch(iMethod)
|
||||
{
|
||||
case SHA160:
|
||||
{
|
||||
for(int i=0; i<SHA160LENGTH; i++)
|
||||
m_auiBuf[i] = sm_H160[i];
|
||||
m_auiBits[0] = 0;
|
||||
m_auiBits[1] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA256:
|
||||
{
|
||||
for(int i=0; i<SHA256LENGTH; i++)
|
||||
m_auiBuf[i] = sm_H256[i];
|
||||
m_auiBits[0] = 0;
|
||||
m_auiBits[1] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA384:
|
||||
{
|
||||
for(int i=0; i<SHA512LENGTH; i++)
|
||||
m_aoui64Buf[i] = sm_H384[i];
|
||||
m_aoui64Bits[0].m_uiLeft = 0;
|
||||
m_aoui64Bits[0].m_uiRight = 0;
|
||||
m_aoui64Bits[1].m_uiLeft = 0;
|
||||
m_aoui64Bits[1].m_uiRight = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
{
|
||||
for(int i=0; i<SHA512LENGTH; i++)
|
||||
m_aoui64Buf[i] = sm_H512[i];
|
||||
m_aoui64Bits[0].m_uiLeft = 0;
|
||||
m_aoui64Bits[0].m_uiRight = 0;
|
||||
m_aoui64Bits[1].m_uiLeft = 0;
|
||||
m_aoui64Bits[1].m_uiRight = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ostrstream ostr;
|
||||
ostr << "FileDigest ERROR: in CSHA() Constructor, Illegal Method " << iMethod << "!" << ends;
|
||||
string ostrMsg = ostr.str();
|
||||
ostr.freeze(false);
|
||||
throw runtime_error(ostrMsg);
|
||||
}
|
||||
}
|
||||
m_iMethod = iMethod;
|
||||
}
|
||||
|
||||
//Update context to reflect the concatenation of another buffer of bytes.
|
||||
void CSHA::AddData(char const* pcData, int iDataLength)
|
||||
{
|
||||
if(iDataLength < 0)
|
||||
throw runtime_error(string("FileDigest ERROR: in CSHA::AddData(), Data Length should be >= 0!"));
|
||||
unsigned int uiT;
|
||||
switch(m_iMethod)
|
||||
{
|
||||
case SHA160:
|
||||
case SHA256:
|
||||
{
|
||||
//Update bitcount
|
||||
uiT = m_auiBits[0];
|
||||
if((m_auiBits[0] = uiT + ((unsigned int)iDataLength << 3)) < uiT)
|
||||
m_auiBits[1]++; //Carry from low to high
|
||||
m_auiBits[1] += iDataLength >> 29;
|
||||
uiT = (uiT >> 3) & (BLOCKSIZE-1); //Bytes already
|
||||
//Handle any leading odd-sized chunks
|
||||
if(uiT != 0)
|
||||
{
|
||||
unsigned char* puc = (unsigned char*)m_aucIn + uiT;
|
||||
uiT = BLOCKSIZE - uiT;
|
||||
if(iDataLength < uiT)
|
||||
{
|
||||
memcpy(puc, pcData, iDataLength);
|
||||
return;
|
||||
}
|
||||
memcpy(puc, pcData, uiT);
|
||||
Transform();
|
||||
pcData += uiT;
|
||||
iDataLength -= uiT;
|
||||
}
|
||||
//Process data in 64-byte chunks
|
||||
while(iDataLength >= BLOCKSIZE)
|
||||
{
|
||||
memcpy(m_aucIn, pcData, BLOCKSIZE);
|
||||
Transform();
|
||||
pcData += BLOCKSIZE;
|
||||
iDataLength -= BLOCKSIZE;
|
||||
}
|
||||
//Handle any remaining bytes of data
|
||||
memcpy(m_aucIn, pcData, iDataLength);
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA384:
|
||||
case SHA512:
|
||||
{
|
||||
uiT = m_aoui64Bits[0].m_uiRight;
|
||||
unsigned int uiU = m_aoui64Bits[0].m_uiLeft;
|
||||
if((m_aoui64Bits[0].m_uiRight = uiT + ((unsigned int)iDataLength << 3)) < uiT)
|
||||
m_aoui64Bits[0].m_uiLeft++; //Carry from low to high
|
||||
unsigned int uiV = m_aoui64Bits[1].m_uiRight;
|
||||
if((m_aoui64Bits[0].m_uiLeft += iDataLength >> 29) < uiU)
|
||||
m_aoui64Bits[1].m_uiRight++;
|
||||
if(m_aoui64Bits[1].m_uiRight < uiV)
|
||||
m_aoui64Bits[1].m_uiLeft++;
|
||||
uiT = (uiT >> 3) & (BLOCKSIZE2-1); //Bytes already
|
||||
//Handle any leading odd-sized chunks
|
||||
if(uiT != 0)
|
||||
{
|
||||
unsigned char* puc = (unsigned char*)m_aucIn + uiT;
|
||||
uiT = BLOCKSIZE2 - uiT;
|
||||
if(iDataLength < uiT)
|
||||
{
|
||||
memcpy(puc, pcData, iDataLength);
|
||||
return;
|
||||
}
|
||||
memcpy(puc, pcData, uiT);
|
||||
Transform();
|
||||
pcData += uiT;
|
||||
iDataLength -= uiT;
|
||||
}
|
||||
//Process data in 64-byte chunks
|
||||
while(iDataLength >= BLOCKSIZE2)
|
||||
{
|
||||
memcpy(m_aucIn, pcData, BLOCKSIZE2);
|
||||
Transform();
|
||||
pcData += BLOCKSIZE2;
|
||||
iDataLength -= BLOCKSIZE2;
|
||||
}
|
||||
//Handle any remaining bytes of data
|
||||
memcpy(m_aucIn, pcData, iDataLength);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//Set the flag
|
||||
m_bAddData = true;
|
||||
}
|
||||
|
||||
//Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
//1 0*(64-bit count of bits processed, MSB-first)
|
||||
void CSHA::FinalDigest(char* pcDigest)
|
||||
{
|
||||
//Is the User's responsability to ensure that pcDigest is properly allocated 20, 32,
|
||||
//48 or 64 bytes, depending on the method
|
||||
if(false == m_bAddData)
|
||||
throw runtime_error(string("FileDigest ERROR: in CSHA::FinalDigest(), No data Added before call!"));
|
||||
switch(m_iMethod)
|
||||
{
|
||||
case SHA160:
|
||||
case SHA256:
|
||||
{
|
||||
unsigned int uiCount;
|
||||
unsigned char *puc;
|
||||
//Compute number of bytes mod 64
|
||||
uiCount = (m_auiBits[0] >> 3) & (BLOCKSIZE-1);
|
||||
//Set the first char of padding to 0x80. This is safe since there is
|
||||
//always at least one byte free
|
||||
puc = m_aucIn + uiCount;
|
||||
*puc++ = 0x80;
|
||||
//Bytes of padding needed to make 64 bytes
|
||||
uiCount = BLOCKSIZE - uiCount - 1;
|
||||
//Pad out to 56 mod 64
|
||||
if(uiCount < 8)
|
||||
{
|
||||
//Two lots of padding: Pad the first block to 64 bytes
|
||||
memset(puc, 0, uiCount);
|
||||
Transform();
|
||||
//Now fill the next block with 56 bytes
|
||||
memset(m_aucIn, 0, BLOCKSIZE-8);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Pad block to 56 bytes
|
||||
memset(puc, 0, uiCount - 8);
|
||||
}
|
||||
//Append length in bits and transform
|
||||
Word2Bytes(m_auiBits[1], &m_aucIn[BLOCKSIZE-8]);
|
||||
Word2Bytes(m_auiBits[0], &m_aucIn[BLOCKSIZE-4]);
|
||||
Transform();
|
||||
switch(m_iMethod)
|
||||
{
|
||||
case SHA160:
|
||||
{
|
||||
for(int i=0; i<SHA160LENGTH; i++,pcDigest+=4)
|
||||
Word2Bytes(m_auiBuf[i], reinterpret_cast<unsigned char*>(pcDigest));
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA256:
|
||||
{
|
||||
for(int i=0; i<SHA256LENGTH; i++,pcDigest+=4)
|
||||
Word2Bytes(m_auiBuf[i], reinterpret_cast<unsigned char*>(pcDigest));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA384:
|
||||
case SHA512:
|
||||
{
|
||||
unsigned char *puc;
|
||||
//Compute number of bytes mod 128
|
||||
unsigned int uiCount = (m_aoui64Bits[0].m_uiRight >> 3) & (BLOCKSIZE2-1);
|
||||
//Set the first char of padding to 0x80. This is safe since there is
|
||||
//always at least one byte free
|
||||
puc = m_aucIn + uiCount;
|
||||
*puc++ = 0x80;
|
||||
//Bytes of padding needed to make 128 bytes
|
||||
uiCount = BLOCKSIZE2 - uiCount - 1;
|
||||
//Pad out to 112 mod 128
|
||||
if(uiCount < 16)
|
||||
{
|
||||
//Two lots of padding: Pad the first block to 128 bytes
|
||||
memset(puc, 0, uiCount);
|
||||
Transform();
|
||||
//Now fill the next block with 112 bytes
|
||||
memset(m_aucIn, 0, BLOCKSIZE2-16);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Pad block to 112 bytes
|
||||
memset(puc, 0, uiCount - 16);
|
||||
}
|
||||
//Append length in bits and transform
|
||||
Word2Bytes(m_aoui64Bits[1], &m_aucIn[BLOCKSIZE2-16]);
|
||||
Word2Bytes(m_aoui64Bits[0], &m_aucIn[BLOCKSIZE2-8]);
|
||||
Transform();
|
||||
switch(m_iMethod)
|
||||
{
|
||||
case SHA384:
|
||||
{
|
||||
for(int i=0; i<SHA384LENGTH; i++,pcDigest+=8)
|
||||
Word2Bytes(m_aoui64Buf[i], reinterpret_cast<unsigned char*>(pcDigest));
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
{
|
||||
for(int i=0; i<SHA512LENGTH; i++,pcDigest+=8)
|
||||
Word2Bytes(m_aoui64Buf[i], reinterpret_cast<unsigned char*>(pcDigest));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
//Reinitialize
|
||||
Reset();
|
||||
}
|
||||
|
||||
//Reset current operation in order to prepare a new one
|
||||
void CSHA::Reset()
|
||||
{
|
||||
//Reinitialize
|
||||
switch(m_iMethod)
|
||||
{
|
||||
case SHA160:
|
||||
{
|
||||
for(int i=0; i<SHA160LENGTH; i++)
|
||||
m_auiBuf[i] = sm_H160[i];
|
||||
m_auiBits[0] = 0;
|
||||
m_auiBits[1] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA256:
|
||||
{
|
||||
for(int i=0; i<SHA256LENGTH; i++)
|
||||
m_auiBuf[i] = sm_H256[i];
|
||||
m_auiBits[0] = 0;
|
||||
m_auiBits[1] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA384:
|
||||
{
|
||||
for(int i=0; i<SHA512LENGTH; i++)
|
||||
m_aoui64Buf[i] = sm_H384[i];
|
||||
m_aoui64Bits[0].m_uiLeft = 0;
|
||||
m_aoui64Bits[0].m_uiRight = 0;
|
||||
m_aoui64Bits[1].m_uiLeft = 0;
|
||||
m_aoui64Bits[1].m_uiRight = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
{
|
||||
for(int i=0; i<SHA512LENGTH; i++)
|
||||
m_aoui64Buf[i] = sm_H512[i];
|
||||
m_aoui64Bits[0].m_uiLeft = 0;
|
||||
m_aoui64Bits[0].m_uiRight = 0;
|
||||
m_aoui64Bits[1].m_uiLeft = 0;
|
||||
m_aoui64Bits[1].m_uiRight = 0;
|
||||
}
|
||||
}
|
||||
//Reset the flag
|
||||
m_bAddData = false;
|
||||
}
|
||||
|
||||
//The core of the SHA algorithm, this alters an existing SHA hash to
|
||||
//reflect the addition of 16 longwords of new data.
|
||||
void CSHA::Transform()
|
||||
{
|
||||
switch(m_iMethod)
|
||||
{
|
||||
case SHA160:
|
||||
{
|
||||
//Expansion of m_aucIn
|
||||
unsigned char* pucIn = m_aucIn;
|
||||
unsigned int auiW[80];
|
||||
int i;
|
||||
for(i=0; i<16; i++,pucIn+=4)
|
||||
Bytes2Word(pucIn, auiW[i]);
|
||||
for(i=16; i<80; i++)
|
||||
auiW[i] = CircularShift(1, auiW[i-3]^auiW[i-8]^auiW[i-14]^auiW[i-16]);
|
||||
unsigned int temp;
|
||||
unsigned int A, B, C, D, E;
|
||||
A = m_auiBuf[0];
|
||||
B = m_auiBuf[1];
|
||||
C = m_auiBuf[2];
|
||||
D = m_auiBuf[3];
|
||||
E = m_auiBuf[4];
|
||||
for(i=0; i<20; i++)
|
||||
{
|
||||
temp = CircularShift(5, A) + ((B & C) | ((~B) & D)) + E + auiW[i] + sm_K160[0];
|
||||
E = D;
|
||||
D = C;
|
||||
C = CircularShift(30, B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
for(i=20; i<40; i++)
|
||||
{
|
||||
temp = CircularShift(5, A) + (B ^ C ^ D) + E + auiW[i] + sm_K160[1];
|
||||
E = D;
|
||||
D = C;
|
||||
C = CircularShift(30, B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
for(i=40; i<60; i++)
|
||||
{
|
||||
temp = CircularShift(5, A) + ((B & C) | (B & D) | (C & D)) + E + auiW[i] + sm_K160[2];
|
||||
E = D;
|
||||
D = C;
|
||||
C = CircularShift(30, B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
for(i=60; i<80; i++)
|
||||
{
|
||||
temp = CircularShift(5, A) + (B ^ C ^ D) + E + auiW[i] + sm_K160[3];
|
||||
E = D;
|
||||
D = C;
|
||||
C = CircularShift(30, B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
m_auiBuf[0] += A;
|
||||
m_auiBuf[1] += B;
|
||||
m_auiBuf[2] += C;
|
||||
m_auiBuf[3] += D;
|
||||
m_auiBuf[4] += E;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA256:
|
||||
{
|
||||
//Expansion of m_aucIn
|
||||
unsigned char* pucIn = m_aucIn;
|
||||
unsigned int auiW[64];
|
||||
int i;
|
||||
for(i=0; i<16; i++,pucIn+=4)
|
||||
Bytes2Word(pucIn, auiW[i]);
|
||||
for(i=16; i<64; i++)
|
||||
auiW[i] = sig1(auiW[i-2]) + auiW[i-7] + sig0(auiW[i-15]) + auiW[i-16];
|
||||
//OR
|
||||
//for(i=0; i<48; i++)
|
||||
// auiW[i+16] = sig1(auiW[i+14]) + auiW[i+9] + sig0(auiW[i+1]) + auiW[i];
|
||||
unsigned int a, b, c, d, e, f, g, h, t;
|
||||
a = m_auiBuf[0];
|
||||
b = m_auiBuf[1];
|
||||
c = m_auiBuf[2];
|
||||
d = m_auiBuf[3];
|
||||
e = m_auiBuf[4];
|
||||
f = m_auiBuf[5];
|
||||
g = m_auiBuf[6];
|
||||
h = m_auiBuf[7];
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[0] + auiW[0]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[1] + auiW[1]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[2] + auiW[2]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[3] + auiW[3]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[4] + auiW[4]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[5] + auiW[5]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[6] + auiW[6]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[7] + auiW[7]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[8] + auiW[8]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[9] + auiW[9]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[10] + auiW[10]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[11] + auiW[11]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[12] + auiW[12]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[13] + auiW[13]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[14] + auiW[14]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[15] + auiW[15]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[16] + auiW[16]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[17] + auiW[17]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[18] + auiW[18]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[19] + auiW[19]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[20] + auiW[20]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[21] + auiW[21]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[22] + auiW[22]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[23] + auiW[23]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[24] + auiW[24]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[25] + auiW[25]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[26] + auiW[26]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[27] + auiW[27]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[28] + auiW[28]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[29] + auiW[29]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[30] + auiW[30]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[31] + auiW[31]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[32] + auiW[32]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[33] + auiW[33]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[34] + auiW[34]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[35] + auiW[35]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[36] + auiW[36]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[37] + auiW[37]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[38] + auiW[38]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[39] + auiW[39]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[40] + auiW[40]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[41] + auiW[41]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[42] + auiW[42]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[43] + auiW[43]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[44] + auiW[44]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[45] + auiW[45]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[46] + auiW[46]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[47] + auiW[47]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[48] + auiW[48]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[49] + auiW[49]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[50] + auiW[50]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[51] + auiW[51]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[52] + auiW[52]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[53] + auiW[53]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[54] + auiW[54]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[55] + auiW[55]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K256[56] + auiW[56]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K256[57] + auiW[57]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K256[58] + auiW[58]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K256[59] + auiW[59]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K256[60] + auiW[60]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K256[61] + auiW[61]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K256[62] + auiW[62]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K256[63] + auiW[63]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
//OR
|
||||
/*
|
||||
unsigned int a, b, c, d, e, f, g, h, t1, t2;
|
||||
a = m_auiBuf[0];
|
||||
b = m_auiBuf[1];
|
||||
c = m_auiBuf[2];
|
||||
d = m_auiBuf[3];
|
||||
e = m_auiBuf[4];
|
||||
f = m_auiBuf[5];
|
||||
g = m_auiBuf[6];
|
||||
h = m_auiBuf[7];
|
||||
//
|
||||
for(i=0; i<64; i++)
|
||||
{
|
||||
t1 = h + SIG1(e) + CH(e, f, g) + sm_K256[i] + auiW[i];
|
||||
t2 = SIG0(a) + MAJ(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d+t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
*/
|
||||
m_auiBuf[0] += a;
|
||||
m_auiBuf[1] += b;
|
||||
m_auiBuf[2] += c;
|
||||
m_auiBuf[3] += d;
|
||||
m_auiBuf[4] += e;
|
||||
m_auiBuf[5] += f;
|
||||
m_auiBuf[6] += g;
|
||||
m_auiBuf[7] += h;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHA384:
|
||||
case SHA512:
|
||||
{
|
||||
//Expansion of m_aucIn
|
||||
unsigned char* pucIn = m_aucIn;
|
||||
SUI64 aoui64W[80];
|
||||
int i;
|
||||
for(i=0; i<16; i++,pucIn+=8)
|
||||
Bytes2Word(pucIn, aoui64W[i]);
|
||||
for(i=16; i<80; i++)
|
||||
aoui64W[i] = sig1(aoui64W[i-2]) + aoui64W[i-7] + sig0(aoui64W[i-15]) + aoui64W[i-16];
|
||||
SUI64 a, b, c, d, e, f, g, h, t;
|
||||
a = m_aoui64Buf[0];
|
||||
b = m_aoui64Buf[1];
|
||||
c = m_aoui64Buf[2];
|
||||
d = m_aoui64Buf[3];
|
||||
e = m_aoui64Buf[4];
|
||||
f = m_aoui64Buf[5];
|
||||
g = m_aoui64Buf[6];
|
||||
h = m_aoui64Buf[7];
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[0] + aoui64W[0]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[1] + aoui64W[1]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[2] + aoui64W[2]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[3] + aoui64W[3]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[4] + aoui64W[4]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[5] + aoui64W[5]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[6] + aoui64W[6]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[7] + aoui64W[7]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[8] + aoui64W[8]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[9] + aoui64W[9]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[10] + aoui64W[10]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[11] + aoui64W[11]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[12] + aoui64W[12]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[13] + aoui64W[13]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[14] + aoui64W[14]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[15] + aoui64W[15]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[16] + aoui64W[16]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[17] + aoui64W[17]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[18] + aoui64W[18]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[19] + aoui64W[19]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[20] + aoui64W[20]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[21] + aoui64W[21]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[22] + aoui64W[22]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[23] + aoui64W[23]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[24] + aoui64W[24]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[25] + aoui64W[25]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[26] + aoui64W[26]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[27] + aoui64W[27]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[28] + aoui64W[28]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[29] + aoui64W[29]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[30] + aoui64W[30]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[31] + aoui64W[31]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[32] + aoui64W[32]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[33] + aoui64W[33]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[34] + aoui64W[34]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[35] + aoui64W[35]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[36] + aoui64W[36]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[37] + aoui64W[37]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[38] + aoui64W[38]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[39] + aoui64W[39]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[40] + aoui64W[40]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[41] + aoui64W[41]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[42] + aoui64W[42]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[43] + aoui64W[43]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[44] + aoui64W[44]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[45] + aoui64W[45]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[46] + aoui64W[46]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[47] + aoui64W[47]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[48] + aoui64W[48]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[49] + aoui64W[49]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[50] + aoui64W[50]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[51] + aoui64W[51]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[52] + aoui64W[52]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[53] + aoui64W[53]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[54] + aoui64W[54]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[55] + aoui64W[55]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[56] + aoui64W[56]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[57] + aoui64W[57]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[58] + aoui64W[58]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[59] + aoui64W[59]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[60] + aoui64W[60]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[61] + aoui64W[61]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[62] + aoui64W[62]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[63] + aoui64W[63]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[64] + aoui64W[64]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[65] + aoui64W[65]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[66] + aoui64W[66]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[67] + aoui64W[67]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[68] + aoui64W[68]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[69] + aoui64W[69]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[70] + aoui64W[70]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[71] + aoui64W[71]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
t = h + SIG1(e) + CH(e, f, g) + sm_K512[72] + aoui64W[72]; h = t + SIG0(a) + MAJ(a, b, c); d += t;
|
||||
t = g + SIG1(d) + CH(d, e, f) + sm_K512[73] + aoui64W[73]; g = t + SIG0(h) + MAJ(h, a, b); c += t;
|
||||
t = f + SIG1(c) + CH(c, d, e) + sm_K512[74] + aoui64W[74]; f = t + SIG0(g) + MAJ(g, h, a); b += t;
|
||||
t = e + SIG1(b) + CH(b, c, d) + sm_K512[75] + aoui64W[75]; e = t + SIG0(f) + MAJ(f, g, h); a += t;
|
||||
t = d + SIG1(a) + CH(a, b, c) + sm_K512[76] + aoui64W[76]; d = t + SIG0(e) + MAJ(e, f, g); h += t;
|
||||
t = c + SIG1(h) + CH(h, a, b) + sm_K512[77] + aoui64W[77]; c = t + SIG0(d) + MAJ(d, e, f); g += t;
|
||||
t = b + SIG1(g) + CH(g, h, a) + sm_K512[78] + aoui64W[78]; b = t + SIG0(c) + MAJ(c, d, e); f += t;
|
||||
t = a + SIG1(f) + CH(f, g, h) + sm_K512[79] + aoui64W[79]; a = t + SIG0(b) + MAJ(b, c, d); e += t;
|
||||
//
|
||||
m_aoui64Buf[0] += a;
|
||||
m_aoui64Buf[1] += b;
|
||||
m_aoui64Buf[2] += c;
|
||||
m_aoui64Buf[3] += d;
|
||||
m_aoui64Buf[4] += e;
|
||||
m_aoui64Buf[5] += f;
|
||||
m_aoui64Buf[6] += g;
|
||||
m_aoui64Buf[7] += h;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
379
3rdparty/MultiEmulator/src/SHA.h
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
//SHA.h
|
||||
|
||||
#ifndef __SHA_H__
|
||||
#define __SHA_H__
|
||||
|
||||
#include "MessageDigest.h"
|
||||
|
||||
//Typical DISCLAIMER:
|
||||
//The code in this project is Copyright (C) 2003 by George Anescu. You have the right to
|
||||
//use and distribute the code in any way you see fit as long as this paragraph is included
|
||||
//with the distribution. No warranties or claims are made as to the validity of the
|
||||
//information and code contained herein, so use it at your own risk.
|
||||
|
||||
//Structure for representing an Unsigned Integer on 64 bits
|
||||
struct SUI64
|
||||
{
|
||||
//Data
|
||||
unsigned int m_uiLeft;
|
||||
unsigned int m_uiRight;
|
||||
|
||||
//Operators
|
||||
SUI64& operator++()
|
||||
{
|
||||
unsigned int uiTemp = m_uiRight;
|
||||
m_uiRight++;
|
||||
if(m_uiRight < uiTemp)
|
||||
m_uiLeft++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator--()
|
||||
{
|
||||
unsigned int uiTemp = m_uiRight;
|
||||
m_uiRight--;
|
||||
if(m_uiRight > uiTemp)
|
||||
m_uiLeft--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator+=(SUI64 const& roUI64)
|
||||
{
|
||||
m_uiRight += roUI64.m_uiRight;
|
||||
if(m_uiRight < roUI64.m_uiRight)
|
||||
m_uiLeft++;
|
||||
m_uiLeft += roUI64.m_uiLeft;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator|=(SUI64 const& roUI64)
|
||||
{
|
||||
m_uiRight |= roUI64.m_uiRight;
|
||||
m_uiLeft |= roUI64.m_uiLeft;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator&=(SUI64 const& roUI64)
|
||||
{
|
||||
m_uiRight &= roUI64.m_uiRight;
|
||||
m_uiLeft &= roUI64.m_uiLeft;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator^=(SUI64 const& roUI64)
|
||||
{
|
||||
m_uiRight ^= roUI64.m_uiRight;
|
||||
m_uiLeft ^= roUI64.m_uiLeft;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator<<=(unsigned int uiBits)
|
||||
{
|
||||
if(uiBits < 32)
|
||||
{
|
||||
(m_uiLeft <<= uiBits) |= (m_uiRight >> (32-uiBits));
|
||||
m_uiRight <<= uiBits;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiLeft = m_uiRight << (uiBits-32);
|
||||
m_uiRight = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SUI64& operator>>=(unsigned int uiBits)
|
||||
{
|
||||
if(uiBits < 32)
|
||||
{
|
||||
(m_uiRight >>= uiBits) |= (m_uiLeft << (32-uiBits));
|
||||
m_uiLeft >>= uiBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiRight = m_uiLeft >> (uiBits-32);
|
||||
m_uiLeft = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator>(SUI64 const& roUI64) const
|
||||
{
|
||||
if(m_uiLeft == roUI64.m_uiLeft)
|
||||
return m_uiRight > roUI64.m_uiRight;
|
||||
else
|
||||
return m_uiLeft > roUI64.m_uiLeft;
|
||||
}
|
||||
|
||||
bool operator<(SUI64 const& roUI64) const
|
||||
{
|
||||
if(m_uiLeft == roUI64.m_uiLeft)
|
||||
return m_uiRight < roUI64.m_uiRight;
|
||||
else
|
||||
return m_uiLeft < roUI64.m_uiLeft;
|
||||
}
|
||||
};
|
||||
|
||||
inline SUI64 operator+(SUI64 const& roUI64_1, SUI64 const& roUI64_2)
|
||||
{
|
||||
SUI64 temp = roUI64_1;
|
||||
temp += roUI64_2;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline SUI64 operator|(SUI64 const& roUI64_1, SUI64 const& roUI64_2)
|
||||
{
|
||||
SUI64 temp = roUI64_1;
|
||||
temp |= roUI64_2;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline SUI64 operator&(SUI64 const& roUI64_1, SUI64 const& roUI64_2)
|
||||
{
|
||||
SUI64 temp = roUI64_1;
|
||||
temp &= roUI64_2;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline SUI64 operator^(SUI64 const& roUI64_1, SUI64 const& roUI64_2)
|
||||
{
|
||||
SUI64 temp = roUI64_1;
|
||||
temp ^= roUI64_2;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline SUI64 operator<<(SUI64 const& roUI64, unsigned int uiBits)
|
||||
{
|
||||
SUI64 temp = roUI64;
|
||||
temp <<= uiBits;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline SUI64 operator>>(SUI64 const& roUI64, unsigned int uiBits)
|
||||
{
|
||||
SUI64 temp = roUI64;
|
||||
temp >>= uiBits;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline bool operator>(SUI64 const& roUI64_1, SUI64 const& roUI64_2)
|
||||
{
|
||||
return roUI64_1.operator>(roUI64_2);
|
||||
}
|
||||
|
||||
inline bool operator<(SUI64 const& roUI64_1, SUI64 const& roUI64_2)
|
||||
{
|
||||
return roUI64_1.operator<(roUI64_2);
|
||||
}
|
||||
|
||||
//SHA Message Digest algorithm
|
||||
//SHA160 TEST VALUES:
|
||||
//1)"abc"
|
||||
//"A9993E364706816ABA3E25717850C26C9CD0D89D"
|
||||
//
|
||||
//2)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
//"84983E441C3BD26EBAAE4AA1F95129E5E54670F1"
|
||||
//
|
||||
//3)1,000,000 repetitions of "a".
|
||||
//"34AA973CD4C4DAA4F61EEB2BDBAD27316534016F"
|
||||
//
|
||||
//SHA256 TEST VALUES:
|
||||
//1)One-Block Message "abc"
|
||||
//"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
||||
//
|
||||
//2)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
//"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
|
||||
//
|
||||
//3)Multi-Block Message "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
//"CF5B16A778AF8380036CE59E7B0492370B249B11E8F07A51AFAC45037AFEE9D1"
|
||||
//
|
||||
//4)Long Message "a" 1,000,000 times
|
||||
//"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
|
||||
//
|
||||
//SHA384 TEST VALUES:
|
||||
//1)One-Block Message "abc"
|
||||
//"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"
|
||||
//
|
||||
//2)Multi-Block Message "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
//"09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039"
|
||||
//
|
||||
//3)Long Message "a" 1,000,000 times
|
||||
//"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985"
|
||||
//
|
||||
//SHA512 TEST VALUES:
|
||||
//1)One-Block Message "abc"
|
||||
//"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a8
|
||||
//36ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
|
||||
//
|
||||
//2)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
//"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4
|
||||
//331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
|
||||
//
|
||||
//3)""
|
||||
//"CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0
|
||||
//FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E"
|
||||
//
|
||||
//4)Long Message "a" 1,000,000 times
|
||||
//"E718483D0CE769644E2E42C7BC15B4638E1F98B13B2044285632A803AFA973EBDE0FF244877EA60A
|
||||
//4CB0432CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B"
|
||||
|
||||
class CSHA : public IMessageDigest
|
||||
{
|
||||
public:
|
||||
enum { SHA160=0, SHA256=1, SHA384=2, SHA512=3 };
|
||||
//CONSTRUCTOR
|
||||
CSHA(int iMethod=SHA160);
|
||||
//Update context to reflect the concatenation of another buffer of bytes.
|
||||
void AddData(char const* pcData, int iDataLength);
|
||||
//Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
//1 0*(64-bit count of bits processed, MSB-first)
|
||||
void FinalDigest(char* pcDigest);
|
||||
//Reset current operation in order to prepare a new one
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
//Transformation Function
|
||||
void Transform();
|
||||
//The Method
|
||||
int m_iMethod;
|
||||
enum { BLOCKSIZE2 = BLOCKSIZE<<1 };
|
||||
//For 32 bits Integers
|
||||
enum { SHA160LENGTH=5, SHA256LENGTH=8 };
|
||||
//Context Variables
|
||||
unsigned int m_auiBuf[SHA256LENGTH]; //Maximum for SHA256
|
||||
unsigned int m_auiBits[2];
|
||||
unsigned char m_aucIn[BLOCKSIZE2]; //128 bytes for SHA384, SHA512
|
||||
//Internal auxiliary static functions
|
||||
static unsigned int CircularShift(unsigned int uiBits, unsigned int uiWord);
|
||||
static unsigned int CH(unsigned int x, unsigned int y, unsigned int z);
|
||||
static unsigned int MAJ(unsigned int x, unsigned int y, unsigned int z);
|
||||
static unsigned int SIG0(unsigned int x);
|
||||
static unsigned int SIG1(unsigned int x);
|
||||
static unsigned int sig0(unsigned int x);
|
||||
static unsigned int sig1(unsigned int x);
|
||||
static void Bytes2Word(unsigned char const* pcBytes, unsigned int& ruiWord);
|
||||
static void Word2Bytes(unsigned int const& ruiWord, unsigned char* pcBytes);
|
||||
static const unsigned int sm_K160[4];
|
||||
static const unsigned int sm_H160[SHA160LENGTH];
|
||||
static const unsigned int sm_K256[64];
|
||||
static const unsigned int sm_H256[SHA256LENGTH];
|
||||
|
||||
//For 64 bits Integers
|
||||
enum { SHA384LENGTH=6, SHA512LENGTH=8 };
|
||||
//Context Variables
|
||||
SUI64 m_aoui64Buf[SHA512LENGTH]; //Maximum for SHA512
|
||||
SUI64 m_aoui64Bits[2];
|
||||
//Internal auxiliary static functions
|
||||
static SUI64 CircularShift(unsigned int uiBits, SUI64 const& roui64Word);
|
||||
static SUI64 CH(SUI64 const& x, SUI64 const& y, SUI64 const& z);
|
||||
static SUI64 MAJ(SUI64 const& x, SUI64 const& y, SUI64 const& z);
|
||||
static SUI64 SIG0(SUI64 const& x);
|
||||
static SUI64 SIG1(SUI64 const& x);
|
||||
static SUI64 sig0(SUI64 const& x);
|
||||
static SUI64 sig1(SUI64 const& x);
|
||||
static void Bytes2Word(unsigned char const* pcBytes, SUI64& ruiWord);
|
||||
static void Word2Bytes(SUI64 const& ruiWord, unsigned char* pcBytes);
|
||||
static const SUI64 sm_H384[SHA512LENGTH]; //Dim is as 512
|
||||
static const SUI64 sm_K512[80];
|
||||
static const SUI64 sm_H512[SHA512LENGTH];
|
||||
};
|
||||
|
||||
inline unsigned int CSHA::CircularShift(unsigned int uiBits, unsigned int uiWord)
|
||||
{
|
||||
return (uiWord << uiBits) | (uiWord >> (32-uiBits));
|
||||
}
|
||||
|
||||
inline unsigned int CSHA::CH(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return ((x&(y^z))^z);
|
||||
}
|
||||
|
||||
inline unsigned int CSHA::MAJ(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return (((x|y)&z)|(x&y));
|
||||
}
|
||||
|
||||
inline unsigned int CSHA::SIG0(unsigned int x)
|
||||
{
|
||||
return ((x >> 2)|(x << 30)) ^ ((x >> 13)|(x << 19)) ^ ((x >> 22)|(x << 10));
|
||||
}
|
||||
|
||||
inline unsigned int CSHA::SIG1(unsigned int x)
|
||||
{
|
||||
return ((x >> 6)|(x << 26)) ^ ((x >> 11)|(x << 21)) ^ ((x >> 25)|(x << 7));
|
||||
}
|
||||
|
||||
inline unsigned int CSHA::sig0(unsigned int x)
|
||||
{
|
||||
return ((x >> 7)|(x << 25)) ^ ((x >> 18)|(x << 14)) ^ (x >> 3);
|
||||
}
|
||||
|
||||
inline unsigned int CSHA::sig1(unsigned int x)
|
||||
{
|
||||
return ((x >> 17)|(x << 15)) ^ ((x >> 19)|(x << 13)) ^ (x >> 10);
|
||||
}
|
||||
|
||||
inline void CSHA::Bytes2Word(unsigned char const* pcBytes, unsigned int& ruiWord)
|
||||
{
|
||||
ruiWord = (unsigned int)*(pcBytes+3) | (unsigned int)(*(pcBytes+2)<<8) |
|
||||
(unsigned int)(*(pcBytes+1)<<16) | (unsigned int)(*pcBytes<<24);
|
||||
}
|
||||
|
||||
inline void CSHA::Word2Bytes(unsigned int const& ruiWord, unsigned char* pcBytes)
|
||||
{
|
||||
pcBytes += 3;
|
||||
*pcBytes = ruiWord & 0xff;
|
||||
*--pcBytes = (ruiWord>>8) & 0xff;
|
||||
*--pcBytes = (ruiWord>>16) & 0xff;
|
||||
*--pcBytes = (ruiWord>>24) & 0xff;
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::CircularShift(unsigned int uiBits, SUI64 const& roui64Word)
|
||||
{
|
||||
return (roui64Word << uiBits) | (roui64Word >> (64-uiBits));
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::CH(SUI64 const& x, SUI64 const& y, SUI64 const& z)
|
||||
{
|
||||
return ((x&(y^z))^z);
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::MAJ(SUI64 const& x, SUI64 const& y, SUI64 const& z)
|
||||
{
|
||||
return (((x|y)&z)|(x&y));
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::SIG0(SUI64 const& x)
|
||||
{
|
||||
return ((x >> 28)|(x << 36)) ^ ((x >> 34)|(x << 30)) ^ ((x >> 39)|(x << 25));
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::SIG1(SUI64 const& x)
|
||||
{
|
||||
return ((x >> 14)|(x << 50)) ^ ((x >> 18)|(x << 46)) ^ ((x >> 41)|(x << 23));
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::sig0(SUI64 const& x)
|
||||
{
|
||||
return ((x >> 1)|(x << 63)) ^ ((x >> 8)|(x << 56)) ^ (x >> 7);
|
||||
}
|
||||
|
||||
inline SUI64 CSHA::sig1(SUI64 const& x)
|
||||
{
|
||||
return ((x >> 19)|(x << 45)) ^ ((x >> 61)|(x << 3)) ^ (x >> 6);
|
||||
}
|
||||
|
||||
inline void CSHA::Bytes2Word(unsigned char const* pcBytes, SUI64& ruiWord)
|
||||
{
|
||||
Bytes2Word(pcBytes+4, ruiWord.m_uiRight);
|
||||
Bytes2Word(pcBytes, ruiWord.m_uiLeft);
|
||||
}
|
||||
|
||||
inline void CSHA::Word2Bytes(SUI64 const& ruiWord, unsigned char* pcBytes)
|
||||
{
|
||||
Word2Bytes(ruiWord.m_uiRight, pcBytes+4);
|
||||
Word2Bytes(ruiWord.m_uiLeft, pcBytes);
|
||||
}
|
||||
|
||||
#endif // __SHA_H__
|
||||
13
3rdparty/MultiEmulator/src/Setti.cpp
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "multi_emulator.h"
|
||||
|
||||
int GenerateSetti(void *pDest)
|
||||
{
|
||||
auto pTicket = (int *)pDest;
|
||||
|
||||
pTicket[0] = 0xD4CA7F7B;
|
||||
pTicket[1] = 0xC7DB6023;
|
||||
pTicket[2] = 0x6D6A2E1F;
|
||||
pTicket[5] = 0xB4C43105;
|
||||
|
||||
return 768;
|
||||
}
|
||||
18
3rdparty/MultiEmulator/src/SteamEmu.cpp
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "multi_emulator.h"
|
||||
int GenerateSteamEmu(void *pDest, int nSteamID)
|
||||
{
|
||||
auto pTicket = (int *)pDest;
|
||||
|
||||
pTicket[20] = -1; // +80, dproto/reunion wants this value to be -1, but if this value
|
||||
// does not match -1, then instead of SteamID in [21] cell
|
||||
// client IP address that xored with 0x25730981 number should
|
||||
// be used. But dproto/reunion will just skip ticket validation
|
||||
// in that case.
|
||||
|
||||
pTicket[21] = nSteamID; // +84, SteamId, low part. Actually, this is just system volume serial
|
||||
// number, which comes from GetVolumeInformationA() function. If
|
||||
// function failed (returned 0), then instead of volume serial number
|
||||
// 777 number will be written to the ticket.
|
||||
|
||||
return 768;
|
||||
}
|
||||
12
3rdparty/MultiEmulator/src/StrUtils.cpp
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "StrUtils.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void CreateRandomString(char *pszDest, int nLength)
|
||||
{
|
||||
static const char c_szAlphaNum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
for (int i = 0; i < nLength; ++i)
|
||||
pszDest[i] = c_szAlphaNum[rand() % (sizeof(c_szAlphaNum) - 1)];
|
||||
|
||||
pszDest[nLength] = '\0';
|
||||
}
|
||||
3
3rdparty/MultiEmulator/src/StrUtils.h
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void CreateRandomString(char *pszDest, int nLength);
|
||||
24
3rdparty/MultiEmulator/wscript
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# mittorn, 2018
|
||||
|
||||
from waflib import Logs
|
||||
import os
|
||||
|
||||
top = '.'
|
||||
|
||||
def options(opt):
|
||||
return
|
||||
|
||||
def configure(conf):
|
||||
return
|
||||
|
||||
def build(bld):
|
||||
bld.stlib(
|
||||
source = bld.path.ant_glob(['src/*.cpp']),
|
||||
target = 'MultiEmulator',
|
||||
features = 'cxx',
|
||||
includes = ['include/', 'src/'],
|
||||
export_includes = ['include/'],
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM
|
||||
)
|
||||
1
3rdparty/bzip2/bz_version.h
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#define BZ_VERSION "1.1.0-fwgs"
|
||||
15
3rdparty/bzip2/wscript
vendored
@@ -14,14 +14,21 @@ def configure(conf):
|
||||
conf.define('BZ_UNIX', 1)
|
||||
|
||||
def build(bld):
|
||||
bld(features = 'subst', source = 'bzip2/bz_version.h.in', target = 'bzip2/bz_version.h', BZ_VERSION='1.1.0-fwgs', name = 'bz_version')
|
||||
# bld(
|
||||
# features = 'subst',
|
||||
# source = 'bzip2/bz_version.h.in',
|
||||
# target = 'bz_version.h',
|
||||
# BZ_VERSION='1.1.0-fwgs'
|
||||
# )
|
||||
|
||||
bz_sources = ['bzip2/blocksort.c', 'bzip2/huffman.c', 'bzip2/crctable.c', 'bzip2/randtable.c', 'bzip2/compress.c', 'bzip2/decompress.c', 'bzip2/bzlib.c']
|
||||
|
||||
bld.stlib(
|
||||
source = bz_sources,
|
||||
target = 'bzip2',
|
||||
use = 'bz_version',
|
||||
includes = 'bzip2/',
|
||||
export_includes = 'bzip2/'
|
||||
# use = 'bz_version.h',
|
||||
features = 'c',
|
||||
includes = ['.', 'bzip2/'],
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
export_includes = ['bzip2/']
|
||||
)
|
||||
|
||||
3
3rdparty/extras/wscript
vendored
@@ -23,6 +23,7 @@ def build(bld):
|
||||
|
||||
bld(features='zip',
|
||||
name = 'extras.pk3',
|
||||
files = srcdir.ant_glob('**/*', excl=['scripts/**']),
|
||||
files = srcdir.ant_glob('**/*'),
|
||||
relative_to = srcdir,
|
||||
compresslevel = 0,
|
||||
install_path = install_path)
|
||||
|
||||
2
3rdparty/extras/xash-extras
vendored
2
3rdparty/gl-wes-v2
vendored
2
3rdparty/gl4es/gl4es
vendored
8
3rdparty/gl4es/wscript
vendored
@@ -13,12 +13,12 @@ def configure(conf):
|
||||
|
||||
def build(bld):
|
||||
gl4es_srcdir = bld.path.find_node('gl4es/src')
|
||||
cflags = []
|
||||
if bld.env.COMPILER_CC != 'msvc':
|
||||
cflags += ['-w', '-fvisibility=hidden', '-std=gnu99']
|
||||
|
||||
bld.stlib(source = gl4es_srcdir.ant_glob(['gl/*.c', 'gl/*/*.c', 'glx/hardext.c']),
|
||||
target = 'gl4es',
|
||||
features = 'c',
|
||||
includes = ['gl4es/src', 'gl4es/src/gl', 'gl4es/src/glx', 'gl4es/include'],
|
||||
defines = ['NOX11', 'NO_GBM', 'NO_INIT_CONSTRUCTOR', 'DEFAULT_ES=2', 'NOEGL', 'NO_LOADER', 'STATICLIB'],
|
||||
cflags = cflags,
|
||||
cflags = ['-w', '-fvisibility=hidden', '-std=gnu99'],
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
export_includes = '.')
|
||||
|
||||
1
3rdparty/libbacktrace/libbacktrace
vendored
195
3rdparty/libbacktrace/wscript
vendored
@@ -1,195 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from waflib import TaskGen
|
||||
from waflib.Tools.c_config import DEFKEYS
|
||||
|
||||
FRAGMENT_ATOMIC='''int i;
|
||||
int main(void) {
|
||||
__atomic_load_n(&i, __ATOMIC_ACQUIRE);
|
||||
__atomic_store_n(&i, 1, __ATOMIC_RELEASE);
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_SYNC='''int i;
|
||||
int main (void) {
|
||||
__sync_bool_compare_and_swap (&i, i, i);
|
||||
__sync_lock_test_and_set (&i, 1);
|
||||
__sync_lock_release (&i);
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
|
||||
int main(void) { return getpagesize(); }'''
|
||||
|
||||
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
|
||||
int main(void) { return getexecname() != 0; }'''
|
||||
|
||||
FRAGMENT_STRNLEN='''#include <string.h>
|
||||
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
|
||||
|
||||
FRAGMENT_DL_ITERATE_PHDR='''#include <%s>
|
||||
int main(void) { return dl_iterate_phdr(0, 0); }'''
|
||||
|
||||
FRAGMENT_FCNTL='''#include <fcntl.h>
|
||||
int main(void) { return fcntl(0, 0, 0); }'''
|
||||
|
||||
FRAGMENT_GETIPINFO='''#include "unwind.h"
|
||||
struct _Unwind_Context *context;
|
||||
int ip_before_insn = 0;
|
||||
int main(void) { return _Unwind_GetIPInfo(context, &ip_before_insn); }'''
|
||||
|
||||
FRAGMENT_LOADQUERY='''#include <sys/ldr.h>
|
||||
#include <sys/debug.h>
|
||||
int main(void) { return loadquery(0, 0, 0); }'''
|
||||
|
||||
FRAGMENT_KERN_PROC='''#include <sys/sysctl.h>
|
||||
#if !defined(%s) || !defined(KERN_PROC_PATHNAME)
|
||||
#error
|
||||
#endif
|
||||
int main(void) { return 0; }'''
|
||||
|
||||
FRAGMENT_LSTAT='''#include <sys/stat.h>
|
||||
struct stat st;
|
||||
int main(int argc, char **argv) { return lstat(argv[0], &st); }'''
|
||||
|
||||
FRAGMENT_READLINK='''#include <unistd.h>
|
||||
char buf[100];
|
||||
int main(int argc, char **argv) { return readlink(argv[0], buf, sizeof(buf)); }'''
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
# add unsupported platforms here
|
||||
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos', 'irix']:
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
# win32 has it's own dbghelp-based backtrace, that's why we ship PDBs
|
||||
if conf.env.COMPILER_CC == 'msvc':
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
if not conf.path.find_dir('libbacktrace') or not conf.path.find_dir('libbacktrace/config'):
|
||||
conf.fatal('Can\'t find libbacktrace submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
conf.define('BACKTRACE_ELF_SIZE', 64 if conf.env.DEST_SIZEOF_VOID_P == 8 else 32)
|
||||
conf.define('BACKTRACE_XCOFF_SIZE', 64 if conf.env.DEST_SIZEOF_VOID_P == 8 else 32)
|
||||
conf.define('_ALL_SOURCE', 1)
|
||||
conf.define('_GNU_SOURCE', 1)
|
||||
conf.define('_POSIX_PTHREAD_SEMANTICS', 1)
|
||||
conf.define('_TANDEM_SOURCE', 1)
|
||||
conf.define('__EXTENSIONS__', 1)
|
||||
conf.define('_DARWIN_USE_64_BIT_INODE', 1)
|
||||
conf.define('_LARGE_FILES', 1)
|
||||
conf.check_large_file(compiler='c', execute=False, mandatory=False) # sets _FILE_OFFSET_BITS
|
||||
|
||||
conf.env.CFLAGS_EXTRAFLAGS = conf.filter_cflags(['-funwind-tables', '-g'], [])
|
||||
|
||||
if conf.filter_cflags(['-frandom-seed=test'], []):
|
||||
conf.env.HAVE_FRANDOM_SEED = True
|
||||
|
||||
def check_header(hdr):
|
||||
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr, 'compiler': 'c'}
|
||||
|
||||
def check_frag(frag, msg, define, **kw):
|
||||
return dict({'fragment': frag, 'msg':'... %s' % msg, 'mandatory': False, 'define_name': define, 'compiler': 'c'}, **kw)
|
||||
|
||||
conf.multicheck(
|
||||
check_header('dlfcn.h'),
|
||||
check_header('inttypes.h'),
|
||||
check_header('link.h'),
|
||||
check_header('sys/link.h'),
|
||||
check_header('mach-o/dyld.h'),
|
||||
check_header('memory.h'),
|
||||
check_header('stdint.h'),
|
||||
check_header('stdlib.h'),
|
||||
check_header('strings.h'),
|
||||
check_header('string.h'),
|
||||
check_header('sys/ldr.h'),
|
||||
check_header('sys/mman.h'),
|
||||
check_header('sys/stat.h'),
|
||||
check_header('sys/types.h'),
|
||||
check_header('tlhelp32.h'),
|
||||
check_header('unistd.h'),
|
||||
check_header('windows.h'),
|
||||
|
||||
check_frag(FRAGMENT_ATOMIC, '__atomic extensions', 'HAVE_ATOMIC_FUNCTIONS'),
|
||||
check_frag(FRAGMENT_SYNC, ' __sync extensions', 'HAVE_SYNC_FUNCTIONS'),
|
||||
check_frag(FRAGMENT_GETPAGESIZE, ' getpagesize function', 'HAVE_DECL_GETPAGESIZE'),
|
||||
check_frag(FRAGMENT_STRNLEN, ' strnlen function', 'HAVE_DECL_STRNLEN'),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'link.h', ' dl_iterate_phdr function in link.h', 'HAVE_DL_ITERATE_PHDR_LINK_H', after_tests=['link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', ' dl_iterate_phdr function in sys/link.h', 'HAVE_DL_ITERATE_PHDR_SYS_LINK_H', after_tests=['sys/link.h']),
|
||||
check_frag(FRAGMENT_FCNTL, 'fnctl function', 'HAVE_FCNTL'),
|
||||
check_frag(FRAGMENT_GETEXECNAME, 'getexecname function','HAVE_GETEXECNAME'),
|
||||
check_frag(FRAGMENT_GETIPINFO, '_Unwind_GetIPInfo function', 'HAVE_GETIPINFO'),
|
||||
check_frag(FRAGMENT_KERN_PROC % 'KERN_PROC', 'KERN_PROC and KERN_PROC_PATHNAME defines', 'HAVE_KERN_PROC'),
|
||||
check_frag(FRAGMENT_KERN_PROC % 'KERN_PROC_ARGS', 'KERN_PROC_ARGS and KERN_PROC_PATHNAME defines', 'HAVE_KERN_PROC_ARGS'),
|
||||
check_frag(FRAGMENT_LOADQUERY, 'loadquery function', 'HAVE_LOADQUERY'),
|
||||
check_frag(FRAGMENT_LSTAT, 'lstat function', 'HAVE_LSTAT'),
|
||||
check_frag(FRAGMENT_READLINK, 'readlink function', 'HAVE_READLINK'),
|
||||
|
||||
# {'lib':'lzma', 'define_name':'HAVE_LIBLZMA', 'uselib_store':'lzma', 'msg':'... lzma library', 'mandatory':False},
|
||||
# {'lib':'z', 'define_name':'HAVE_ZLIB', 'uselib_store':'z', 'msg':'... zlib library', 'mandatory':False},
|
||||
# {'lib':'zstd', 'define_name':'HAVE_ZSTD', 'uselib_store':'zstd', 'msg':'... zstd library', 'mandatory':False},
|
||||
msg='Checking for in parallel'
|
||||
)
|
||||
|
||||
if conf.is_defined('HAVE_DL_ITERATE_PHDR_LINK_H') or conf.is_defined('HAVE_DL_ITERATE_PHDR_SYS_LINK_H'):
|
||||
conf.define('HAVE_DL_ITERATE_PHDR', 1)
|
||||
|
||||
conf.env[DEFKEYS].sort()
|
||||
|
||||
conf.write_config_header()
|
||||
|
||||
conf.define('BACKTRACE_SUPPORTED', 1)
|
||||
conf.define('BACKTRACE_USES_MALLOC', 0)
|
||||
conf.define('BACKTRACE_SUPPORTS_THREADS', 1)
|
||||
conf.define('BACKTRACE_SUPPORTS_DATA', conf.env.DEST_BINFMT in ['elf', 'mac-o'])
|
||||
|
||||
conf.write_config_header('backtrace-supported.h')
|
||||
|
||||
@TaskGen.feature('frandomseed')
|
||||
@TaskGen.after_method('propagate_uselib_vars')
|
||||
def process_frandom_seed(ctx):
|
||||
tasks = getattr(ctx, 'compiled_tasks', [])
|
||||
|
||||
for task in tasks:
|
||||
out = task.outputs[0]
|
||||
task.env.CFLAGS = list(task.env.CFLAGS) # need a copy
|
||||
task.env.CFLAGS += ['-frandom-seed=%s' % out.path_from(out.ctx.bldnode)]
|
||||
|
||||
def build(bld):
|
||||
if bld.env.DISABLE_LIBBACKTRACE:
|
||||
return
|
||||
|
||||
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c']
|
||||
|
||||
if bld.env.DEST_OS == 'win32':
|
||||
sources += ['read.c', 'alloc.c']
|
||||
else:
|
||||
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
|
||||
sources += ['mmap.c', 'mmapio.c']
|
||||
|
||||
if bld.env.DEST_BINFMT == 'pe':
|
||||
sources += ['pecoff.c']
|
||||
elif bld.env.DEST_BINFMT == 'mac-o':
|
||||
sources += ['macho.c']
|
||||
elif bld.env.DEST_BINFMT == 'elf':
|
||||
sources += ['elf.c']
|
||||
else:
|
||||
sources += ['unknown.c']
|
||||
|
||||
task = bld.stlib(
|
||||
source = ['libbacktrace/' + i for i in sources],
|
||||
# while we're using upstream libbacktrace, sometimes compiler picks up it's own version that isn't built with required options
|
||||
target = 'backtrace_custom',
|
||||
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
|
||||
use = 'EXTRAFLAGS lzma z zstd',
|
||||
includes = '. libbacktrace/',
|
||||
export_defines = 'HAVE_LIBBACKTRACE=1',
|
||||
export_includes = 'libbacktrace/'
|
||||
)
|
||||
|
||||
1
3rdparty/libogg/libogg
vendored
50
3rdparty/libogg/wscript
vendored
@@ -1,50 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
if not conf.path.find_dir('libogg') or not conf.path.find_dir('libogg/src'):
|
||||
conf.fatal('Can\'t find libogg submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
conf.env.INCLUDE_INTTYPES_H = 0
|
||||
conf.env.INCLUDE_SYS_TYPES_H = 0
|
||||
conf.env.INCLUDE_STDINT_H = 0
|
||||
|
||||
if conf.check_cc(header_name='inttypes.h', mandatory = False):
|
||||
conf.env.INCLUDE_INTTYPES_H = 1
|
||||
elif conf.check_cc(header_name='sys/types.h', mandatory = False):
|
||||
conf.env.INCLUDE_SYS_TYPES_H = 1
|
||||
elif conf.check_cc(header_name='stdint.h', mandatory = False):
|
||||
conf.env.INCLUDE_STDINT_H = 1
|
||||
|
||||
def build(bld):
|
||||
sources = bld.path.ant_glob([
|
||||
'libogg/src/*.c'
|
||||
])
|
||||
|
||||
bld(
|
||||
features = 'subst',
|
||||
name = 'libogg_config_types',
|
||||
source = 'libogg/include/ogg/config_types.h.in',
|
||||
target = 'libogg/include/ogg/config_types.h',
|
||||
INCLUDE_INTTYPES_H = bld.env.INCLUDE_INTTYPES_H,
|
||||
INCLUDE_SYS_TYPES_H = bld.env.INCLUDE_SYS_TYPES_H,
|
||||
INCLUDE_STDINT_H = bld.env.INCLUDE_STDINT_H,
|
||||
SIZE16 = 'int16_t',
|
||||
USIZE16 = 'uint16_t',
|
||||
SIZE32 = 'int32_t',
|
||||
USIZE32 = 'uint32_t',
|
||||
SIZE64 = 'int64_t',
|
||||
USIZE64 = 'uint64_t'
|
||||
)
|
||||
|
||||
bld.stlib(
|
||||
source = sources,
|
||||
target = 'ogg',
|
||||
use = 'libogg_config_types',
|
||||
includes = 'libogg/include/',
|
||||
export_includes = 'libogg/include/'
|
||||
)
|
||||
1
3rdparty/library_suffix
vendored
1
3rdparty/maintui
vendored
2
3rdparty/mainui
vendored
107
3rdparty/mbedtls/compat.c
vendored
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
compat.c - mbedTLS platform overrides for targets upstream doesn't cover
|
||||
Copyright (C) 2026 Xash3D FWGS contributors
|
||||
|
||||
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 3 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
WinXP: legacy CryptGenRandom via advapi32
|
||||
Source: ttps://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom
|
||||
|
||||
PSVita: sceKernelGetRandomNumber from psp2/kernel/rng.h (64-byte cap).
|
||||
Source: https://github.com/vitasdk/vita-headers/blob/master/include/psp2/kernel/rng.h
|
||||
|
||||
NSwitch: randomGet from libnx.
|
||||
Source: https://github.com/switchbrew/libnx/blob/master/nx/include/switch/kernel/random.h
|
||||
*/
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined( MBEDTLS_PLATFORM_MS_TIME_ALT )
|
||||
|
||||
mbedtls_ms_time_t mbedtls_ms_time( void )
|
||||
{
|
||||
extern double Platform_DoubleTime( void );
|
||||
|
||||
return (mbedtls_ms_time_t)( Platform_DoubleTime() * 1000.0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PLATFORM_MS_TIME_ALT */
|
||||
|
||||
#if defined( MBEDTLS_PSA_DRIVER_GET_ENTROPY )
|
||||
#if defined( _WIN32 ) && !defined( _WIN64 )
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
int mbedtls_platform_get_entropy( psa_driver_get_entropy_flags_t flags, size_t *estimate_bits, unsigned char *output, size_t output_size )
|
||||
{
|
||||
if( flags != 0 )
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
HCRYPTPROV prov;
|
||||
if( !CryptAcquireContextW( &prov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT ))
|
||||
return PSA_ERROR_INSUFFICIENT_ENTROPY;
|
||||
|
||||
if( !CryptGenRandom( prov, (DWORD)output_size, output ))
|
||||
{
|
||||
CryptReleaseContext( prov, 0 );
|
||||
return PSA_ERROR_INSUFFICIENT_ENTROPY;
|
||||
}
|
||||
|
||||
CryptReleaseContext( prov, 0 );
|
||||
*estimate_bits = 8 * output_size;
|
||||
return 0;
|
||||
}
|
||||
#elif defined( __vita__ )
|
||||
#include <psp2/kernel/rng.h>
|
||||
|
||||
int mbedtls_platform_get_entropy( psa_driver_get_entropy_flags_t flags, size_t *estimate_bits, unsigned char *output, size_t output_size )
|
||||
{
|
||||
if( flags != 0 )
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
size_t total = 0;
|
||||
while( total < output_size )
|
||||
{
|
||||
size_t chunk = output_size - total;
|
||||
|
||||
if( chunk > 64 )
|
||||
chunk = 64;
|
||||
|
||||
if( sceKernelGetRandomNumber( output + total, chunk ) != 0 )
|
||||
return PSA_ERROR_INSUFFICIENT_ENTROPY;
|
||||
|
||||
total += chunk;
|
||||
}
|
||||
|
||||
*estimate_bits = 8 * output_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined( __SWITCH__ )
|
||||
#include <switch.h>
|
||||
|
||||
int mbedtls_platform_get_entropy( psa_driver_get_entropy_flags_t flags, size_t *estimate_bits, unsigned char *output, size_t output_size )
|
||||
{
|
||||
if( flags != 0 )
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
randomGet( output, output_size );
|
||||
*estimate_bits = 8 * output_size;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#error "MBEDTLS_PSA_DRIVER_GET_ENTROPY enabled but no platform impl in compat.c"
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_PSA_DRIVER_GET_ENTROPY */
|
||||
1
3rdparty/mbedtls/mbedtls
vendored
67
3rdparty/mbedtls/wscript
vendored
@@ -1,67 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
def options(opt):
|
||||
grp = opt.add_option_group('mbedTLS options')
|
||||
grp.add_option('--disable-mbedtls', action='store_false', dest='MBEDTLS', default=True,
|
||||
help='disable bundled mbedTLS and built-in HTTPS support [default: enabled]')
|
||||
|
||||
def configure(conf):
|
||||
conf.env.MBEDTLS = conf.options.MBEDTLS
|
||||
if not conf.env.MBEDTLS:
|
||||
return
|
||||
|
||||
if not conf.path.find_dir('mbedtls') or not conf.path.find_dir('mbedtls/library'):
|
||||
conf.fatal('Can\'t find mbedtls submodule. Run `git submodule update --init --recursive`.')
|
||||
|
||||
if not conf.path.find_dir('mbedtls/tf-psa-crypto/core'):
|
||||
conf.fatal('mbedTLS nested submodule tf-psa-crypto is missing. Run `git submodule update --init --recursive`.')
|
||||
|
||||
def build(bld):
|
||||
if not bld.env.MBEDTLS:
|
||||
return
|
||||
|
||||
sources = bld.path.ant_glob([
|
||||
'mbedtls/library/*.c',
|
||||
'mbedtls/tf-psa-crypto/core/*.c',
|
||||
'mbedtls/tf-psa-crypto/extras/*.c',
|
||||
'mbedtls/tf-psa-crypto/platform/*.c',
|
||||
'mbedtls/tf-psa-crypto/utilities/*.c',
|
||||
'mbedtls/tf-psa-crypto/drivers/builtin/src/*.c',
|
||||
])
|
||||
|
||||
sources += ['compat.c']
|
||||
|
||||
defines = [
|
||||
'MBEDTLS_USER_CONFIG_FILE="xash_mbedtls_config.h"',
|
||||
'TF_PSA_CRYPTO_USER_CONFIG_FILE="xash_psa_config.h"',
|
||||
]
|
||||
|
||||
includes = [
|
||||
'.',
|
||||
'mbedtls/include',
|
||||
'mbedtls/library',
|
||||
'mbedtls/tf-psa-crypto/include',
|
||||
'mbedtls/tf-psa-crypto/drivers/builtin/include',
|
||||
'mbedtls/tf-psa-crypto/core',
|
||||
'mbedtls/tf-psa-crypto/drivers/builtin/src',
|
||||
'mbedtls/tf-psa-crypto/utilities',
|
||||
'mbedtls/tf-psa-crypto/extras',
|
||||
'mbedtls/tf-psa-crypto/platform',
|
||||
'mbedtls/tf-psa-crypto/dispatch',
|
||||
]
|
||||
|
||||
bld.stlib(
|
||||
source = sources,
|
||||
target = 'mbedtls',
|
||||
features = 'c',
|
||||
includes = includes,
|
||||
defines = defines,
|
||||
export_defines = ['XASH_MBEDTLS'],
|
||||
export_includes = [
|
||||
'.',
|
||||
'mbedtls/include',
|
||||
'mbedtls/tf-psa-crypto/include',
|
||||
'mbedtls/tf-psa-crypto/drivers/builtin/include',
|
||||
]
|
||||
)
|
||||
36
3rdparty/mbedtls/xash_mbedtls_config.h
vendored
@@ -1,36 +0,0 @@
|
||||
#ifndef XASH_MBEDTLS_CONFIG_H
|
||||
#define XASH_MBEDTLS_CONFIG_H
|
||||
|
||||
#undef MBEDTLS_NET_C
|
||||
#undef MBEDTLS_PKCS7_C
|
||||
#undef MBEDTLS_TIMING_C
|
||||
#undef MBEDTLS_SSL_SRV_C
|
||||
#undef MBEDTLS_SSL_PROTO_DTLS
|
||||
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
|
||||
#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
#undef MBEDTLS_SSL_DTLS_SRTP
|
||||
#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
|
||||
#undef MBEDTLS_SSL_COOKIE_C
|
||||
#undef MBEDTLS_SSL_CACHE_C
|
||||
#undef MBEDTLS_SSL_TICKET_C
|
||||
#undef MBEDTLS_SSL_SESSION_TICKETS
|
||||
#undef MBEDTLS_SSL_RENEGOTIATION
|
||||
#undef MBEDTLS_SSL_CONTEXT_SERIALIZATION
|
||||
#undef MBEDTLS_SSL_KEYING_MATERIAL_EXPORT
|
||||
#undef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||
#undef MBEDTLS_SSL_ALL_ALERT_MESSAGES
|
||||
#undef MBEDTLS_SSL_ALPN
|
||||
#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC
|
||||
#undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
|
||||
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
|
||||
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
|
||||
#undef MBEDTLS_X509_CREATE_C
|
||||
#undef MBEDTLS_X509_CRT_WRITE_C
|
||||
#undef MBEDTLS_X509_CSR_PARSE_C
|
||||
#undef MBEDTLS_X509_CSR_WRITE_C
|
||||
#undef MBEDTLS_X509_CRL_PARSE_C
|
||||
#undef MBEDTLS_VERSION_FEATURES
|
||||
|
||||
#endif /* XASH_MBEDTLS_CONFIG_H */
|
||||
82
3rdparty/mbedtls/xash_psa_config.h
vendored
@@ -1,82 +0,0 @@
|
||||
#ifndef XASH_PSA_CONFIG_H
|
||||
#define XASH_PSA_CONFIG_H
|
||||
|
||||
#if (defined( _WIN32 ) && !defined( _WIN64 )) || defined( __vita__ ) || defined( __SWITCH__ )
|
||||
/* WinXP, PSVita and NSwitch use entropy paths upstream doesn't cover.
|
||||
compat.c provides mbedtls_platform_get_entropy() for all three. */
|
||||
#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY
|
||||
#define MBEDTLS_PSA_DRIVER_GET_ENTROPY
|
||||
#endif
|
||||
|
||||
#if defined( __vita__ ) || defined( __SWITCH__ )
|
||||
/* Upstream has no Vita/NSW support; compat.c fills in */
|
||||
#define MBEDTLS_PLATFORM_MS_TIME_ALT
|
||||
#endif
|
||||
|
||||
#undef MBEDTLS_FS_IO
|
||||
#undef MBEDTLS_PSA_ITS_FILE_C
|
||||
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
#undef MBEDTLS_SELF_TEST
|
||||
#undef MBEDTLS_HMAC_DRBG_C
|
||||
#undef MBEDTLS_LMS_C
|
||||
#undef MBEDTLS_NIST_KW_C
|
||||
#undef MBEDTLS_PKCS5_C
|
||||
|
||||
#undef PSA_WANT_ALG_CCM
|
||||
#undef PSA_WANT_ALG_CCM_STAR_NO_TAG
|
||||
#undef PSA_WANT_ALG_CBC_NO_PADDING
|
||||
#undef PSA_WANT_ALG_CBC_PKCS7
|
||||
#undef PSA_WANT_ALG_CFB
|
||||
#undef PSA_WANT_ALG_CMAC
|
||||
#undef PSA_WANT_ALG_CTR
|
||||
#undef PSA_WANT_ALG_ECB_NO_PADDING
|
||||
#undef PSA_WANT_ALG_OFB
|
||||
#undef PSA_WANT_ALG_STREAM_CIPHER
|
||||
#undef PSA_WANT_ALG_JPAKE
|
||||
#undef PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
|
||||
#undef PSA_WANT_ALG_TLS12_PSK_TO_MS
|
||||
#undef PSA_WANT_ALG_FFDH
|
||||
#undef PSA_WANT_ALG_PBKDF2_HMAC
|
||||
#undef PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128
|
||||
#undef PSA_WANT_KEY_TYPE_PASSWORD
|
||||
#undef PSA_WANT_KEY_TYPE_PASSWORD_HASH
|
||||
#undef PSA_WANT_ALG_SHA3_224
|
||||
#undef PSA_WANT_ALG_SHA3_256
|
||||
#undef PSA_WANT_ALG_SHA3_384
|
||||
#undef PSA_WANT_ALG_SHA3_512
|
||||
#undef PSA_WANT_ALG_SHAKE128
|
||||
#undef PSA_WANT_ALG_SHAKE256
|
||||
#undef PSA_WANT_ALG_SHA_224
|
||||
#undef PSA_WANT_ALG_SHA_1
|
||||
#undef PSA_WANT_ALG_MD5
|
||||
#undef PSA_WANT_ALG_RIPEMD160
|
||||
#undef PSA_WANT_KEY_TYPE_ARIA
|
||||
#undef PSA_WANT_KEY_TYPE_CAMELLIA
|
||||
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_256
|
||||
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_384
|
||||
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_512
|
||||
#undef PSA_WANT_ECC_SECP_K1_256
|
||||
#undef PSA_WANT_ECC_MONTGOMERY_448
|
||||
#undef PSA_WANT_ECC_SECP_R1_521
|
||||
#undef PSA_WANT_DH_RFC7919_2048
|
||||
#undef PSA_WANT_DH_RFC7919_3072
|
||||
#undef PSA_WANT_DH_RFC7919_4096
|
||||
#undef PSA_WANT_DH_RFC7919_6144
|
||||
#undef PSA_WANT_DH_RFC7919_8192
|
||||
#undef PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC
|
||||
#undef PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT
|
||||
#undef PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE
|
||||
#undef PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT
|
||||
#undef PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY
|
||||
#undef PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT
|
||||
#undef PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT
|
||||
#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT
|
||||
#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE
|
||||
#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
|
||||
#undef MBEDTLS_PEM_WRITE_C
|
||||
#undef MBEDTLS_PK_WRITE_C
|
||||
#undef MBEDTLS_PK_PARSE_EC_COMPRESSED
|
||||
#undef MBEDTLS_PK_PARSE_EC_EXTENDED
|
||||
#undef MBEDTLS_ASN1_WRITE_C
|
||||
|
||||
#endif /* XASH_PSA_CONFIG_H */
|
||||
2
3rdparty/nanogl
vendored
2
3rdparty/opus/opus
vendored
106
3rdparty/opus/wscript
vendored
@@ -3,37 +3,6 @@
|
||||
|
||||
import os
|
||||
|
||||
FRAGMENT_VLA='''int main (int argc, char **argv) {
|
||||
char a[argc];
|
||||
a[sizeof( a ) - 1] = 0;
|
||||
int N;
|
||||
return a[0];
|
||||
}'''
|
||||
|
||||
FRAGMENT_ALLOCA_H='''#include <alloca.h>
|
||||
int main (void) {
|
||||
int foo=10;
|
||||
int * array = alloca(foo);
|
||||
}'''
|
||||
|
||||
FRAGMENT_STDLIB_H='''#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
int main (void) {
|
||||
int foo=10;
|
||||
int * array = alloca(foo);
|
||||
}'''
|
||||
|
||||
FRAGMENT_LRINT='''#include <math.h>
|
||||
#include <stdlib.h>
|
||||
int main (int argc, char **argv) {
|
||||
return lrint%s((%s)atof(argv[1]));
|
||||
}'''
|
||||
|
||||
# assuming MSVC always enables NEON
|
||||
FRAGMENT_NEON='''#if !defined __ARM_NEON__ && !defined _MSC_VER
|
||||
#error
|
||||
#endif'''
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
@@ -42,61 +11,6 @@ def configure(conf):
|
||||
conf.fatal('Can\'t find opus submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
if conf.check_cc(fragment=FRAGMENT_LRINT % ('', 'double'), msg = 'Checking for C99 lrint', use = 'M', mandatory = False):
|
||||
conf.define('HAVE_LRINT', 1)
|
||||
|
||||
if conf.check_cc(fragment=FRAGMENT_LRINT % ('f', 'float'), msg = 'Checking for C99 lrintf', use = 'M', mandatory = False):
|
||||
conf.define('HAVE_LRINTF', 1)
|
||||
|
||||
# Check for C99 variable-size arrays, or alloca() as fallback
|
||||
if conf.check_cc(fragment=FRAGMENT_VLA, msg = 'Checking for C99 VLA support', mandatory = False):
|
||||
conf.define('VAR_ARRAYS', 1)
|
||||
elif conf.check_cc(fragment=FRAGMENT_ALLOCA_H, msg = 'Checking for alloca in alloca.h header', mandatory = False):
|
||||
conf.define('USE_ALLOCA', 1)
|
||||
conf.define('HAVE_ALLOCA_H', 1)
|
||||
elif conf.check_cc(fragment=FRAGMENT_STDLIB_H, msg = 'Checking for alloca.h in stdlib.h', mandatory = False):
|
||||
conf.define('USE_ALLOCA', 1)
|
||||
|
||||
if conf.env.DEST_CPU in ['thumb', 'arm']:
|
||||
if conf.check(header_name='arm_neon.h', mandatory = False):
|
||||
if conf.check(fragment=FRAGMENT_NEON, msg = 'Checking if compiler enabled NEON', mandatory = False):
|
||||
conf.env.HAVE_NEON = True
|
||||
conf.define('OPUS_ARM_MAY_HAVE_NEON_INTR', 1)
|
||||
conf.define('OPUS_ARM_PRESUME_NEON', 1)
|
||||
elif conf.env.DEST_CPU.startswith('x86'):
|
||||
if conf.check(header_name='xmmintrin.h', mandatory = False):
|
||||
if conf.env.COMPILER_CC != 'msvc':
|
||||
conf.env.CFLAGS += ['-msse']
|
||||
conf.define('OPUS_X86_MAY_HAVE_SSE', 1)
|
||||
if conf.env.DEST_SIZEOF_VOID_P > 4:
|
||||
conf.define('OPUS_X86_PRESUME_SSE', 1)
|
||||
|
||||
if conf.check(header_name='emmintrin.h', mandatory = False):
|
||||
if conf.env.COMPILER_CC != 'msvc':
|
||||
conf.env.CFLAGS += ['-msse2']
|
||||
conf.define('OPUS_X86_MAY_HAVE_SSE2', 1)
|
||||
if conf.env.DEST_SIZEOF_VOID_P > 4:
|
||||
conf.define('OPUS_X86_PRESUME_SSE2', 1)
|
||||
|
||||
# on x86_64 we enable both SSE and SSE2, so RTCD can be disabled (it's actually doesn't even build with RTCD enabled)
|
||||
if conf.env.DEST_SIZEOF_VOID_P == 4:
|
||||
if conf.check(header_name='cpuid.h', mandatory=False):
|
||||
conf.define('CPU_INFO_BY_C', 1)
|
||||
else:
|
||||
conf.define('CPU_INFO_BY_ASM', 1)
|
||||
|
||||
conf.define('OPUS_HAVE_RTCD', 1)
|
||||
|
||||
# if conf.check(header_name='smmintrin.h', mandatory = False):
|
||||
# if conf.env.COMPILER_CC != 'msvc':
|
||||
# conf.env.CFLAGS += ['-msse4.1']
|
||||
# conf.define('OPUS_X86_MAY_HAVE_SSE4_1', 1)
|
||||
|
||||
# if conf.check(header_name='immintrin.h', mandatory = False):
|
||||
# if conf.env.COMPILER_CC != 'msvc':
|
||||
# conf.env.CFLAGS += ['-mavx']
|
||||
# conf.define('OPUS_X86_MAY_HAVE_AVX', 1)
|
||||
|
||||
# TODO: ARM/x86 intrinsics detection
|
||||
# TODO: maybe call autotools/cmake/meson instead?
|
||||
|
||||
@@ -112,23 +26,8 @@ def build(bld):
|
||||
'opus/src/opus_compare.c',
|
||||
'opus/celt/opus_custom_demo.c'
|
||||
])
|
||||
|
||||
includes = ['opus', 'opus/include/', 'opus/celt/', 'opus/silk/', 'opus/silk/float/']
|
||||
|
||||
if bld.env.DEST_CPU in ['thumb', 'arm']:
|
||||
if bld.env.HAVE_NEON:
|
||||
sources += bld.path.ant_glob(['opus/silk/arm/*.c', 'opus/celt/arm/*.c'])
|
||||
includes += ['opus/silk/arm', 'opus/celt/arm']
|
||||
elif bld.env.DEST_CPU.startswith('x86'):
|
||||
sources += ['opus/silk/x86/x86_silk_map.c',
|
||||
'opus/celt/x86/pitch_sse.c',
|
||||
'opus/celt/x86/pitch_sse2.c',
|
||||
'opus/celt/x86/vq_sse2.c',
|
||||
'opus/celt/x86/x86_celt_map.c',
|
||||
'opus/celt/x86/x86cpu.c']
|
||||
includes += ['opus/silk/x86', 'opus/celt/x86']
|
||||
|
||||
defines = ['OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.4.0"', 'CUSTOM_MODES', 'ENABLE_HARDENING']
|
||||
includes = ['opus/include/', 'opus/celt/', 'opus/silk/', 'opus/silk/float/']
|
||||
defines = ['USE_ALLOCA', 'OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.3.1"', 'CUSTOM_MODES']
|
||||
|
||||
bld.stlib(
|
||||
source = sources,
|
||||
@@ -136,5 +35,6 @@ def build(bld):
|
||||
features = 'c',
|
||||
includes = includes,
|
||||
defines = defines,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
export_includes = ['opus/include/']
|
||||
)
|
||||
|
||||
1
3rdparty/opusfile/opusfile
vendored
37
3rdparty/opusfile/wscript
vendored
@@ -1,37 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
if not conf.path.find_dir('opusfile') or not conf.path.find_dir('opusfile/src'):
|
||||
conf.fatal('Can\'t find opusfile submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
if conf.env.COMPILER_CC == 'msvc':
|
||||
conf.define('_CRT_SECURE_NO_WARNINGS', 1)
|
||||
conf.define('_CRT_SECURE_NO_DEPRECATE', 1)
|
||||
conf.define('_CRT_NONSTDC_NO_DEPRECATE', 1)
|
||||
|
||||
if conf.env.DEST_OS == 'android':
|
||||
# HACKHACK: set it to 32 here because opusfile can't be built on Android SDK < 24
|
||||
# with _FILE_OFFSET_BITS 64 (which it sets automatically in src/internal.h)
|
||||
# we are not (????) relying on this part of the API, so it should be harmless
|
||||
conf.define('_FILE_OFFSET_BITS', 32)
|
||||
|
||||
def build(bld):
|
||||
sources = [
|
||||
'opusfile/src/info.c',
|
||||
'opusfile/src/internal.c',
|
||||
'opusfile/src/opusfile.c',
|
||||
'opusfile/src/stream.c'
|
||||
]
|
||||
|
||||
bld.stlib(
|
||||
source = sources,
|
||||
target = 'opusfile',
|
||||
includes = 'opusfile/include/',
|
||||
use = 'ogg opus',
|
||||
export_includes = 'opusfile/include/'
|
||||
)
|
||||
2
3rdparty/vgui_support
vendored
1
3rdparty/vorbis/vorbis-src
vendored
71
3rdparty/vorbis/wscript
vendored
@@ -1,71 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
FRAGMENT_MEMORY_H='''#include <memory.h>
|
||||
int main (void) {
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_ALLOCA_H='''#include <alloca.h>
|
||||
int main (void) {
|
||||
int foo=10;
|
||||
int * array = alloca(foo);
|
||||
}'''
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
if not conf.path.find_dir('vorbis-src') or not conf.path.find_dir('vorbis-src/lib'):
|
||||
conf.fatal('Can\'t find Vorbis submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
if conf.check_cc(fragment=FRAGMENT_MEMORY_H, msg = 'Checking for memory.h header', mandatory = False):
|
||||
conf.define('USE_MEMORY_H', 1)
|
||||
|
||||
conf.check_cc(fragment=FRAGMENT_ALLOCA_H, msg = 'Checking for alloca in alloca.h header', mandatory = False)
|
||||
|
||||
if conf.env.COMPILER_CC == 'msvc':
|
||||
conf.define('_CRT_SECURE_NO_WARNINGS', 1)
|
||||
conf.define('_CRT_SECURE_NO_DEPRECATE', 1)
|
||||
conf.define('_CRT_NONSTDC_NO_DEPRECATE', 1)
|
||||
|
||||
def build(bld):
|
||||
libvorbis_sources = [
|
||||
'vorbis-src/lib/mdct.c',
|
||||
'vorbis-src/lib/smallft.c',
|
||||
'vorbis-src/lib/block.c',
|
||||
'vorbis-src/lib/envelope.c',
|
||||
'vorbis-src/lib/window.c',
|
||||
'vorbis-src/lib/lsp.c',
|
||||
'vorbis-src/lib/lpc.c',
|
||||
'vorbis-src/lib/analysis.c',
|
||||
'vorbis-src/lib/synthesis.c',
|
||||
'vorbis-src/lib/psy.c',
|
||||
'vorbis-src/lib/info.c',
|
||||
'vorbis-src/lib/floor1.c',
|
||||
'vorbis-src/lib/floor0.c',
|
||||
'vorbis-src/lib/res0.c',
|
||||
'vorbis-src/lib/mapping0.c',
|
||||
'vorbis-src/lib/registry.c',
|
||||
'vorbis-src/lib/codebook.c',
|
||||
'vorbis-src/lib/sharedbook.c',
|
||||
'vorbis-src/lib/lookup.c',
|
||||
'vorbis-src/lib/bitrate.c'
|
||||
]
|
||||
|
||||
bld.stlib(
|
||||
source = libvorbis_sources,
|
||||
target = 'vorbis',
|
||||
includes = 'vorbis-src/include/',
|
||||
use = 'ogg',
|
||||
export_includes = 'vorbis-src/include/'
|
||||
)
|
||||
|
||||
bld.stlib(
|
||||
source = 'vorbis-src/lib/vorbisfile.c',
|
||||
target = 'vorbisfile',
|
||||
includes = 'vorbis-src/include/',
|
||||
use = 'vorbis',
|
||||
export_includes = 'vorbis-src/include/'
|
||||
)
|
||||
59
3rdparty/yy-thunks/wscript
vendored
@@ -1,59 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
import hashlib
|
||||
from waflib import Task, TaskGen, Logs
|
||||
|
||||
OBJ_NAME = 'YY_Thunks_for_WinXP.obj'
|
||||
OBJ_SHA256 = '51a13c4b667c82181d357e274a50308a273be63f5f85ae958465774857721573'
|
||||
DLL_LINKFLAGS = ['-ENTRY:DllMainCRTStartupForYY_Thunks', '-alternatename:_YY_ThunksOriginalDllMainCRTStartup@12=__DllMainCRTStartup@12']
|
||||
|
||||
class copy_yy_thunks(Task.Task):
|
||||
color = 'CYAN'
|
||||
def run(self):
|
||||
return self.outputs[0].write(self.inputs[0].read('rb'), 'wb')
|
||||
|
||||
@TaskGen.feature('yy_thunks')
|
||||
def add_yy_thunks_obj(self):
|
||||
src = self.path.find_node(OBJ_NAME)
|
||||
out = self.path.find_or_declare(OBJ_NAME)
|
||||
self.compiled_tasks = [self.create_task('copy_yy_thunks', src, out)]
|
||||
|
||||
@TaskGen.feature('cshlib', 'cxxshlib')
|
||||
@TaskGen.after_method('process_use')
|
||||
def apply_yy_thunks_dll(self):
|
||||
if 'yy_thunks' not in self.to_list(getattr(self, 'use', [])):
|
||||
return
|
||||
|
||||
try:
|
||||
self.bld.get_tgen_by_name('yy_thunks')
|
||||
except Exception:
|
||||
return
|
||||
self.env.append_value('LINKFLAGS', DLL_LINKFLAGS)
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
if conf.env.DEST_OS != 'win32' or conf.env.COMPILER_CC != 'msvc':
|
||||
return
|
||||
|
||||
if conf.env.MSVC_TARGETS[0] not in ['amd64_x86', 'x86']:
|
||||
return
|
||||
|
||||
obj = conf.path.find_node(OBJ_NAME)
|
||||
if not obj:
|
||||
Logs.warn('YY-Thunks: %s not found, XP compatibility disabled' % OBJ_NAME)
|
||||
return
|
||||
|
||||
with open(obj.abspath(), 'rb') as f:
|
||||
digest = hashlib.sha256(f.read()).hexdigest()
|
||||
|
||||
if digest != OBJ_SHA256:
|
||||
conf.fatal('%s checksum mismatch: expected %s, got %s' % (OBJ_NAME, OBJ_SHA256, digest))
|
||||
|
||||
conf.env.YY_THUNKS = True
|
||||
|
||||
def build(bld):
|
||||
if bld.env.YY_THUNKS:
|
||||
bld(name='yy_thunks', features='yy_thunks')
|
||||
@@ -29,11 +29,10 @@
|
||||
|
||||
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
||||
* In short:
|
||||
* Use spaces in parenthesis, but not when two parentheses are consecutive.
|
||||
* Use spaces in parenthesis.
|
||||
* Only tabs for indentation.
|
||||
* Any brace must have it's own line.
|
||||
* Short blocks, if statements and loops on single line are allowed.
|
||||
* Prefer generic utilities from libpublic over rolling your own.
|
||||
* Avoid magic numbers.
|
||||
* While macros are powerful, it's better to avoid overusing them.
|
||||
* If you unsure, try to mimic code style from anywhere else of engine source code.
|
||||
@@ -46,8 +45,3 @@
|
||||
Tags can be any: subsystem, simple feature name or even just a filename, without extension.
|
||||
Just keep them always same, it helps keep history clean and commit messages short.
|
||||
|
||||
## LLM-based tools usage.
|
||||
|
||||
While we wouldn't recommend using any LLM-based (also misleadingly called AI) tools, we understand that they are here to stay.
|
||||
|
||||
Whether you're reporting bug or contributing the code, you take complete authorship and responsibility over provided content and the same rules will apply to you as for everybody else, so validate the bug report or the patch before sending it.
|
||||
|
||||
@@ -13,6 +13,5 @@ When `-bugcomp` is specified with argument, it interpreted as flags separated wi
|
||||
| Flag | Description | Games that require this flag |
|
||||
| ------- | ----------- | ---------------------------- |
|
||||
| `peoei` | Reverts `pfnPEntityOfEntIndex` behavior to GoldSrc, where it returns NULL for last player due to incorrect player index comparison | * Counter-Strike: Condition Zero - Deleted Scenes |
|
||||
| `gsmrf` | Rewrites message at the moment when Game DLL attempts to write an internal engine message, usually specific to GoldSrc protocol.<br>Right now only supports `svc_spawnstaticsound`, more messages added by request. | * MetaMod/AMXModX based mods |
|
||||
| `gsmrf` | Rewrites message at the moment when Game DLL attempts to write an internal engine message, usually specific to GoldSrc protocol. Right now only supports `svc_spawnstaticsound`, more messages added by request. | * MetaMod/AMXModX based mods |
|
||||
| `sp_attn_none` | Makes sounds with attenuation zero spatialized, i.e. have a stereo effect. | Possibly, every game that was made for GoldSrc. |
|
||||
| `get_game_dir_full` | Makes server return full path in server's `pfnGetGameDir` API function | Mods targetting engine before HL 1.1.1.1, according to MetaMod [documentation](http://metamod.org/engine_notes.html#GetGameDir) |
|
||||
|
||||
@@ -5,10 +5,5 @@ This can be useful to test engine in Wine without using virtual machines or dual
|
||||
0. Clone and install https://github.com/mstorsjo/msvc-wine (you can skip CMake part)
|
||||
1. Set environment variable MSVC_WINE_PATH to the path to installed MSVC toolchain
|
||||
2. Pre-load wine: `wineserver -k; wineserver -p; wine64 wineboot`
|
||||
3. Run `PKGCONFIG=/bin/false ./waf configure -T <build-type> --enable-wine-msvc --sdl2=../SDL2_VC`. Configuration step will take more time than usual.
|
||||
3. Run `./waf configure -T <build-type> --enable-wine-msvc --sdl2=../SDL2_VC`. Configuration step will take more time than usual.
|
||||
4. .. other typical steps to build from console ...
|
||||
|
||||
> [!NOTE]
|
||||
> Notice the usage of PKGCONFIG=/bin/false here. We're disabling pkg-config so we don't accidentally pull
|
||||
> system-wide dependencies and force building them from source. In future builds we might set custom
|
||||
> directory to pull dependencies from, like ffmpeg...
|
||||
@@ -1,103 +0,0 @@
|
||||
## Setting up Xash3D FWGS in Qt Creator
|
||||
|
||||
### Intro
|
||||
|
||||
Most versions of Qt Creator support using `compile_commands.json` as a project
|
||||
file and Waf supports generating this file in a compliant format. In this
|
||||
tutorial we will leverage that features.
|
||||
|
||||
The tutorial is written using Qt Creator 18.0, but I urge you to use whatever
|
||||
latest Qt Creator version is available, as it's often has important bug fixes.
|
||||
|
||||
### Step 1. Configure the build.
|
||||
|
||||
`compile_commands.json` file, as it can be guessed from it's name, contains
|
||||
every command used to invoke compiler during build. As the build process
|
||||
depends on the build configuration, we have to configure it first. I'm not
|
||||
going to get into details here, as basics of compiling Xash3D FWGS already
|
||||
explained in `README.md`, located in repository root.
|
||||
|
||||
Save the configure step command somewhere, as it's going to be used later.
|
||||
|
||||
### Step 2. Generate `compile_commands.json` file.
|
||||
|
||||
Usually, this file is located in `build` directory after a successful build.
|
||||
However, it's also possible to generate it manually by running follow command:
|
||||
|
||||
On *nix systems:
|
||||
|
||||
```
|
||||
$ ./waf clangdb
|
||||
```
|
||||
|
||||
Or on Windows:
|
||||
|
||||
```
|
||||
> waf.bat clangdb
|
||||
```
|
||||
|
||||
### Step 3. Load the project in Qt Creator.
|
||||
|
||||
To do this, you need to be sure that `Compilation Databases` plugin is enabled.
|
||||
As it's considered experimental, it probably needs to be enabled manually. It
|
||||
can be done in `Help` -> `About Plugins...`. Locate it in `Build Systems`
|
||||
category, put the checkbox and press `OK`. The IDE will ask for restart, so do
|
||||
this.
|
||||
|
||||
After IDE has been restarted, you can use `File` -> `Open File or Project...`.
|
||||
Navigate to Xash3D FWGS directory, then to `build` directory and select
|
||||
`compile_commands.json` file. If everything is done correctly, IDE will ask to
|
||||
set up the project. Press `Configure Project` button, as most options there are
|
||||
usually unapplicable to us.
|
||||
|
||||
Next IDE will show project tree, however you might not see any files. This is
|
||||
happens as Qt Creator "thinks" our project root located in `build` directory.
|
||||
Thankfully it provides a way to override this. To fix it, click with right
|
||||
mouse button on the root of project tree (it's usually called something like
|
||||
`build [master]`) and select `Change Root Directory`. In opened window choose
|
||||
Xash3D FWGS repository root and press `OK`.
|
||||
|
||||
### Step 4. Tell IDE how to build this project.
|
||||
|
||||
Open `Projects` on the left menu and choose `Build Settings` tab. You should
|
||||
see an empty configuration for build and clean steps. Press on `Add Build Step`
|
||||
button and choose `Custom Process Step`.
|
||||
|
||||
In created step you should see `Command`, `Arguments` and `Working Directory`.
|
||||
|
||||
For the command, choose the Python executable. For arguments, use configure
|
||||
command for Waf from the first step. Working directory is usually set by IDE
|
||||
to `%{buildDir}`. You need to select the upper directory, where the `waf` is
|
||||
located. To save some time, it can be specified as `%{buildDir}/../`.
|
||||
|
||||
Add another custom step, fill it with the same command and working directory.
|
||||
For arguments use `waf build`.
|
||||
|
||||
Below you should see `Clean steps`. Create a clean step the same way, fill the
|
||||
arguments and working directory as usual, for arguments use `waf clean`.
|
||||
|
||||
### Step 5. Tell IDE how to copy built binaries.
|
||||
|
||||
Now select `Deploy Settings` tab. Press `Add Deploy Step` -> `Custom Process
|
||||
Step`. Again, same command and working directory. In arguments field type:
|
||||
`waf install --destdir="<here put where Xash binaries should be copied to>"`.
|
||||
|
||||
### Step 6. Finally, set up Qt Creator to run the engine.
|
||||
|
||||
Select the `Run Settings` tab. Below you might see familiar text fields:
|
||||
`Executable`, `Command line arguments` and `Working directory`.
|
||||
|
||||
For working directory click on `Browse...` button and select the folder where
|
||||
Xash3D executable will be copied to, from previous step.
|
||||
|
||||
For executable type `./xash3d` if you're on *nix or `xash3d.exe` if you're on
|
||||
Windows. The command line arguments are the same you use to run the engine. Can
|
||||
be empty as well, but I personally use `-dev 2 -log` for extra verbosity.
|
||||
|
||||
### Outro
|
||||
|
||||
At this moment, you should be able to press `Run` button, wait until build
|
||||
finishes and see running Xash3D FWGS. On Windows to use the debugger you might
|
||||
need the `CDB` debugger and appropriate `qtcreatorcdbext` binary for debugging
|
||||
32-bit applications and a separate for 64-bit, but that's left as an exercise
|
||||
for the reader and a potential improvement for this document.
|
||||
@@ -2,34 +2,23 @@
|
||||
|
||||
On this page you can find links where you can support each developer individually, who has provided public sponsorship information.
|
||||
|
||||
## [a1batross](https://github.com/a1batross)
|
||||
### [a1batross](https://github.com/a1batross)
|
||||
|
||||
Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
|
||||
* Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
|
||||
* Boosty page: https://boosty.to/a1ba
|
||||
|
||||
* [Boosty page](https://boosty.to/a1ba)
|
||||
### [nekonomicon](https://github.com/nekonomicon)
|
||||
|
||||
## [nekonomicon](https://github.com/nekonomicon)
|
||||
* [hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
|
||||
* Boosty page: https://boosty.to/nekonomicon
|
||||
|
||||
[hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
|
||||
### [Velaron](https://github.com/Velaron)
|
||||
* [cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
|
||||
* BuyMeACoffee page: https://www.buymeacoffee.com/velaron
|
||||
|
||||
* [Boosty page](https://boosty.to/nekonomicon)
|
||||
|
||||
## [Velaron](https://github.com/Velaron)
|
||||
|
||||
[cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
|
||||
|
||||
* [Boosty page](https://boosty.to/velaron)
|
||||
|
||||
## [SNMetamorph](https://github.com/SNMetamorph)
|
||||
|
||||
[PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
|
||||
|
||||
* [Boosty page](https://boosty.to/snmetamorph)
|
||||
* [Other donation methods](https://snmetamorph.github.io/donate)
|
||||
|
||||
## [$_Vladislav](https://github.com/Vladislav4KZ)
|
||||
|
||||
[YaPB Project](https://github.com/yapb) member and [contributor](https://github.com/yapb/yapb/commits?author=Vladislav4KZ) ([Docs](https://github.com/yapb/docs), [Nav Graphs](https://github.com/yapb/graph), [RU translation](https://github.com/yapb/yapb/blob/master/cfg/addons/yapb/conf/lang/ru_lang.cfg)), Xash3D FWGS [tester](https://github.com/FWGS/xash3d-fwgs/issues?q=is%3Aissue%20state%3Aopen%20author%3AVladislav4KZ) and [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Vladislav4KZ) (gyro-aim support, scr-parser, etc.), [CS16Client](https://github.com/Velaron/cs16-client) [contributor](https://github.com/Velaron/cs16-client/commits?author=Vladislav4KZ).
|
||||
|
||||
* [Boosty page](https://boosty.to/rasstaman1337)
|
||||
* [PayPal link](https://paypal.me/rasstaman1337)
|
||||
### [SNMetamorph](https://github.com/SNMetamorph)
|
||||
* [PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
|
||||
* BTC: `16GAzK3qei5AwBW7sggXp3yNcFHBtdpxXj`
|
||||
* ETH (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* USDT (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* USDC (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
|
||||
@@ -22,7 +22,7 @@ The other yet unsupported configuration is the big endian.
|
||||
|
||||
2) Open `public/build.h` file. Add appropriate checks for your operating system and/or CPU architecture. It shouldn't be hard.
|
||||
|
||||
Also, you'll need to build [Half-Life SDK](https://github.com/FWGS/hlsdk-portable/). It has same `public/build.h` so reflect changes into it. Note that to be compatible with HLSDK proprietary license, it's relicensed as public domain under [Unlicense](https://unlicense.org).
|
||||
Also, you'll need to build [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d/). It has same `public/build.h` so reflect changes into it. Note that to be compatible with HLSDK proprietary license, it's relicensed as public domain under [Unlicense](https://unlicense.org).
|
||||
|
||||
We have a library naming scheme that allows us and game creators to distribute binaries for different platforms in one archive. Read `Documentation/extensions/library-naming.md` for more information.
|
||||
|
||||
150
Documentation/entity-tools.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# There are few new commands availiable in xash3d fork:
|
||||
|
||||
## Commands:
|
||||
### ent_create
|
||||
Create entity with specified classname and key/values
|
||||
|
||||
`ent_create <classname> <key> <value> <key> <value> ...`
|
||||
|
||||
for example:
|
||||
|
||||
`ent_create monster_zombie targetname zomb1`
|
||||
|
||||
after creating entity, ent_last_xxx cvars are set to new entity and ent_last_cb called, look at ent_getvars description
|
||||
|
||||
### ent_fire
|
||||
|
||||
Make some actions on entity
|
||||
|
||||
`ent_fire <pattern> <command> <args>`
|
||||
Availiavle commands:
|
||||
* Set fields (Only set entity field, does not call any functions):
|
||||
* health
|
||||
* gravity
|
||||
* movetype
|
||||
* solid
|
||||
* rendermode
|
||||
* rendercolor (vector)
|
||||
* renderfx
|
||||
* renderamt
|
||||
* hullmin (vector)
|
||||
* hullmax (vector)
|
||||
* Actions
|
||||
* rename: set entity targetname
|
||||
* settarget: set entity target (only targetnames)
|
||||
* setmodel: set entity model (does not update)
|
||||
* set: set key/value by server library
|
||||
* See game FGD to get list.
|
||||
* command takes two arguments
|
||||
* touch: touch entity by current player.
|
||||
* use: use entity by current player.
|
||||
* movehere: place entity in player fov.
|
||||
* drop2floor: place entity to nearest floor surface
|
||||
* moveup: move entity to 25 units up
|
||||
* moveup (value): move by y axis relatively to specified value
|
||||
* Flags (Set/clear specified flag bit, arg is bit number):
|
||||
* setflag
|
||||
* clearflag
|
||||
* setspawnflag
|
||||
* clearspawnflag
|
||||
|
||||
### ent_info
|
||||
Print information about entity by identificator
|
||||
|
||||
`ent_info <identificator>`
|
||||
|
||||
### ent_getvars
|
||||
Set client cvars containing entity information (useful for [[Scripting]]) and call ent_last_cb
|
||||
|
||||
`ent_getvars <identificator>`
|
||||
|
||||
These cvars are set:
|
||||
```
|
||||
ent_last_name
|
||||
ent_last_num
|
||||
ent_last_inst
|
||||
ent_last_origin
|
||||
ent_last_class
|
||||
```
|
||||
|
||||
### ent_list
|
||||
Print short information about antities, filtered by pattern
|
||||
|
||||
`ent_list <pattern>`
|
||||
|
||||
## Syntax description
|
||||
|
||||
### \<identificator\>
|
||||
|
||||
* !cross: entity under aim
|
||||
* Instance code: !\<number\>_\<seria\l>
|
||||
* set by ent_getvars command
|
||||
* Entity index
|
||||
* targetname pattern
|
||||
|
||||
### \<pattern\>
|
||||
|
||||
Pattern is like identificator, but may filter many entities by classname
|
||||
|
||||
### (vector)
|
||||
|
||||
used by ent_fire command. vector means three float values, entered without quotes
|
||||
|
||||
### key/value
|
||||
|
||||
All entities parameters may be set by specifiing key and value strings.
|
||||
|
||||
Originally, this mechanizm is used in map/bsp format, but it can be used in enttools too.
|
||||
|
||||
Keys and values are passed to server library and processed by entity keyvalue function, setting edict and entity owns parameters.
|
||||
|
||||
If value contains spaces, it must be put in quotes:
|
||||
|
||||
`ent_fire !cross set origin "0 0 0"`
|
||||
|
||||
## Using with scripting
|
||||
|
||||
ent_create and ent_getvars commands are setting cvars on client
|
||||
|
||||
It can be used with ent_last_cb alias that is executed after setting cvars.
|
||||
|
||||
Simple example:
|
||||
|
||||
```
|
||||
ent_create weapon_c4
|
||||
alias ent_last_cb "ent_fire \$ent_last_inst use"
|
||||
```
|
||||
|
||||
Use weapon_c4 after creating it.
|
||||
|
||||
Note that you cannot use many dfferent callbacks at the same time.
|
||||
|
||||
You can set entity name by by pattern and create special script, contatning all callbacks.
|
||||
|
||||
Example:
|
||||
|
||||
example.cfg
|
||||
```
|
||||
alias ent_last_cb exec entity_cb.cfg
|
||||
ent create \<class\> targetname my_ent1_$name
|
||||
ent_create \<class\> targetname my_ent2_$name
|
||||
```
|
||||
entity_cb.cfg
|
||||
```
|
||||
if $ent_last_name == my_ent1_$name
|
||||
:(ent1 actions)
|
||||
if $ent_last_name == my_ent2_$name
|
||||
:(ent2 actions)
|
||||
```
|
||||
Note that scripting cannot be blocking. You cannot wait for server answer and continue. But you can use small scripts, connected with ent_last_cb command. The best usage is user interaction. You can add touch buttons to screen or call user command menu actions by callbacks.
|
||||
## Server side
|
||||
|
||||
To enable entity tools on server, set sv_enttools_enable to 1
|
||||
|
||||
To change maximum number of entities, touched by ent_fire, change sv_enttools_maxfire to required number.
|
||||
|
||||
To enable actions on players, set sv_enttools_players to 1.
|
||||
|
||||
To enable entity tools for player by nickname, set sv_enttools_godplayer to nickname. Useful to temporary enable from rcon.
|
||||
|
||||
To prevent crash on some actions, set host_mapdesign_fatal to 0
|
||||
@@ -1,16 +0,0 @@
|
||||
# Addon folders in Xash3D FWGS
|
||||
|
||||
Xash3D FWGS supports both GoldSource-style addon folders and has few own. Each directory can have it's own archives that will be mounted with lower priority than directory itself.
|
||||
|
||||
Below is the mounts map, in order of precedence from least important to most important.
|
||||
|
||||
|--------------------|------|
|
||||
| Directory | Note |
|
||||
|--------------------|------|
|
||||
| `$game/downloaded` | Always added. Used to store server downloads.|
|
||||
| `$game` | This is the game directory. |
|
||||
| `$game/custom` | Always added. Used for user modifications content. |
|
||||
| `$game_hd` | Added with `fs_mount_hd` set to non-zero value. Used for high definition content, similar to GoldSrc.. |
|
||||
| `$game_addon` | Added with `fs_mount_addon` set to non-zero value. Used for user modifications content, similar to GoldSrc. |
|
||||
| `$game_lv` | Added with `fs_mount_lv` set to non-zero value. Used for low-violence content, similar to GoldSrc. |
|
||||
| `$game_$language` | Added with `fs_mount_l10n` set to non-zero value. Language is controlled with `ui_language` cvar or `-language` command line switch. Used for localization content, similar to GoldSrc. |
|
||||
@@ -1,152 +0,0 @@
|
||||
# Entity tools
|
||||
|
||||
For some features described below, you need to enable [console scripting](https://github.com/FWGS/xash3d-fwgs/blob/master/Documentation/extensions/console-scripting.md) with command `cmd_scripting 1` in console.
|
||||
To get more information about it, check another according page related to console scripting.
|
||||
|
||||
## Commands description
|
||||
|
||||
### ent_create
|
||||
Create entity with specified classname and key/values.
|
||||
|
||||
`ent_create <classname> <key> <value> <key> <value> ...`
|
||||
|
||||
For example:
|
||||
|
||||
`ent_create monster_zombie targetname zomb1`
|
||||
|
||||
After creating entity, ent_last_xxx cvars are set to new entity and ent_last_cb called, look at ent_getvars description.
|
||||
|
||||
### ent_fire
|
||||
|
||||
Makes some actions on entity.
|
||||
|
||||
`ent_fire <pattern> <command> <args>`
|
||||
|
||||
#### Available commands:
|
||||
|
||||
Set fields (only set entity field, does not call any functions)
|
||||
* health
|
||||
* gravity
|
||||
* movetype
|
||||
* solid
|
||||
* rendermode
|
||||
* rendercolor (vector)
|
||||
* renderfx
|
||||
* renderamt
|
||||
* hullmin (vector)
|
||||
* hullmax (vector)
|
||||
|
||||
Actions
|
||||
* rename: set entity targetname
|
||||
* settarget: set entity target (only targetnames)
|
||||
* setmodel: set entity model (does not update)
|
||||
* set: set key/value by server library
|
||||
* See game FGD to get list.
|
||||
* command takes two arguments
|
||||
* touch: touch entity by current player.
|
||||
* use: use entity by current player.
|
||||
* movehere: place entity in player fov.
|
||||
* drop2floor: place entity to nearest floor surface
|
||||
* moveup: move entity to 25 units up
|
||||
* moveup (value): move by y axis relatively to specified value
|
||||
|
||||
Flags (set/clear specified flag bit, arg is bit number):
|
||||
* setflag
|
||||
* clearflag
|
||||
* setspawnflag
|
||||
* clearspawnflag
|
||||
|
||||
### ent_info
|
||||
Print information about entity by identificator.
|
||||
|
||||
`ent_info <identificator>`
|
||||
|
||||
### ent_getvars
|
||||
Set client cvars containing entity information (useful for [scripting](extensions/console-scripting.md)) and then calls ent_last_cb.
|
||||
|
||||
`ent_getvars <identificator>`
|
||||
|
||||
These cvars are set:
|
||||
```
|
||||
ent_last_name
|
||||
ent_last_num
|
||||
ent_last_inst
|
||||
ent_last_origin
|
||||
ent_last_class
|
||||
```
|
||||
|
||||
### ent_list
|
||||
Print short information about antities, filtered by pattern.
|
||||
|
||||
`ent_list <pattern>`
|
||||
|
||||
## Syntax description
|
||||
|
||||
#### \<identificator\>
|
||||
* !cross: entity under aim
|
||||
* !\<number\>_\<serial\>: instance code
|
||||
* Set by ent_getvars command
|
||||
* Entity index
|
||||
* Targetname pattern
|
||||
|
||||
#### \<pattern\>
|
||||
|
||||
Pattern is like identificator, but may filter many entities by classname.
|
||||
|
||||
#### (vector)
|
||||
|
||||
Used by ent_fire command. vector means three float values, entered without quotes.
|
||||
|
||||
#### key/value
|
||||
|
||||
All entities parameters may be set by specifiing key and value strings.
|
||||
|
||||
Originally, this mechanizm is used in map/bsp format, but it can be used in enttools too.
|
||||
|
||||
Keys and values are passed to server library and processed by entity keyvalue function, setting edict and entity owns parameters.
|
||||
|
||||
If value contains spaces, it must be put in quotes:
|
||||
|
||||
`ent_fire !cross set origin "0 0 0"`
|
||||
|
||||
## Using with scripting
|
||||
|
||||
ent_create and ent_getvars commands are setting cvars on client
|
||||
|
||||
It can be used with ent_last_cb alias that is executed after setting cvars.
|
||||
|
||||
Simple example:
|
||||
|
||||
```
|
||||
ent_create weapon_c4
|
||||
alias ent_last_cb "ent_fire \$ent_last_inst use"
|
||||
```
|
||||
|
||||
Use weapon_c4 after creating it.
|
||||
|
||||
Note that you cannot use many different callbacks at the same time.
|
||||
|
||||
You can set entity name by by pattern and create special script, contatning all callbacks.
|
||||
|
||||
Example:
|
||||
|
||||
> example.cfg
|
||||
```
|
||||
alias ent_last_cb exec entity_cb.cfg
|
||||
ent create \<class\> targetname my_ent1_$name
|
||||
ent_create \<class\> targetname my_ent2_$name
|
||||
```
|
||||
> entity_cb.cfg
|
||||
```
|
||||
if $ent_last_name == my_ent1_$name
|
||||
:(ent1 actions)
|
||||
if $ent_last_name == my_ent2_$name
|
||||
:(ent2 actions)
|
||||
```
|
||||
Note that scripting cannot be blocking. You cannot wait for server answer and continue. But you can use small scripts, connected with ent_last_cb command. The best usage is user interaction. You can add touch buttons to screen or call user command menu actions by callbacks.
|
||||
|
||||
## Server side configuration
|
||||
|
||||
To enable entity tools on server, set sv_enttools_enable to 1
|
||||
|
||||
To change maximum number of entities, touched by ent_fire, change sv_enttools_maxfire to required number.
|
||||
@@ -42,6 +42,3 @@ Issue #3: Some mods (like The Specialists, Tyrian, ...) already apply suffixes _
|
||||
Resolution: On x86 on **Win/Lin/Mac**, don't change anything. Otherwise, strip the _i?86 part and follow the usual scheme.
|
||||
|
||||
See discussion: https://github.com/FWGS/xash3d-fwgs/issues/39
|
||||
|
||||
Issue #4: When distributing game libraries on Android inside an APK, they couldn't be loaded.
|
||||
Resolution: Enable `useLegacyPackaging` option in build.gradle, when distributing games in APK. Always force game libraries to have `lib` prefix on Android, regardless if they are packaged in APK or not..
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
## Lightmapped water
|
||||
|
||||
Xash3D FWGS supports lightmapped water, as an extension. It adds three new cvars and new worldspawn key values.
|
||||
|
||||
### For level designers:
|
||||
|
||||
If you're a level designer and intend to make your level to have lightmapped water, you can put these keyvalues to worldspawn entity description (always first entity in entities list):
|
||||
|
||||
| Key | Value | Description |
|
||||
| ---------------------- | ------- | ----------- |
|
||||
| `_litwater` | integer | Set to any non-zero value to enable lightmapped water. Overrides `gl_litwater_force` cvar value. |
|
||||
| `_litwater_minlight` | integer | Minimal lightmap value water surface will receive. Helps to avoid too dark areas when water isn't properly lit. If not set, defaults to zero. |
|
||||
| `_litwater_scale` | float | Scales up lightmap value for water surfaces. If not set, defaults to 1.0. |
|
||||
|
||||
### For players:
|
||||
|
||||
Some of the maps already have computed lightmap for water surfaces and sometimes water has been properly lit but the support hasn't been declared by the level designer.
|
||||
|
||||
As a player, you can enable it in `Video options` menu or through console with `gl_litwater_force` cvar. There are also `gl_litwater_minlight` and `gl_litwater_scale` cvars that function similar to keys above. The default values has been set to `192` and `1.25` respectively to slightly avoid issues with maps that wasn't intended to have lightmapped water.
|
||||
@@ -16,7 +16,6 @@ Only these objects are guaranteed to be available on all targets.
|
||||
|-------------|-----------|
|
||||
| `VFileSystem009` | Provides C++ interface to filesystem, binary-compatible with Valve's VFileSystem009. |
|
||||
| `XashFileSystemXXX` | Provides C interface to filesystem. This interface is unstable and not recommended for generic use, outside of engine internals. For more info about current version look into `filesystem.h`. |
|
||||
| `MenuFactory` | Returns a `CreateInterface` function pointer (`pfnCreateInterface_t`) for the currently loaded menu library. |
|
||||
|
||||
#### Android-specific objects
|
||||
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
# Steam API Broker Protocol Specification
|
||||
|
||||
## Overview
|
||||
|
||||
Due to proprietary nature of Steamworks SDK, it cannot be run on same amount
|
||||
of platforms supported by Xash3D FWGS, neither we can link library directly due to
|
||||
GNU GPLv3 license.
|
||||
|
||||
However, here comes the broker, by running it (in trusted
|
||||
network, preferrably) on a machine that has Steam client installed, the
|
||||
engine can communicate with it, acquiring needed information to log-in into
|
||||
Steam protected multiplayer servers.
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
Broker uses a simple TCP-based binary protocol with the following properties:
|
||||
|
||||
- Single active session per connection: once a session is activated, the broker will reject all other TCP connections until the session is terminated.
|
||||
- All messages follow a consistent structure with a header, length, and payload: this is called a "frame".
|
||||
- Stateful interactions: commands affect the session state, and certain commands are only valid in specific states.
|
||||
- Numeric parameters are encoded in little-endian format for compatibility with majority of platforms.
|
||||
---
|
||||
|
||||
## Frame Format
|
||||
|
||||
All communication uses a fixed frame structure:
|
||||
|
||||
| Field | Size | Type | Description |
|
||||
|-------|------|------|-------------|
|
||||
| Header | 4 bytes | ASCII | Frame start signature |
|
||||
| Length | 2 bytes | uint16_t (LE) | Size of payload in bytes |
|
||||
| Payload | N bytes | Binary | Command string or response data |
|
||||
|
||||
**Notes**:
|
||||
- Header must be exactly `SBRK` (`53 42 52 4B` in hexadecimal form)
|
||||
- Maximum frame size: soft limit is 4096 bytes, hard limit is 65535 bytes (due to uint16_t usage)
|
||||
|
||||
---
|
||||
|
||||
## Session Lifecycle
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ IDLE │ ← Initial state, accepts new TCP connections
|
||||
└──────────────┘
|
||||
│ sb_gamedir
|
||||
↓
|
||||
┌──────────────┐
|
||||
│ ACTIVE │ ← Session established, rejecting all of other TCP connections
|
||||
└──────────────┘
|
||||
│ sb_connect
|
||||
↓
|
||||
┌──────────────┐
|
||||
│ ACTIVE │ ← Client getting auth ticket to connect to game server
|
||||
└──────────────┘
|
||||
│ sb_disconnect
|
||||
↓
|
||||
┌──────────────┐
|
||||
│ ... │ ← Client announcing disconnect from game server, could connect somewhere again
|
||||
└──────────────┘
|
||||
│
|
||||
↓
|
||||
┌──────────────┐
|
||||
│ ACTIVE │ ← Client shutting down game, terminating broker to reset Steam client state
|
||||
└──────────────┘
|
||||
│ sb_terminate
|
||||
↓
|
||||
┌──────────────┐
|
||||
│ RESTARTING │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
All commands listed below are meant to be sent from client to broker as payload of a frame. The broker will parse the command string and respond accordingly.
|
||||
|
||||
### Session activation
|
||||
|
||||
Activates the session and signaling game startup.
|
||||
|
||||
**Format**: `sb_gamedir <gamedir>`
|
||||
|
||||
**Response**: None
|
||||
|
||||
---
|
||||
|
||||
### Authentication ticket request
|
||||
|
||||
Requests authentication ticket for a game server.
|
||||
|
||||
**Precondition**: Session must be active
|
||||
|
||||
**Format**: `sb_connect <ip:port> <server_steamid> <secure> <challenge>`
|
||||
|
||||
**Parameters**:
|
||||
|
||||
| Name | Description |
|
||||
|------|------------------|
|
||||
| `<ip:port>` | Game server address (e.g., `127.0.0.1:27015`) |
|
||||
| `<server_steamid>` | Server SteamID |
|
||||
| `<secure>` | 0 = insecure, 1 = secure |
|
||||
| `<challenge>` | Random value for reply prevention |
|
||||
|
||||
|
||||
**Response Format**:
|
||||
|
||||
| Field | Size | Type | Description |
|
||||
|-------|------|------|-------------|
|
||||
| Header | 11 bytes | string | `"sb_connect\n"` |
|
||||
| Challenge | 4 bytes | int32_t (LE) | Echo of challenge from request |
|
||||
| SteamID | 8 bytes | uint64_t (LE) | Client SteamID from configuration |
|
||||
| Size | 4 bytes | uint32_t (LE) | Length of ticket in bytes |
|
||||
| Ticket | N bytes | - | Authentication ticket data |
|
||||
|
||||
---
|
||||
|
||||
### Server disconnection announcement
|
||||
|
||||
Notifies broker of disconnection from game server.
|
||||
|
||||
**Precondition**: Session must be active
|
||||
|
||||
**Format**: `sb_disconnect <ip:port> <challenge>`
|
||||
|
||||
**Response**: None
|
||||
|
||||
---
|
||||
|
||||
### Session termination
|
||||
|
||||
Signaling game shutdown to broker and resetting Steam client state.
|
||||
|
||||
**Format**: `sb_terminate`
|
||||
|
||||
**Response**: None
|
||||
|
||||
---
|
||||
@@ -1,181 +0,0 @@
|
||||
# XRCON Protocol Specification
|
||||
|
||||
## Overview
|
||||
|
||||
XRCON is a TCP-based remote console protocol implemented as a server within the engine. It provides an alternative to the legacy RCON (which operates over UDP as out-of-band packets). XRCON uses a framed binary protocol over a single persistent TCP connection, accepting at most one client at a time.
|
||||
|
||||
Key characteristics:
|
||||
|
||||
- Based on TCP (stream-oriented, reliable)
|
||||
- Default port is 27000
|
||||
- Maximum only one concurrent client
|
||||
- Binary framed protocol with a 12-byte header + variable-length payload
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
The XRCON server is controlled by two configuration variables, both restricted to privileged users:
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `xrcon_enable` | `0` (disabled) | Master switch; when enabled, the server starts listening for connections |
|
||||
| `xrcon_address` | `127.0.0.1:27000` | Bind address and port; supports both IPv4 and IPv6. Changing this at runtime triggers a XRCON server restart (stop + rebind) |
|
||||
|
||||
By default, XRCON binds only to localhost (`127.0.0.1`), providing a degree of access control. The server will not start listening until explicitly enabled.
|
||||
|
||||
|
||||
|
||||
## Frame Format
|
||||
|
||||
All XRCON messages are encapsulated in a framed binary format. Each frame consists of a fixed 12-byte header followed by a variable-length payload.
|
||||
|
||||
### Header (12 bytes)
|
||||
|
||||
| Offset | Size | Field | Description |
|
||||
|---|---|---|---|
|
||||
| 0 | 4 | Type | 4-character message type string (null-terminated, occupies 5 bytes in the structure but the 5th byte is padding) |
|
||||
| 4 | 4 | Version | Protocol version (32-bit unsigned integer, network byte order) |
|
||||
| 8 | 2 | Length | Total frame length in bytes, including the header (16-bit unsigned integer, network byte order) |
|
||||
| 10 | 2 | Handle | Handle or sequence number (16-bit unsigned integer, network byte order; currently always zero) |
|
||||
|
||||
|
||||
### Protocol Version
|
||||
|
||||
The current protocol version is `0x000000D4` (212 decimal). The server also accepts `0x00D40000` for compatibility with certain third-party clients (e.g., CS2RemoteConsole).
|
||||
|
||||
### Maximum Frame Size
|
||||
|
||||
- Maximum payload per frame: 4096 bytes
|
||||
- Maximum total packet size (header + payload): approximately 4136 bytes
|
||||
- Receive buffer size: 4096 + 64 bytes
|
||||
- Transmit buffer size: 16384 bytes (4 × maximum frame size)
|
||||
|
||||
### Byte Order
|
||||
|
||||
Multi-byte integer fields (version, length, handle) are transmitted in **network byte order** (big-endian).
|
||||
|
||||
|
||||
|
||||
## Message Types
|
||||
|
||||
| Type | Direction | Description |
|
||||
|---|---|---|
|
||||
| `CMND` | Client → Server | Execute a console command |
|
||||
| `PRNT` | Server → Client | Console output / print message |
|
||||
| `CHAN` | Server → Client | Channel list (channel metadata) |
|
||||
| `AINF` | Server → Client | Application / server info |
|
||||
| `ADON` | Server → Client | Additional info / server name |
|
||||
|
||||
### CMND — Client Command
|
||||
|
||||
**Direction**: Client → Server
|
||||
|
||||
Sent by the client to execute a console command on the server.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"CMND"`, version, length, handle |
|
||||
| Payload | Variable | Raw command string (null-terminated) |
|
||||
|
||||
The command string is injected into the engine's command buffer for execution. There is **no authentication** — any connected client may execute arbitrary commands.
|
||||
|
||||
### PRNT — Server Print
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server to stream console output to the connected client.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"PRNT"`, version, length, handle |
|
||||
| Channel ID | 4 bytes | Channel identifier (unsigned 32-bit integer; always 0 for "Console") |
|
||||
| Padding | 20 bytes | Reserved (5 × 32-bit unsigned integers, all zero) |
|
||||
| Red | 1 byte | Red color component (always 255) |
|
||||
| Green | 1 byte | Green color component (always 255) |
|
||||
| Blue | 1 byte | Blue color component (always 255) |
|
||||
| Alpha | 1 byte | Alpha / opacity component (always 255) |
|
||||
| Text | Variable | The console output text (up to 4096 bytes) |
|
||||
|
||||
|
||||
### CHAN — Channel List
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server during the initial handshake (and potentially later) to describe the available console output channels.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"CHAN"`, version, length, handle |
|
||||
| Channel Count | 2 bytes | Number of channel records (unsigned 16-bit integer; always 1) |
|
||||
|
||||
Each channel record (58 bytes):
|
||||
|
||||
| Field | Size | Description |
|
||||
|---|---|---|
|
||||
| Channel ID | 4 bytes | Unique channel identifier (unsigned 32-bit integer; always 0) |
|
||||
| Unknown 1 | 4 bytes | Reserved (unsigned 32-bit integer; always 0) |
|
||||
| Unknown 2 | 4 bytes | Reserved (unsigned 32-bit integer; always 0) |
|
||||
| Default Verbosity | 4 bytes | Default verbosity level (unsigned 32-bit integer; always 5) |
|
||||
| Current Verbosity | 4 bytes | Current verbosity level (unsigned 32-bit integer; always 5) |
|
||||
| Red | 1 byte | Red color component for the channel (always 255) |
|
||||
| Green | 1 byte | Green color component (always 255) |
|
||||
| Blue | 1 byte | Blue color component (always 255) |
|
||||
| Alpha | 1 byte | Alpha component (always 255) |
|
||||
| Name | 34 bytes | Channel name string, null-padded (always `"Console"`) |
|
||||
|
||||
Total payload size for this frame: 2 + 58 = 60 bytes.
|
||||
|
||||
### AINF — Application Info
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server immediately after a client connects, before `ADON` and `CHAN`.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"AINF"`, version, length, handle |
|
||||
| Payload | 77 bytes | All zeros (placeholder / reserved for structured application information) |
|
||||
|
||||
This packet currently serves as a placeholder and contains no meaningful data. It may be extended in future versions to carry structured metadata about the server application.
|
||||
|
||||
### ADON — Additional Info
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server immediately after `AINF` during the connection handshake.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"ADON"`, version, length, handle |
|
||||
| Unknown | 2 bytes | Reserved (unsigned 16-bit integer; always 0) |
|
||||
| Name Length | 2 bytes | Length of the name string (unsigned 16-bit integer) |
|
||||
| Name | Variable | Server name / identifier string (e.g., `"HLDS"`) |
|
||||
|
||||
This packet carries the server application name, which is a short string identifying the server type (e.g., `"HLDS"` for Half-Life Dedicated Server).
|
||||
|
||||
|
||||
|
||||
## Security
|
||||
|
||||
XRCON has **no built-in authentication or encryption**. There is no password validation or transport-layer security. Any client that can establish a TCP connection to the XRCON port has full command execution access to the engine console.
|
||||
|
||||
The only security measures are:
|
||||
|
||||
1. **Default localhost binding**: The server binds to `127.0.0.1` by default, accepting connections only from the local machine.
|
||||
2. **Disabled by default**: The `xrcon_enable` variable defaults to `0`, so the server does not listen unless explicitly enabled.
|
||||
3. **Privileged variables**: Both configuration variables are restricted to privileged users and cannot be modified through unprivileged console commands or external access.
|
||||
|
||||
|
||||
|
||||
## Comparison with Legacy RCON
|
||||
|
||||
| Feature | XRCON | Legacy RCON |
|
||||
|---|---|---|
|
||||
| Transport | TCP (stream) | UDP (datagram, out-of-band) |
|
||||
| Port | Configurable, default 27000 | Game port (default 27015) |
|
||||
| Framing | Binary frame header | Plain text over UDP |
|
||||
| Authentication | None | Password-based |
|
||||
| Max clients | 1 | Multiple |
|
||||
| Interaction format | Full console access | Request-response only for submitted command |
|
||||
| Supported environments | Client and server | Server only |
|
||||
@@ -85,9 +85,6 @@ These strings are specific to Xash3D FWGS.
|
||||
As Xash3D accidentally supports GoldSrc games, it also supports parsing liblist.gam.\
|
||||
Xash3D will use this file if gameinfo.txt is absent, or if its modification timestamp is older than liblist.gam.
|
||||
|
||||
> [!NOTE]
|
||||
> Starting from January 2025, Xash3D FWGS doesn't automatically generate gameinfo.txt from liblist.gam. The key conversion table still remains but if you wish to use gameinfo.txt instead of liblist.gam, you can execute `fs_make_gameinfo` in console.
|
||||
|
||||
For game creators who plan supporting only Xash3D, using this file is not recommended.
|
||||
|
||||
The table below defines conversion rules from liblist.gam to gameinfo.txt. Some keys' interpretation does differ from `gameinfo.txt`, in this case a note will be left. If `liblist.gam` key isn't present in this table, it's ignored.
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
# Support for GoldSrc network protocol
|
||||
This feature is still work-in-progress, but for now it's available for all users, and we appreciate any bug-reports and contributions around it.
|
||||
|
||||
For connecting to GoldSrc-based servers, use this command:
|
||||
```
|
||||
connect ip:port gs
|
||||
```
|
||||
|
||||
You need to use [Steam API broker](https://github.com/FWGS/steam-broker) and have purchased Half-Life 1 on your Steam account to be able to join GoldSrc servers.
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should accept HLTV connections.
|
||||
Without this requirement, you will just get "Steam validation rejected" error on connecting.
|
||||
|
||||
Broker will run on your PC and will be responsible for communicating with Steam client and obtaining auth tickets.
|
||||
Also, make sure to set that broker as current ticket generator using console or edit `config.cfg` file manually:
|
||||
```
|
||||
cl_ticket_generator steam
|
||||
```
|
||||
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||
|
||||
If you want to join GoldSrc servers from other device (Android/iOS or console), make sure to set proper broker IP address with `cl_steam_broker_addr` console variable. Default value assumed that broker is running on the same device as game client.
|
||||
|
||||
By the way, we encountered that some GoldSrc-based servers are recognizing Xash3D clients as "fake clients" and banning/kicking them. Maybe this problem will be
|
||||
solved along with better compatibility with GoldSrc behavior, but may be not - we don't know logic behind this fake client checks.
|
||||
In case of ReHLDS with Reunion plugin, by default it rejects HLTV clients. But connections from HLTV can be easily enabled in `reunion.cfg` file.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
filename.ext - do not include this file, only copy the header
|
||||
Copyright (C) 2015-2025 Xash3D FWGS contributors
|
||||
|
||||
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 3 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.
|
||||
*/
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.1 MiB |
@@ -1,32 +0,0 @@
|
||||
# NAT bypass feature in Xash3D FWGS
|
||||
Since IPv6 not as widespread as we would like, NAT (Network Address Translation) still being actively used by many internet service providers in an attempts to
|
||||
mitigate IPv4 addresses exhaustion. In short, they uses one IPv4 address and doing some tricks with ports to represent many other users behind this address.
|
||||
|
||||
But this leads to a problem for users: they cannot accept direct
|
||||
incoming connections anymore. This means that if you are behind provider's NAT and will try to setup Xash3D FWGS server - nobody will be able to connect to it,
|
||||
and the server will not show up in servers public list.
|
||||
|
||||
## Is it possible to avoid this problem?
|
||||
In most cases, it is possible to bypass NAT with UDP hole punching, and Xash3D FWGS uses this method too. But this method is not 100% guaranteed to work - it depends
|
||||
on NAT configurations on both server and client side, and there is no way to control it.
|
||||
|
||||
First of all, server should not be behind symmetric NAT. You can check your NAT type on [this page](https://www.checkmynat.com/).
|
||||
If you get "Symmetric NAT" result in this test, that means you cannot setup publicly available server with internet connection that you are using.
|
||||
|
||||
Here is more detailed scheme of different NAT types compatibility, it explains are users with different NAT types can connect to each other or not.
|
||||
Client NAT type on rows, server NAT type on columns:
|
||||
|
||||
| *NAT Type* | Full Cone | Restricted Cone | Port Restricted Cone | Symmetric |
|
||||
| -------------------- | --------- | --------------- | -------------------- | --------- |
|
||||
| Full Cone | ✔️ | ✔️ | ✔️ | ✔️ |
|
||||
| Restricted Cone | ✔️ | ✔️ | ✔️ | ✔️ |
|
||||
| Port Restricted Cone | ✔️ | ✔️ | ✔️ | ❌ |
|
||||
| Symmetric | ✔️ | ✔️ | ❌ | ❌ |
|
||||
|
||||
## How to use NAT bypass feature?
|
||||
If you are starting server within the game, you need to enable option "*Use NAT Bypass instead of direct mode*" in bottom left corner of screen.
|
||||
|
||||
If you are starting dedicated server, you should add console variable `sv_nat 1` to server.cfg file, or add `+sv_nat 1` to server startup parameters.
|
||||
|
||||
If you need to connect to server behind NAT, there is separate tab named *NAT* for such servers in server browser. Note that it is useless to add NAT server to favorites,
|
||||
or somehow trying manually to store it, because it has changing address and port.
|
||||
@@ -2,19 +2,10 @@
|
||||
|
||||
|Name |Version |Why not working |What was made for that
|
||||
|---- |------- |--------------- |----------------------
|
||||
|Area 51 |Update 1 |Uses outdated BSP31 map format and custom HLFX SDK libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps but there no warranty if it works.
|
||||
|Arrange Mod: Rebirth |v150 |No idea yet. |
|
||||
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support. |Recreated source code here: https://github.com/FWGS/hlsdk-portable/tree/bshift.
|
||||
|Counter Strike |Beta 6.5- |Uses an old WON HL 1.0.0.16- interface. |
|
||||
| |1.4 |Has encrypted blob instead of normal client.dll. |You can try [this tool](https://aluigi.altervista.org/papers/hldlldec.zip) to decrypt client.dll but there no warranty if it works.
|
||||
| |1.5 |Has encrypted blob instead of normal client.dll. |Decrypted blob here: https://csm.dev/threads/cs-1-5-client-dll-decrypted-patched-for-usage.38845.
|
||||
| |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|
||||
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|
||||
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support. Uses new sequences code on engine-side that was never used in any other mods before. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|
||||
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|
||||
|Half-Life: Extended |Day One demo |Uses many hooks to GoldSource engine and version check. |Just wait new version or use more old version.
|
||||
|Icon of Hell |Beta 0.99 |Uses outdated BSP31 map format and paranoia 2 libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps and use Paranoia 2: The Savior 1.51 libraries but there no warranty if it works.
|
||||
|Paranoia 2: The Savior |All builds older 1.51 |Uses an old renderer interface and engine features. |
|
||||
|Rebellion |1.0 |Uses an old WON HL 1.0.0.16- interface. |Recreated source code here: https://github.com/FWGS/hlsdk-portable/tree/rebellion.
|
||||
|Sven-Coop |5.0+ |Uses custom GoldSrc engine. |
|
||||
|Time Shadows |Beta 0.1 |Uses Direct3D renderer. |
|
||||
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift
|
||||
|Counter Strike |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Sven-Coop |5.0+ |Uses custom GoldSrc engine |
|
||||
|
||||
|
||||
@@ -16,9 +16,6 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
|
||||
## Battle Grounds
|
||||
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
|
||||
|
||||
## Brain Bread
|
||||
Official github repository - https://github.com/IronOak-Studios/BrainBread
|
||||
|
||||
## Bubblemod
|
||||
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
|
||||
|
||||
@@ -35,27 +32,15 @@ Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/c
|
||||
## Cold Ice Ressurection
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
|
||||
|
||||
## Counter-Life
|
||||
Available on ModDB - https://www.moddb.com/mods/counter-life/downloads/cl-version-1-source-code
|
||||
|
||||
## Cthulhu
|
||||
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
|
||||
|
||||
## Deathmatch Classic
|
||||
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/dmc
|
||||
|
||||
## Delta Particles
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-delta/downloads/delta-particles-full-sources-maps-and-c-code
|
||||
|
||||
## Earth Special Forces
|
||||
Alpha 2.0 - https://www.gamers-desire.de/details/2830
|
||||
|
||||
## ESHQ
|
||||
Official github repository - https://github.com/adslbarxatov/xash3d-for-ESHQ
|
||||
|
||||
## Feline
|
||||
Available on ModDB - https://www.moddb.com/mods/feline-10/downloads/feline-sdk
|
||||
|
||||
## Flat-Life
|
||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_(Flat-Life)
|
||||
|
||||
@@ -70,9 +55,6 @@ Version 3.0, mirrored on github - https://github.com/nekonomicon/Go-mod30
|
||||
## GT mod
|
||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
||||
|
||||
## Half-Force
|
||||
Available on ModDB - https://www.moddb.com/mods/half-force/downloads/half-force-v20-sdk
|
||||
|
||||
## Half-Life: Advanced Deathmatch
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
|
||||
|
||||
@@ -85,9 +67,6 @@ Available on ModDB - https://www.moddb.com/mods/half-life-echoes
|
||||
## Half-Life: Expanded Arsenal
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
|
||||
|
||||
## Half-Life: Field Intensity
|
||||
Branch **field_intensity_1.7** in halflife-featureful - https://github.com/FreeSlave/halflife-featureful/tree/field_intensity_1.7
|
||||
|
||||
## Half-Life: Gravgun mod
|
||||
Branch **gravgun** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/gravgun
|
||||
|
||||
@@ -109,9 +88,6 @@ Official github repository - https://github.com/Fograin/hl-subsmod-ex
|
||||
## Half-Life: Rally
|
||||
Official gitlab repository - https://gitlab.com/hlrally/src
|
||||
|
||||
## Half-Life: RXT
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-rxt/downloads/rxt-source-code-v57
|
||||
|
||||
## Half-Life: Weapon Edition
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
|
||||
|
||||
@@ -133,25 +109,15 @@ Official github repository - https://github.com/HeathGames/half_rats_parasomnia_
|
||||
## Half-Screwed
|
||||
Official github repository - https://github.com/desukuran/half-screwed
|
||||
|
||||
## Halo: GoldSource
|
||||
Available on ModDB - https://www.moddb.com/mods/halo-goldsrc/downloads/halo-gold-source-summer-2025-release-v10-sdk
|
||||
|
||||
## Headcrab Frenzy
|
||||
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
|
||||
|
||||
## Heart of Evil
|
||||
Mirrored on github - https://github.com/nekonomicon/HeartOfEvil
|
||||
|
||||
Mirrored on github (Includes maps and models source files) - https://github.com/malortie/heart-of-evil-source-files
|
||||
|
||||
## Ingram Chillin' Mod
|
||||
Official SourceForge repository - https://sourceforge.net/projects/icm-hl/
|
||||
|
||||
## Master Sword
|
||||
Official github repository of Master Sword Classic - https://github.com/BerntA/MasterSwordClassic
|
||||
|
||||
Official github repository of Master Sword Rebirth - https://github.com/MSRevive/MasterSwordRebirth
|
||||
|
||||
## MechMod
|
||||
Official github repository - https://github.com/vermagav/mechmod
|
||||
|
||||
@@ -175,9 +141,6 @@ Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient
|
||||
|
||||
Version 1.51, mirrored on github - https://github.com/a1batross/Paranoia2_original
|
||||
|
||||
## Public Enemy
|
||||
Official github repository - https://github.com/IronOak-Studios/Public-Enemy
|
||||
|
||||
## Raven City
|
||||
*Unfinished mod*
|
||||
|
||||
@@ -209,9 +172,6 @@ Mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-wastelan
|
||||
## Wizard Wars
|
||||
Download page on official site - http://www.thothie.com/ww/
|
||||
|
||||
## Wrong Door
|
||||
Available on ModDB - https://www.moddb.com/mods/wrong-door/downloads/wrong-door-sdk
|
||||
|
||||
## XashXT
|
||||
Mirrored on github - https://github.com/a1batross/XashXT_original
|
||||
|
||||
@@ -236,7 +196,7 @@ Branch **redempt** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tr
|
||||
OpenAG by YaLTeR - https://github.com/YaLTeR/OpenAG
|
||||
|
||||
## Afraid of Monsters
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-aom
|
||||
malortie's recreation - https://github.com/malortie/hl-aom
|
||||
|
||||
Branch **aom** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aom
|
||||
|
||||
@@ -244,17 +204,17 @@ Branch **aom** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/a
|
||||
Reverse-engineered code: branch **aomdc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aomdc
|
||||
|
||||
## Azure Sheep
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-asheep
|
||||
malortie's recreation - https://github.com/malortie/hl-asheep
|
||||
|
||||
Reverse-engineered code: branch **asheep** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/asheep
|
||||
|
||||
## Big Lolly
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-biglolly
|
||||
malortie's recreation - https://github.com/malortie/hl-biglolly
|
||||
|
||||
Branch **biglolly** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/biglolly
|
||||
|
||||
## Black Ops
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-blackops
|
||||
malortie's recreation - https://github.com/malortie/hl-blackops
|
||||
|
||||
Branch **blackops** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/blackops
|
||||
|
||||
@@ -277,16 +237,13 @@ Reverse-engineered code of server part by s1lentq - https://github.com/s1lentq/R
|
||||
## Counter Strike Online
|
||||
CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
|
||||
|
||||
## Crack-Life
|
||||
Reverse-engineered code: branch **cracklife** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/cracklife
|
||||
|
||||
## Crack-Life: Campaign Mode
|
||||
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
|
||||
|
||||
Reverse-engineered code: branch **clcampaign** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/clcampaign
|
||||
|
||||
## Escape from the Darkness
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-eftd
|
||||
malortie's recreation - https://github.com/malortie/hl-eftd
|
||||
|
||||
Reverse-engineered code: branch **eftd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/eftd
|
||||
|
||||
@@ -317,7 +274,7 @@ Reverse-engineered code: branch **rebellion** in hlsdk-portable - https://github
|
||||
Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/hl_urbicide
|
||||
|
||||
## Half-Life: Visitors
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-visitors
|
||||
malortie's recreation - https://github.com/malortie/hl-visitors
|
||||
|
||||
Reverse-engineered code: branch **visitors** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/visitors
|
||||
|
||||
@@ -325,17 +282,17 @@ Reverse-engineered code: branch **visitors** in hlsdk-portable - https://github.
|
||||
Branch **half-secret** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/half-secret
|
||||
|
||||
## Night at the Office
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-nato
|
||||
malortie's recreation - https://github.com/malortie/hl-nato
|
||||
|
||||
Branch **noffice** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/noffice
|
||||
|
||||
## Poke 646
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-poke646
|
||||
malortie's recreation - https://github.com/malortie/hl-poke646
|
||||
|
||||
Reverse-engineered code: branch **poke646** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646
|
||||
|
||||
## Poke 646: Vendetta
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-poke646-vendetta
|
||||
malortie's recreation - https://github.com/malortie/hl-poke646-vendetta
|
||||
|
||||
Reverse-engineered code: branch **poke646_vendetta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646_vendetta
|
||||
|
||||
@@ -352,19 +309,19 @@ Branch **sewer_beta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable
|
||||
Reverse-engineered code by Velaron - https://github.com/Velaron/tf15-client
|
||||
|
||||
## The Gate
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-thegate
|
||||
malortie's recreation - https://github.com/malortie/hl-thegate
|
||||
|
||||
Reverse-engineered code: branch **thegate** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/thegate
|
||||
|
||||
## They Hunger
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-theyhunger
|
||||
malortie's recreation - https://github.com/malortie/hl-theyhunger
|
||||
|
||||
Reverse-engineered code: branch **theyhunger** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/theyhunger
|
||||
|
||||
They Hunger: Tactical - https://www.moddb.com/mods/they-hunger-tactical/downloads/tht-source-code-documentation
|
||||
|
||||
## Times of Troubles
|
||||
malortie's recreation - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-tot
|
||||
malortie's recreation - https://github.com/malortie/hl-tot
|
||||
|
||||
Branch **tot** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/tot
|
||||
|
||||
@@ -382,14 +339,11 @@ Deathmatch Quaked - https://www.moddb.com/games/deathmatch-classic/downloads/dmq
|
||||
|
||||
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
|
||||
|
||||
## Delta Particles
|
||||
Branch **delta_particles** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/delta_particles
|
||||
|
||||
## Half-Life: Echoes
|
||||
Branch **echoes** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/echoes
|
||||
|
||||
## Half-Life: Invasion
|
||||
Port to HLSDK 2.4 by malortie - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-invasion
|
||||
Port to HLSDK 2.4 by malortie - https://github.com/malortie/hl-invasion
|
||||
|
||||
Port to Linux by fmoraw - https://github.com/fmoraw/hlinvasion
|
||||
|
||||
@@ -408,7 +362,7 @@ Port to Linux - https://github.com/fmoraw/NS
|
||||
Version 1.2: branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
|
||||
|
||||
## Swiss Cheese Halloween 2002
|
||||
Just more playable version by malortie - https://github.com/HL1-Mods-Reimplementations-and-Ports/hl-shall
|
||||
Just more playable version by malortie - https://github.com/malortie/hl-shall
|
||||
|
||||
Branch **halloween** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/halloween
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
Xash3D FWGS is intended to be easily portable for various platforms, however main issue is maintaining such ports.
|
||||
Xash3D FWGS is intended to be easily ported to specific platform, however main issue is maintaining such ports.
|
||||
|
||||
This page is about merged ports to main source tree and responsible for it developers.
|
||||
|
||||
For porting guidelines, read engine-porting-guide.md.
|
||||
For porting guidelines, look engine-porting-guide.md.
|
||||
|
||||
Status:
|
||||
* **Supported**: active, confirmed to be fully functional, gets built on CI.
|
||||
* **Orphaned**: some work was done but not finished or actively tested due to lack of human resources.
|
||||
* **Supported**: active, was confirmed to be fully functional.
|
||||
* **In progress**: active, under development.
|
||||
* **Old Engine**: port was for old engine fork.
|
||||
* **Deprecated**: not supported anymore.
|
||||
* **Old Engine**: port was for old engine fork
|
||||
* **Not maintained**: lack of human resources
|
||||
* **Deprecated**: not supported anymore
|
||||
|
||||
Table is sorted by status and platform.
|
||||
|
||||
@@ -17,22 +17,17 @@ Table is sorted by status and platform.
|
||||
| -------- | ------ | ---------- | ----
|
||||
| Android | Supported | @Velaron |
|
||||
| *BSD | Supported | @nekonomicon |
|
||||
| DOS4GW | Supported | @mittorn |
|
||||
| GNU/Linux | Supported | @a1batross, @mittorn |
|
||||
| Haiku | Supported | not maintained | Was added by #478 and #483
|
||||
| macOS | Supported | @sofakng |
|
||||
| MotoMAGX | Supported | @a1batross |
|
||||
| PSVita | Supported | @fgsfdsfgs |
|
||||
| Switch | Supported | @fgsfdsfgs |
|
||||
| Windows | Supported | @a1batross, @SNMetamorph |
|
||||
| iOS | Supported | @ksagameng2 |
|
||||
| DOS4GW | Orphaned | N/A | Haven't been confirmed to work for a very long time
|
||||
| Haiku | Orphaned | N/A | Was added by #478 and #483
|
||||
| IRIX | Orphaned | N/A | Undone, compiles but requires big endian port
|
||||
| MotoMAGX | Orphaned | N/A | Should work but the compiler used for this platform is very unstable and easy to crash (it's GCC 3.4)
|
||||
| SerenityOS | Orphaned | N/A | Works but not throughly tested
|
||||
| Solaris | Orphaned | N/A | Works but not throughly tested
|
||||
| WebAssembly System Interface | Orphaned | N/A | Undone, WASI is missing a lot of APIs we want to use
|
||||
| Dreamcast | In progress | @maximqaxd | [GitHub Repository](https://github.com/maximqaxd/xash3d-fwgs_dc/)
|
||||
| PSP | In progress | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs)
|
||||
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
|
||||
| Emscripten | Old Engine | N/A |
|
||||
| 3DS | Old Engine fork | N/A | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
||||
| Oculus Quest | Old Engine fork | N/A | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
||||
| Emscripten | Old Engine | not maintained |
|
||||
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
||||
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
||||
| iOS | Deprecated | not maintained | See GitHub issue #61
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Xash3D FWGS protocol support
|
||||
|
||||
Xash3D FWGS currently supports four network protocols:
|
||||
* Version 49, introduced in Xash3D in around 2018.
|
||||
* Version 48, used in Xash3D FWGS 0.19 and earlier. Deprecated and to be removed in the future.
|
||||
* GoldSrc version 48, used in current GoldSource version.
|
||||
* Quake version 15, only used for demo playback for Quake Wrapper mod.
|
||||
|
||||
On the server side, we only support Xash3D 49 protocol, but bugcomp `gsmrf` mode can convert GoldSrc 48 messages into Xash3D 49 on the fly, for some mods that directly write engine internal messages.
|
||||
|
||||
In the following documents we will only cover version 49, as everything else is either not Xash3D specific or deprecated.
|
||||
@@ -1,366 +0,0 @@
|
||||
# Xash3D 49 connectionless protocol
|
||||
|
||||
Connectionless protocol defines four common message sources and destinations, they can be:
|
||||
* `S` for Server
|
||||
* `C` for Client
|
||||
* `M` for Master
|
||||
* `A` for Anything else
|
||||
|
||||
All connectionless packets have `\xff\xff\xff\xff` (32-bit integer set to all ones) in it's header. Let's go through each of possible direction in this document.
|
||||
|
||||
<!--TOC-->
|
||||
|
||||
- [Any](#any)
|
||||
- [Any to Any](#any-to-any)
|
||||
- [`A2A_PING` and `A2A_GOLDSRC_PING`](#a2a_ping-and-a2a_goldsrc_ping)
|
||||
- [`A2A_ACK` and `A2A_GOLDSRC_ACK`](#a2a_ack-and-a2a_goldsrc_ack)
|
||||
- [Deprecated queries](#deprecated-queries)
|
||||
- [`A2A_NETINFO`](#a2a_netinfo)
|
||||
- [`A2A_INFO`](#a2a_info)
|
||||
- [Any to Client](#any-to-client)
|
||||
- [`A2C_PRINT` and `A2C_GOLDSRC_PRINT`](#a2c_print-and-a2c_goldsrc_print)
|
||||
- [Any to Server and Server to Any](#any-to-server-and-server-to-any)
|
||||
- [GoldSrc server queries](#goldsrc-server-queries)
|
||||
- [`A2S_GOLDSRC_INFO`](#a2s_goldsrc_info)
|
||||
- [`A2S_GOLDSRC_PLAYERS`](#a2s_goldsrc_players)
|
||||
- [`A2S_GOLDSRC_RULES`](#a2s_goldsrc_rules)
|
||||
- [Any to Master](#any-to-master)
|
||||
- [`S2M_SCAN_REQUEST`](#s2m_scan_request)
|
||||
- [Master to Any](#master-to-any)
|
||||
- [`M2A_SERVERSLIST`](#m2a_serverslist)
|
||||
- [Master and game server](#master-and-game-server)
|
||||
- [Server to Master](#server-to-master)
|
||||
- [`S2M_HEARTBEAT`](#s2m_heartbeat)
|
||||
- [`S2M_SHUTDOWN`](#s2m_shutdown)
|
||||
- [`S2M_INFO`](#s2m_info)
|
||||
- [Master to Server](#master-to-server)
|
||||
- [`M2S_CHALLENGE`](#m2s_challenge)
|
||||
- [`M2S_NAT_CONNECT`](#m2s_nat_connect)
|
||||
- [Client and game server](#client-and-game-server)
|
||||
- [Client to Server](#client-to-server)
|
||||
- [`C2S_BANDWIDTHTEST`](#c2s_bandwidthtest)
|
||||
- [`C2S_GETCHALLENGE`](#c2s_getchallenge)
|
||||
- [`C2S_CONNECT`](#c2s_connect)
|
||||
- [Server to Client](#server-to-client)
|
||||
- [`S2C_BANDWIDTHTEST`](#s2c_bandwidthtest)
|
||||
- [`S2C_CHALLENGE`](#s2c_challenge)
|
||||
- [`S2C_CONNECTION`](#s2c_connection)
|
||||
- [`S2C_ERRORMSG`](#s2c_errormsg)
|
||||
- [`S2C_REJECT`](#s2c_reject)
|
||||
|
||||
<!--TOC-->
|
||||
|
||||
## Any
|
||||
|
||||
### Any to Any
|
||||
|
||||
#### `A2A_PING` and `A2A_GOLDSRC_PING`
|
||||
|
||||
Simple ping message.
|
||||
* Request, in ASCII: `ping` or `i` in GoldSrc format
|
||||
* Response is always `A2A_ACK` or `A2A_GOLDSRC_ACK`
|
||||
|
||||
#### `A2A_ACK` and `A2A_GOLDSRC_ACK`
|
||||
|
||||
Simple ack message.
|
||||
* Request, in ASCII: `ack` or `j` in GoldSrc format
|
||||
* Response: none
|
||||
|
||||
#### Deprecated queries
|
||||
|
||||
These text-based Xash protocol queries are deprecated in favor of [GoldSrc server queries](#goldsrc-server-queries), which Xash3D FWGS servers implement as well. New implementations must not send them. The server still responds to `A2A_INFO` for compatibility with older clients, `A2A_NETINFO` is not handled anymore.
|
||||
|
||||
##### `A2A_NETINFO`
|
||||
|
||||
Used to implement Half-Life's NetAPI.
|
||||
* Request message, in ASCII: `netinfo <version> <context> <request_id>`
|
||||
- `version` must be 49, as text.
|
||||
- `context` can be any 32-bit signed integer value, encoded as text.
|
||||
- `request_id` see `common/net_api.h`
|
||||
|
||||
* Response message, in ASCII: `netinfo <context> <request_id> <response>`
|
||||
- `context` same as in request.
|
||||
- `request_id` same as in request.
|
||||
- `response` is server's response, depending on request type. Always encoded as Quake info string.
|
||||
|
||||
Possible requests and response formats:
|
||||
* Request ID `1` will make server respond with empty response string.
|
||||
* Request ID `2` makes server respond with all server game rule cvars where the key is cvar name and the value is cvar value. One additional key `rules` with total amount of cvars is added.
|
||||
* Request ID `3` makes server respond with players list, where:
|
||||
- `p<id>name` is set to player's name
|
||||
- `p<id>frags` is set to player's kill count
|
||||
- `p<id>time` is set to player's total play time
|
||||
- `players` is total player's list.
|
||||
- Alternatively, it can respond with `neterror` set to `forbidden` if server does not wish to expose it's player list.
|
||||
* Request ID `4` makes server to respond with common game details:
|
||||
- `hostname` is server's name
|
||||
- `gamedir` is game directory name
|
||||
- `current` is total player count
|
||||
- `max` is max players limit
|
||||
- `map` is server's current level
|
||||
* On any other server will respond with `neterror` set to `undefined`
|
||||
* If protocol version doesn't match, server responds with `neterror` set to `protocol`
|
||||
|
||||
##### `A2A_INFO`
|
||||
|
||||
Used to request server's details.
|
||||
* Request message, in ASCII: `info <version>`
|
||||
- `version` must be 49, as text
|
||||
* Response message, in ASCII: `info\n<response>`
|
||||
- `response` is Quake info string, otherwise it's an error message.
|
||||
|
||||
* Response info string format:
|
||||
- `p` is set to protocol version (FWGS extension)
|
||||
- `map` is server's current level
|
||||
- `dm` set to 1 if current game mode is deathmatch otherwise 0
|
||||
- `team` set to 1 if current game mode includes teamplay otherwise 0
|
||||
- `coop` set to 1 if current game mode is cooperative otherwise 0
|
||||
- `numcl` is total player count
|
||||
- `maxcl` is max players limit
|
||||
- `gamedir` is game directory name
|
||||
- `password` set to 1 if server is protected with password otherwise 0
|
||||
- `host` is server's name
|
||||
|
||||
### Any to Client
|
||||
|
||||
#### `A2C_PRINT` and `A2C_GOLDSRC_PRINT`
|
||||
|
||||
Simple print message.
|
||||
* Header: `\xff\xff\xff\xff`
|
||||
* Request, in ASCII: `print <message>` or `l<message>` in GoldSrc format.
|
||||
* Response: none
|
||||
|
||||
### Any to Server and Server to Any
|
||||
|
||||
#### GoldSrc server queries
|
||||
|
||||
These match Source Engine Query messages used in GoldSrc and Source engine and implemented for compatibility with existing server browsers and monitoring tools. The client uses them to query GoldSrc servers in the server browser, and as text-based Xash protocol queries are [deprecated](#deprecated-queries), it will use them to query Xash servers as well. Read documentation for them on VDC: https://developer.valvesoftware.com/wiki/Server_queries
|
||||
|
||||
Unlike other connectionless messages these are binary: integers are little-endian, floats are 32-bit IEEE 754 and strings are null-terminated.
|
||||
|
||||
`A2S_GOLDSRC_PLAYERS` and `A2S_GOLDSRC_RULES` requests carry a 32-bit challenge, `A2S_GOLDSRC_INFO` may have one appended after the query string. When no challenge is known yet, `\xff\xff\xff\xff` is sent in it's place. The server may answer with a challenge instead of the data: byte `A` (`0x41`) followed by a 32-bit challenge value, 9 bytes total with the header. The request is then repeated with the received challenge. Don't confuse this message with textual `S2C_GOLDSRC_CHALLENGE` used during connection, they only share the first byte.
|
||||
|
||||
Responses that don't fit into a single packet (usually rules) come from GoldSrc servers split into fragments. Such packets start with `\xfe\xff\xff\xff` instead of `\xff\xff\xff\xff`, followed by a 32-bit sequence number, same in all fragments of one response, and a byte with total fragment count in the lower 4 bits and this fragment's index in the upper 4 bits. Fragment payloads concatenated in index order form a normal `\xff\xff\xff\xff` message. Xash servers never split query responses and send them as single datagrams.
|
||||
|
||||
#### `A2S_GOLDSRC_INFO`
|
||||
|
||||
Used to request server's details.
|
||||
|
||||
* Request: `TSource Engine Query\0`, optionally followed by a 32-bit challenge. Xash servers ignore it.
|
||||
* Response: byte `I` (`S2A_GOLDSRC_INFO`), followed by:
|
||||
- byte: protocol version, 48 on GoldSrc, 49 on Xash3D FWGS
|
||||
- string: server's name
|
||||
- string: server's current level
|
||||
- string: game directory name
|
||||
- string: game description
|
||||
- int16: Steam AppID, always 0 on Xash servers
|
||||
- byte: total player count, bots included
|
||||
- byte: max players limit
|
||||
- byte: bot count
|
||||
- byte: server type, `d` for dedicated or `l` for listen server
|
||||
- byte: server's operating system, `w` for Windows, `l` for Linux, `m` for macOS
|
||||
- byte: set to 1 if server is protected with password otherwise 0
|
||||
- byte: set to 1 if server is VAC secured, Xash servers put the `secure` value from gameinfo here
|
||||
- string: server's version
|
||||
|
||||
Same as the Source engine response format but without the extra data flag and its fields.
|
||||
|
||||
Legacy GoldSrc servers respond with the obsolete `m` format (`S2A_GOLDSRC_LEGACY_INFO`) instead, see VDC for its layout. Xash servers never send it but the client understands it and assumes protocol 48.
|
||||
|
||||
#### `A2S_GOLDSRC_PLAYERS`
|
||||
|
||||
Used to request server's player list.
|
||||
|
||||
* Request: byte `U` (`0x55`), then a 32-bit challenge.
|
||||
* Response: byte `D` (`S2A_GOLDSRC_PLAYERS`), followed by a byte with total player count, then for each player:
|
||||
- byte: player's index. Xash servers send sequential indexes starting from 0, GoldSrc servers always send 0 here.
|
||||
- string: player's name
|
||||
- int32: player's kill count
|
||||
- float: time in seconds the player is connected, -1.0 for bots on Xash servers
|
||||
|
||||
Xash server doesn't respond at all if the player list is empty, the server is protected with password or exposing the player list is disabled with `sv_expose_player_list` cvar.
|
||||
|
||||
#### `A2S_GOLDSRC_RULES`
|
||||
|
||||
Used to request server's game rules.
|
||||
|
||||
* Request: byte `V` (`0x56`), then a 32-bit challenge.
|
||||
* Response: byte `E` (`S2A_GOLDSRC_RULES`), followed by an int16 with total rule count, then rule name and rule value strings for each.
|
||||
|
||||
Only server cvars (`FCVAR_SERVER`) are sent. Values of protected cvars (`FCVAR_PROTECTED`) are replaced with `1` if the value is set otherwise `0`. If there are no cvars to expose, server doesn't respond at all.
|
||||
|
||||
### Any to Master
|
||||
|
||||
#### `S2M_SCAN_REQUEST`
|
||||
|
||||
* Request: `1<region><IP:Port>\0<info>`
|
||||
- Format of this message is loosely based on https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol
|
||||
- `info` however adds few additional fields:
|
||||
- `clver` set to engine's version
|
||||
- `nat` set to 1 to filter only servers behind NAT and tell master to notify servers about scan
|
||||
- `commit` set to engine's build commit hash
|
||||
- `branch` set to engine's build branch
|
||||
- `os` set to which operating system engine has been built
|
||||
- `arch` set to which CPU architecture engine has been built
|
||||
- `buildnum` set to engine's build number
|
||||
- `key` set to random 32-bit value formatted as hex, used to validate master responses
|
||||
* Response: `M2A_SERVERSLIST`
|
||||
|
||||
### Master to Any
|
||||
|
||||
#### `M2A_SERVERSLIST`
|
||||
|
||||
* Request: `f\xff<key><reserved><IP:Port>...`
|
||||
- `key` is random 32-bit value set in `S2M_SCAN_REQUEST`
|
||||
- `reserved` is single reserved 8-bit byte
|
||||
- Following is list of IP addresses in binary form: 6-bytes for IPv4 address + port and 18-bytes for IPv6 address + port
|
||||
- If port is 0, it means the end of list, otherwise it's the last IP used for pagination (not implemented in Xash3D)
|
||||
* Response: client doesn't make response to master server but might request `A2S_GOLDSRC_INFO` from servers
|
||||
|
||||
## Master and game server
|
||||
|
||||
### Server to Master
|
||||
|
||||
#### `S2M_HEARTBEAT`
|
||||
|
||||
Used to update game server information on the master server.
|
||||
|
||||
* Request: `q\xff<heartbeat challenge>`
|
||||
- `heartbeat challenge` is random 32-bit value, used to prevent faked/forged source IP addresses.
|
||||
* Response: `M2S_CHALLENGE`
|
||||
|
||||
#### `S2M_SHUTDOWN`
|
||||
|
||||
Used to notify master server about server shutdown, but due to security reasons must be ignored by any master implementation.
|
||||
|
||||
* Request: `\x62\x0a`
|
||||
* Response: none
|
||||
|
||||
#### `S2M_INFO`
|
||||
|
||||
Game server info response on `M2S_CHALLENGE`.
|
||||
|
||||
* Request: `0\n<info>`
|
||||
- `info` is Quake info string containing server information passed to master server. It contains following fields:
|
||||
- `protocol` is always 49
|
||||
- `challenge` is master challenge
|
||||
- `players` is total player count, without bots
|
||||
- `max` is max players limits
|
||||
- `bots` is total bot count
|
||||
- `gamedir` is set to game directory
|
||||
- `map` is server's current level
|
||||
- `type` set to `d` for dedicated or `l` for listen server
|
||||
- `password` set to `1` if server protected with password set otherwise `0`
|
||||
- `os` always `w`
|
||||
- `secure` always `0`
|
||||
- `lan` always `0`
|
||||
- `version` engine version
|
||||
- `region` always `255`
|
||||
- `product` same as `gamedir`
|
||||
- `nat` set to `1` if server is behind NAT
|
||||
* Response: none
|
||||
|
||||
### Master to Server
|
||||
|
||||
#### `M2S_CHALLENGE`
|
||||
|
||||
Master's respoonse on game server's heartbeat message.
|
||||
|
||||
* Request: `s<master challenge><heartbeat challenge>`
|
||||
- `master challenge` contains 32-bit value, used in server response to prevent faked/forged source IP addresses.
|
||||
- `heartbat challenge` cotnains 32-bit value, used in heartbeat request to prevent faked/forged source IP addresses.
|
||||
* Response: `S2M_INFO`.
|
||||
|
||||
#### `M2S_NAT_CONNECT`
|
||||
|
||||
Master server's message with client IP address and port, used in NAT punching.
|
||||
|
||||
* Request: `c <IP:Port>`
|
||||
* Response: `S2C_INFO` to a specified client address.
|
||||
|
||||
## Client and game server
|
||||
|
||||
### Client to Server
|
||||
|
||||
#### `C2S_BANDWIDTHTEST`
|
||||
|
||||
Used to figure out network MTU. The message is optional and server might choose to not implement it or respond with challenge.
|
||||
|
||||
* Request, in ASCII: `bandwidth <version> <max_size>`
|
||||
- `version` must be 49, as text.
|
||||
- `max_size` is requested maximum packet size.
|
||||
|
||||
* Possible responses:
|
||||
- `S2C_BANDWIDTHTEST`
|
||||
- `S2C_CHALLENGE`
|
||||
- `A2A_PRINT` followed by `S2C_REJECT`
|
||||
- `S2C_ERRORMSG` (as FWGS extension) followed by `A2A_PRINT` and `S2C_REJECT`.
|
||||
|
||||
#### `C2S_GETCHALLENGE`
|
||||
|
||||
Used to validate client's address to prevent faked/forged source IP addresses.
|
||||
|
||||
* Header: `\xff\xff\xff\xff`
|
||||
* Request, in ASCII: `getchallenge steam`
|
||||
- `steam` argument is optional and can be ignored by the server, as it's only kept for compatibility with similar GoldSrc 48 message.
|
||||
|
||||
* Possible responses:
|
||||
- `S2C_CHALLENGE`
|
||||
|
||||
#### `C2S_CONNECT`
|
||||
|
||||
Used to build a connection with the server.
|
||||
|
||||
* Header: `\xff\xff\xff\xff`
|
||||
* Request, in ASCII: `connect <version> <challenge> "<protinfo>" "<userinfo>"`
|
||||
- `version` must be 49, as text.
|
||||
- `challenge` must be challenge value, as text.
|
||||
- `protinfo` is a Quake info string, containing protocol extensions and other connection information.
|
||||
- `uuid` is this client's unique ID (FWGS extension) hasheed with MD5.
|
||||
- `qport` is random integer value from 1 to 65535, unique for this engine run.
|
||||
- `ext` is an integer value OR'ed with requested protocol extensions. Currently only extension is `NET_EXT_SPLITSIZE` with the value of `1`, which tells server to split messages based on `cl_dlmax` value from `userinfo`.
|
||||
- `userinfo` contains initial user info, encoded as Quake info string.
|
||||
* Possible responses:
|
||||
- `A2A_PRINT` followed by `S2C_REJECT`
|
||||
- `S2C_ERRORMSG` (as FWGS extension) followed by `A2A_PRINT` and `S2C_REJECT`.
|
||||
- `S2C_CONNECTION`
|
||||
|
||||
### Server to Client
|
||||
|
||||
#### `S2C_BANDWIDTHTEST`
|
||||
|
||||
* Request: `testpacket<crc><blob>`
|
||||
- `crc` is 32-bit CRC of `blob`
|
||||
- `blob` random data
|
||||
* There is no required response to this message
|
||||
|
||||
Total message size doesn't exceed request max size.
|
||||
|
||||
#### `S2C_CHALLENGE`
|
||||
|
||||
* Request, in ASCII: `challenge <value>`
|
||||
- `value` is challenge value that client must include in it's response
|
||||
* Response: `C2S_CONNECT`
|
||||
|
||||
#### `S2C_CONNECTION`
|
||||
|
||||
* Request, in ASCII: `client_connect <protinfo>`
|
||||
- `protinfo` is an optional Quake info string, contains following optional fields:
|
||||
- `ext` is an integer value OR'ed with allowed protocol extension. Bit fields match requested in `ext` field in `C2S_CONNECT`
|
||||
- `cheats` set to 1 if server allows cheats otherwise 0
|
||||
* Response: there is no out of band from the client but client will proceed to building netchan and switch client-server interaction to it.
|
||||
|
||||
#### `S2C_ERRORMSG`
|
||||
|
||||
Show client error message. Doesn't mean connection reject, only used for UI.
|
||||
|
||||
* Request, in ASCII: `errormsg <message>`
|
||||
- `message` contains error message
|
||||
* Response: none
|
||||
|
||||
#### `S2C_REJECT`
|
||||
|
||||
Client has been rejected in connection.
|
||||
|
||||
* Request, in ASCII: `disconnect`
|
||||
* Response: client can cope, get depressed or mentally tell server to fuck off.
|
||||
@@ -1,3 +0,0 @@
|
||||
# Xash3D 49 netchan protocol
|
||||
|
||||
TBD...
|
||||
@@ -1,72 +0,0 @@
|
||||
# Static HTTP server list
|
||||
|
||||
Replacement for the UDP `S2M_SCAN_REQUEST` / `M2A_SERVERSLIST` exchange
|
||||
described in [02-connectionless.md](02-connectionless.md). Read-only HTTP,
|
||||
no NAT punching, no filtering or pagination in the request.
|
||||
|
||||
## URL
|
||||
|
||||
`xashcomm.lst` carries a base URL per source:
|
||||
|
||||
```
|
||||
masterstatic http://master.example.org/server-list
|
||||
```
|
||||
|
||||
The engine appends `/v1/servers/<gamedir>` and `GET`s the result. For
|
||||
`gamedir = valve`:
|
||||
|
||||
```
|
||||
GET http://master.example.org/server-list/v1/servers/valve
|
||||
```
|
||||
|
||||
Trailing slashes on the base URL are stripped. Multiple `masterstatic`
|
||||
lines are allowed; results are merged.
|
||||
|
||||
The request is bare: no body, no auth, no cookies, no compressed encodings.
|
||||
Only the standard `User-Agent` is set. `POST` / `PUT` / `DELETE` are not
|
||||
used; servers register out of band.
|
||||
|
||||
## Response
|
||||
|
||||
UTF-8 text, parsed line by line. Each line is tokenized with
|
||||
`COM_ParseFileSafe` (whitespace separates, `//` and `#` start line
|
||||
comments, `"..."` quotes a token). Blank lines and comment-only lines
|
||||
are ignored. One directive per line:
|
||||
|
||||
* `ip <address>` — Xash3D server (protocol 49).
|
||||
* `gs <address>` — GoldSrc server (protocol 48).
|
||||
|
||||
`<address>` is parsed by `NET_StringToAdr` (`1.2.3.4:27015`,
|
||||
`[2001:db8::1]:27015`, hostnames). Port defaults to `27015`. Lines
|
||||
starting with an unknown directive are skipped entirely, so new keywords
|
||||
with any number of operands can be added without breaking older clients.
|
||||
|
||||
`Content-Type` is not inspected, `text/plain; charset=utf-8` expected.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
# diffusion servers
|
||||
ip 192.0.2.10:27015
|
||||
ip [2001:db8::1]:27015
|
||||
gs 198.51.100.5:27015
|
||||
```
|
||||
|
||||
A file with zero records is valid and represents an empty list.
|
||||
|
||||
### Versioning
|
||||
|
||||
The `/v1/` segment is fixed in this revision. A future protocol revision
|
||||
adds a sibling `/v2/...` resource without breaking older clients.
|
||||
|
||||
## Client behaviour
|
||||
|
||||
Each `ip` / `gs` record from the response triggers a probe to the listed
|
||||
address, identical to a server discovered through the UDP master. DNS
|
||||
errors, non-200 responses, and malformed bodies are reported to the
|
||||
console.
|
||||
|
||||
## Server behaviour
|
||||
|
||||
Any static HTTP server works. A typical setup is a periodic job that
|
||||
probes a set of known addresses and writes `v1/servers/<gamedir>`.
|
||||
@@ -2,14 +2,11 @@
|
||||
|
||||
### Prerequisites
|
||||
1. Make sure your PSVita is [set up to run homebrew applications](https://vita.hacks.guide/).
|
||||
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/). It is recommended to use kubridge version `0.1`, because other versions aren't tested, we don't know are they suitable or not.
|
||||
|
||||
Worth to notice, we got reports that automatic plugins management app EasyPlugin have issues with installing kubridge plugin, so it's better to install it manually: by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`, but could be `ur0:/tai`) and add it to your `config.txt`, for example:
|
||||
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/) by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`) and add it to your `config.txt`, for example:
|
||||
```
|
||||
*KERNEL
|
||||
ux0:tai/kubridge.skprx
|
||||
```
|
||||
|
||||
3. Install `libshacccg.suprx` by following [this guide](https://cimmerian.gitbook.io/vita-troubleshooting-guide/shader-compiler/extract-libshacccg.suprx).
|
||||
|
||||
### Installation
|
||||
|
||||
15
Documentation/public-servers-rules-and-recommendations.md
Normal file
@@ -0,0 +1,15 @@
|
||||
As online community is growing, we don't want to keep bad or invalid servers on the Internet Games list. It's a common rules for all Xash3D server owners who are using default master server.
|
||||
|
||||
1. Breaking master server or clients is prohibited in any way. If you found a serious bug, contact us at contact 'at' fwgs.ru or post an issue at GitHub.
|
||||
|
||||
2. Changing settings, exploiting vulnerabilities of clients is prohibited in any way. If you found a serious bug, contact us at contact 'at' fwgs.ru or post an issue at GitHub.
|
||||
|
||||
2. Agressive advertisement and spam on other servers is prohibited in any way.
|
||||
|
||||
3. If your server is require downloading custom content, it should be available for everyone. Recommended way to deliver custom content is FastDL.
|
||||
|
||||
4. It's recommended to keep your server is up-to-date. You may use our public Debian/Ubuntu/Arch Linux [repository](https://github.com/FWGS/xash3d/wiki/How-to-set-up-a-Xash3D-Dedicated-Server-on-Debian-or-Ubuntu) to simplify updating process.
|
||||
|
||||
Just follow these rules to not get banned on our master server. Good luck, have fun!
|
||||
|
||||
|
||||