mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 04:05:11 +08:00
Compare commits
12 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fb92e22fd | ||
|
|
7364765d62 | ||
|
|
b64329d1ee | ||
|
|
ff1d3c4257 | ||
|
|
d418fb5f28 | ||
|
|
62d7959843 | ||
|
|
980f356fe9 | ||
|
|
83194ca0f5 | ||
|
|
d23968b12e | ||
|
|
5034b860c8 | ||
|
|
5a708f90c6 | ||
|
|
4118ac2561 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -19,6 +19,3 @@
|
||||
[submodule "3rdparty/xash-extras"]
|
||||
path = 3rdparty/extras/xash-extras
|
||||
url = https://github.com/FWGS/xash-extras
|
||||
[submodule "3rdparty/bzip2/bzip2"]
|
||||
path = 3rdparty/bzip2/bzip2
|
||||
url = https://gitlab.com/bzip2/bzip2
|
||||
|
||||
21
3rdparty/MultiEmulator/LICENSE
vendored
21
3rdparty/MultiEmulator/LICENSE
vendored
@@ -1,21 +0,0 @@
|
||||
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
25
3rdparty/MultiEmulator/README.md
vendored
@@ -1,25 +0,0 @@
|
||||
# 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
37
3rdparty/MultiEmulator/include/multi_emulator.h
vendored
@@ -1,37 +0,0 @@
|
||||
#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
13
3rdparty/MultiEmulator/src/AVSMP.cpp
vendored
@@ -1,13 +0,0 @@
|
||||
#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
1376
3rdparty/MultiEmulator/src/CRijndael.cpp
vendored
File diff suppressed because it is too large
Load Diff
187
3rdparty/MultiEmulator/src/CRijndael.h
vendored
187
3rdparty/MultiEmulator/src/CRijndael.h
vendored
@@ -1,187 +0,0 @@
|
||||
#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
128
3rdparty/MultiEmulator/src/DoubleBuffering.cpp
vendored
@@ -1,128 +0,0 @@
|
||||
//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
40
3rdparty/MultiEmulator/src/DoubleBuffering.h
vendored
@@ -1,40 +0,0 @@
|
||||
//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
38
3rdparty/MultiEmulator/src/MessageDigest.cpp
vendored
@@ -1,38 +0,0 @@
|
||||
//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
47
3rdparty/MultiEmulator/src/MessageDigest.h
vendored
@@ -1,47 +0,0 @@
|
||||
//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
13
3rdparty/MultiEmulator/src/OldRevEmu.cpp
vendored
@@ -1,13 +0,0 @@
|
||||
#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
27
3rdparty/MultiEmulator/src/RevEmu.cpp
vendored
@@ -1,27 +0,0 @@
|
||||
#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
55
3rdparty/MultiEmulator/src/RevEmu2013.cpp
vendored
@@ -1,55 +0,0 @@
|
||||
#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
96
3rdparty/MultiEmulator/src/RevSpoofer.cpp
vendored
@@ -1,96 +0,0 @@
|
||||
#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
7
3rdparty/MultiEmulator/src/RevSpoofer.h
vendored
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace RevSpoofer
|
||||
{
|
||||
bool Spoof(char *pszDest, int uSID);
|
||||
unsigned int Hash(char *pszString);
|
||||
}
|
||||
52
3rdparty/MultiEmulator/src/SC2009.cpp
vendored
52
3rdparty/MultiEmulator/src/SC2009.cpp
vendored
@@ -1,52 +0,0 @@
|
||||
#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
734
3rdparty/MultiEmulator/src/SHA.cpp
vendored
@@ -1,734 +0,0 @@
|
||||
//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
379
3rdparty/MultiEmulator/src/SHA.h
vendored
@@ -1,379 +0,0 @@
|
||||
//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
13
3rdparty/MultiEmulator/src/Setti.cpp
vendored
@@ -1,13 +0,0 @@
|
||||
#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
18
3rdparty/MultiEmulator/src/SteamEmu.cpp
vendored
@@ -1,18 +0,0 @@
|
||||
#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
12
3rdparty/MultiEmulator/src/StrUtils.cpp
vendored
@@ -1,12 +0,0 @@
|
||||
#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
3
3rdparty/MultiEmulator/src/StrUtils.h
vendored
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
void CreateRandomString(char *pszDest, int nLength);
|
||||
24
3rdparty/MultiEmulator/wscript
vendored
24
3rdparty/MultiEmulator/wscript
vendored
@@ -1,24 +0,0 @@
|
||||
#! /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
1
3rdparty/bzip2/bz_version.h
vendored
@@ -1 +0,0 @@
|
||||
#define BZ_VERSION "1.1.0-fwgs"
|
||||
1
3rdparty/bzip2/bzip2
vendored
1
3rdparty/bzip2/bzip2
vendored
Submodule 3rdparty/bzip2/bzip2 deleted from 66c46b8c94
34
3rdparty/bzip2/wscript
vendored
34
3rdparty/bzip2/wscript
vendored
@@ -1,34 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
conf.define('_GNU_SOURCE', 1)
|
||||
conf.define('BZ_NO_STDIO', 1)
|
||||
|
||||
if conf.env.DEST_OS == 'win32':
|
||||
conf.define('BZ_LCCWIN32', 1)
|
||||
else:
|
||||
conf.define('BZ_UNIX', 1)
|
||||
|
||||
def build(bld):
|
||||
# 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.h',
|
||||
features = 'c',
|
||||
includes = ['.', 'bzip2/'],
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
export_includes = ['bzip2/']
|
||||
)
|
||||
@@ -14,4 +14,3 @@ When `-bugcomp` is specified with argument, it interpreted as flags separated wi
|
||||
| ------- | ----------- | ---------------------------- |
|
||||
| `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. 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. |
|
||||
|
||||
19
Documentation/extensions/litwater.md
Normal file
19
Documentation/extensions/litwater.md
Normal file
@@ -0,0 +1,19 @@
|
||||
## 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.
|
||||
@@ -1,14 +0,0 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||
|
||||
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.
|
||||
61
README.md
61
README.md
@@ -11,12 +11,12 @@ Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://ww
|
||||
If you like Xash3D FWGS, consider supporting individual engine maintainers. By supporting us, you help to continue developing this game engine further. The sponsorship links are available in [documentation](Documentation/donate.md).
|
||||
|
||||
## Fork features
|
||||
* Steam Half-Life (HLSDK 2.5) support.
|
||||
* Steam Half-Life (HLSDK 2.4) support.
|
||||
* Crossplatform and modern compilers support: supports Windows, Linux, BSD & Android on x86 & ARM and [many more](Documentation/ports.md).
|
||||
* Better multiplayer: multiple master servers, headless dedicated server, voice chat, [GoldSrc protocol support](Documentation/goldsrc-protocol-support.md) and IPv6 support.
|
||||
* Better multiplayer support: multiple master servers, headless dedicated server, voice chat and IPv6 support.
|
||||
* Multiple renderers support: OpenGL, GLESv1, GLESv2 and Software.
|
||||
* Advanced virtual filesystem: `.pk3` and `.pk3dir` support, compatibility with GoldSrc FS module, fast case-insensitivity emulation for crossplatform.
|
||||
* Mobility API: better game integration on mobile devices (vibration, touch controls).
|
||||
* Mobility API: better game integration on mobile devices (vibration, touch controls)
|
||||
* Different input methods: touch and gamepad in addition to mouse & keyboard.
|
||||
* TrueType font rendering, as a part of mainui_cpp.
|
||||
* External VGUI support module.
|
||||
@@ -35,16 +35,17 @@ You still needed to copy `valve` directory as all game resources located there.
|
||||
For additional info, run Xash3D with `-help` command line key.
|
||||
|
||||
## Contributing
|
||||
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html.
|
||||
* Issues are accepted in both English and Russian.
|
||||
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html
|
||||
* Issues are accepted in both English and Russian
|
||||
* Before sending a PR, check if you followed our contribution guide in CONTRIBUTING.md file.
|
||||
|
||||
## Build instructions
|
||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
|
||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read https://waf.io/book/
|
||||
|
||||
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
|
||||
|
||||
### Prerequisites
|
||||
|
||||
If your CPU is x86 compatible and you're on Windows or Linux, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
|
||||
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
|
||||
|
||||
@@ -61,39 +62,31 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
|
||||
#### GNU/Linux
|
||||
##### Debian/Ubuntu
|
||||
* For 32-bit engine on 64-bit x86 operating system:
|
||||
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`.
|
||||
* Install development tools: `$ sudo apt install build-essential gcc-multilib g++-multilib python libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype6-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`.
|
||||
* Enable i386 on your system, if you're compiling 32-bit engine on amd64. If not, skip this
|
||||
|
||||
* For non-x86 systems:
|
||||
* Install development tools: `$ sudo apt install build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev libopus-dev libbz2-dev`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
##### RedHat/Fedora
|
||||
* For 32-bit engine on 64-bit x86 operating system:
|
||||
* Install development tools: `$ sudo dnf install gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 fontconfig-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
|
||||
|
||||
* For non-x86 systems:
|
||||
* Install development tools: `$ sudo dnf install gcc gcc-c++ SDL2-devel opus-devel fontconfig-devel freetype-devel bzip2-devel`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
`$ sudo dpkg --add-architecture i386`
|
||||
* Install development tools
|
||||
* For 32-bit engine on amd64: \
|
||||
`$ sudo apt install build-essential gcc-multilib g++-multilib python libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype6-dev:i386`
|
||||
* For everything else: \
|
||||
`$ sudo apt install build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev`
|
||||
* Clone this repostory:
|
||||
`$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`
|
||||
|
||||
### Building
|
||||
#### Windows (Visual Studio)
|
||||
0) Open command line.
|
||||
0) Open command line
|
||||
1) Navigate to `xash3d-fwgs` directory.
|
||||
2) (optional) Examine which build options are available: `waf --help`.
|
||||
3) Configure build: `waf configure --sdl2=c:/path/to/SDL2`.
|
||||
4) Compile: `waf build`.
|
||||
5) Install: `waf install --destdir=c:/path/to/any/output/directory`.
|
||||
2) Carefully examine which build options are available: `waf --help`
|
||||
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2`
|
||||
4) Compile: `waf build`
|
||||
5) Install: `waf install --destdir=c:/path/to/any/output/directory`
|
||||
|
||||
#### Linux
|
||||
If compiling 32-bit on amd64, make sure `PKG_CONFIG_PATH` from the previous step is set correctly, prior to running configure.
|
||||
If compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
|
||||
|
||||
0) (optional) Examine which build options are available: `./waf --help`.
|
||||
1) Configure build: `./waf configure` (you need to pass `-8` to compile 64-bit engine on 64-bit x86 processor).
|
||||
2) Compile: `./waf build`.
|
||||
3) Install: `./waf install --destdir=/path/to/any/output/directory`.
|
||||
0) Examine which build options are available: `./waf --help`
|
||||
1) Configure build: `./waf configure -T release`
|
||||
(You need to pass `-8` to compile 64-bit engine on 64-bit x86 processor)
|
||||
2) Compile: `./waf build`
|
||||
3) Install(optional): `./waf install --destdir=/path/to/any/output/directory`
|
||||
|
||||
@@ -56,8 +56,6 @@ color24 gTracerColors[] =
|
||||
};
|
||||
*/
|
||||
|
||||
#define TRACER_COLORINDEX_DEFAULT 4
|
||||
|
||||
// Temporary entity array
|
||||
#define TENTPRIORITY_LOW 0
|
||||
#define TENTPRIORITY_HIGH 1
|
||||
|
||||
@@ -79,22 +79,11 @@ typedef uint64_t longtime_t;
|
||||
#define GAME_EXPORT
|
||||
#endif
|
||||
|
||||
#define MALLOC __attribute__(( malloc ))
|
||||
|
||||
// added in GCC 11
|
||||
#if __GNUC__ >= 11
|
||||
// might want to set noclone due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116893
|
||||
// but it's easier to not force mismatched-dealloc to error yet
|
||||
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
|
||||
#else
|
||||
#define MALLOC_LIKE( x, y ) MALLOC
|
||||
#endif
|
||||
#define NORETURN __attribute__(( noreturn ))
|
||||
#define NONNULL __attribute__(( nonnull ))
|
||||
#define _format( x ) __attribute__(( format( printf, x, x + 1 )))
|
||||
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
||||
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
|
||||
#define RENAME_SYMBOL( x ) asm( x )
|
||||
#else
|
||||
#if defined( _MSC_VER )
|
||||
@@ -110,9 +99,6 @@ typedef uint64_t longtime_t;
|
||||
#define _format( x )
|
||||
#define ALLOC_CHECK( x )
|
||||
#define RENAME_SYMBOL( x )
|
||||
#define MALLOC
|
||||
#define MALLOC_LIKE( x, y )
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
|
||||
@@ -274,13 +274,6 @@ void CL_GenericShot_f( void )
|
||||
string checkname;
|
||||
int i;
|
||||
|
||||
// allow overriding screenshot by users request
|
||||
if( Cmd_Argc() > 1 )
|
||||
{
|
||||
Q_strncpy( cls.shotname, Cmd_Argv( 1 ), sizeof( cls.shotname ));
|
||||
break;
|
||||
}
|
||||
|
||||
if( type == scrshot_snapshot )
|
||||
{
|
||||
fmt = "../%s_%04d.png";
|
||||
|
||||
@@ -40,8 +40,6 @@ GNU General Public License for more details.
|
||||
#define IDEMOHEADER (('M'<<24)+('E'<<16)+('D'<<8)+'I') // little-endian "IDEM"
|
||||
#define DEMO_PROTOCOL 3
|
||||
|
||||
#define PROTOCOL_GOLDSRC_VERSION_DEMO (PROTOCOL_GOLDSRC_VERSION | (BIT( 7 ))) // should be 48, only to differentiate it from PROTOCOL_LEGACY_VERSION
|
||||
|
||||
const char *demo_cmd[dem_lastcmd+1] =
|
||||
{
|
||||
"dem_unknown",
|
||||
@@ -122,7 +120,7 @@ static int CL_GetDemoNetProtocol( connprotocol_t proto )
|
||||
case PROTO_QUAKE:
|
||||
return PROTOCOL_VERSION_QUAKE;
|
||||
case PROTO_GOLDSRC:
|
||||
return PROTOCOL_GOLDSRC_VERSION_DEMO;
|
||||
return PROTOCOL_GOLDSRC_VERSION;
|
||||
}
|
||||
|
||||
return PROTOCOL_VERSION;
|
||||
@@ -138,7 +136,7 @@ static connprotocol_t CL_GetProtocolFromDemo( int net_protocol )
|
||||
return PROTO_LEGACY;
|
||||
case PROTOCOL_VERSION_QUAKE:
|
||||
return PROTO_QUAKE;
|
||||
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
||||
case PROTOCOL_GOLDSRC_VERSION:
|
||||
return PROTO_GOLDSRC;
|
||||
}
|
||||
|
||||
@@ -708,7 +706,7 @@ static void CL_DemoStartPlayback( int mode )
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize, 0 );
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
|
||||
@@ -25,16 +25,13 @@ static CVAR_DEFINE_AUTO( tracerspeed, "6000", 0, "tracer speed" );
|
||||
static CVAR_DEFINE_AUTO( tracerlength, "0.8", 0, "tracer length factor" );
|
||||
static CVAR_DEFINE_AUTO( traceroffset, "30", 0, "tracer starting offset" );
|
||||
|
||||
static particle_t *cl_active_particles;
|
||||
static particle_t *cl_active_tracers;
|
||||
static particle_t *cl_free_particles;
|
||||
static particle_t *cl_particles = NULL; // particle pool
|
||||
particle_t *cl_active_particles;
|
||||
particle_t *cl_active_tracers;
|
||||
particle_t *cl_free_particles;
|
||||
particle_t *cl_particles = NULL; // particle pool
|
||||
static vec3_t cl_avelocities[NUMVERTEXNORMALS];
|
||||
static float cl_lasttimewarn = 0.0f;
|
||||
|
||||
// expand debugging BBOX particle hulls by this many units.
|
||||
#define BOX_GAP 0.0f
|
||||
|
||||
/*
|
||||
================
|
||||
R_LookupColor
|
||||
@@ -253,7 +250,7 @@ static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life
|
||||
VectorCopy( vel, p->vel );
|
||||
p->die = cl.time + life;
|
||||
p->ramp = tracerlength.value;
|
||||
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
||||
p->color = 4; // select custom color
|
||||
p->packedColor = 255; // alpha
|
||||
|
||||
return p;
|
||||
@@ -265,9 +262,9 @@ VIEWBEAMS MANAGEMENT
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
static BEAM *cl_active_beams;
|
||||
static BEAM *cl_free_beams;
|
||||
static BEAM *cl_viewbeams = NULL; // beams pool
|
||||
BEAM *cl_active_beams;
|
||||
BEAM *cl_free_beams;
|
||||
BEAM *cl_viewbeams = NULL; // beams pool
|
||||
|
||||
|
||||
/*
|
||||
@@ -1604,73 +1601,6 @@ void GAME_EXPORT R_RocketTrail( vec3_t start, vec3_t end, int type )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_ParticleLine
|
||||
|
||||
draw line from particles
|
||||
================
|
||||
*/
|
||||
static void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel )
|
||||
{
|
||||
float len, curdist;
|
||||
vec3_t diff, pos;
|
||||
|
||||
// determine distance
|
||||
VectorSubtract( end, start, diff );
|
||||
len = VectorNormalizeLength( diff );
|
||||
curdist = 0;
|
||||
|
||||
while( curdist <= len )
|
||||
{
|
||||
VectorMA( start, curdist, diff, pos );
|
||||
CL_Particle( pos, pcolor, life, 0, zvel );
|
||||
curdist += 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawRectangle
|
||||
|
||||
================
|
||||
*/
|
||||
static void PM_DrawRectangle( const vec3_t tl, const vec3_t bl, const vec3_t tr, const vec3_t br, int pcolor, float life )
|
||||
{
|
||||
PM_ParticleLine( tl, bl, pcolor, life, 0 );
|
||||
PM_ParticleLine( bl, br, pcolor, life, 0 );
|
||||
PM_ParticleLine( br, tr, pcolor, life, 0 );
|
||||
PM_ParticleLine( tr, tl, pcolor, life, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawBBox
|
||||
|
||||
================
|
||||
*/
|
||||
static void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life )
|
||||
{
|
||||
vec3_t p[8], tmp;
|
||||
float gap = BOX_GAP;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
tmp[0] = (i & 1) ? mins[0] - gap : maxs[0] + gap;
|
||||
tmp[1] = (i & 2) ? mins[1] - gap : maxs[1] + gap ;
|
||||
tmp[2] = (i & 4) ? mins[2] - gap : maxs[2] + gap ;
|
||||
|
||||
VectorAdd( tmp, origin, tmp );
|
||||
VectorCopy( tmp, p[i] );
|
||||
}
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_ParticleLine
|
||||
@@ -1834,6 +1764,25 @@ void GAME_EXPORT R_StreakSplash( const vec3_t pos, const vec3_t dir, int color,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DebugParticle
|
||||
|
||||
just for debug purposes
|
||||
===============
|
||||
*/
|
||||
void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b )
|
||||
{
|
||||
particle_t *p;
|
||||
|
||||
p = R_AllocParticle( NULL );
|
||||
if( !p ) return;
|
||||
|
||||
VectorCopy( pos, p->org );
|
||||
p->color = R_LookupColor( r, g, b );
|
||||
p->die = cl.time + 0.01f;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_Particle
|
||||
|
||||
@@ -380,7 +380,7 @@ CL_ParseReliableEvent
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg )
|
||||
{
|
||||
int event_index;
|
||||
event_args_t nullargs, args;
|
||||
@@ -390,19 +390,11 @@ void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
event_index = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
|
||||
// reliable events not use delta-compression just null-compression
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
Delta_ReadGSFields( msg, DT_EVENT_T, &nullargs, &args, 0.0f );
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
}
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
|
||||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
args.angles[PITCH] *= -3.0f;
|
||||
@@ -417,43 +409,34 @@ CL_ParseEvent
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
void CL_ParseEvent( sizebuf_t *msg )
|
||||
{
|
||||
int event_index;
|
||||
int i, num_events;
|
||||
int packet_index;
|
||||
const event_args_t nullargs = { 0 };
|
||||
event_args_t args = { 0 };
|
||||
event_args_t nullargs, args;
|
||||
entity_state_t *state;
|
||||
float delay;
|
||||
int entity_bits;
|
||||
|
||||
memset( &nullargs, 0, sizeof( nullargs ));
|
||||
memset( &args, 0, sizeof( args ));
|
||||
|
||||
num_events = MSG_ReadUBitLong( msg, 5 );
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
||||
else if( proto == PROTO_LEGACY )
|
||||
entity_bits = MAX_LEGACY_ENTITY_BITS;
|
||||
else entity_bits = MAX_ENTITY_BITS;
|
||||
|
||||
// parse events queue
|
||||
for( i = 0 ; i < num_events; i++ )
|
||||
{
|
||||
event_index = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
packet_index = MSG_ReadUBitLong( msg, entity_bits );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
Delta_ReadGSFields( msg, DT_EVENT_T, &nullargs, &args, 0.0f );
|
||||
else MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
}
|
||||
}
|
||||
packet_index = MSG_ReadUBitLong( msg, cls.legacymode ? MAX_LEGACY_ENTITY_BITS : MAX_ENTITY_BITS );
|
||||
else packet_index = -1;
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args );
|
||||
}
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
delay = (float)MSG_ReadWord( msg ) * (1.0f / 100.0f);
|
||||
else delay = 0.0f;
|
||||
|
||||
@@ -174,7 +174,7 @@ static qboolean CL_EntityCustomLerp( cl_entity_t *e )
|
||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
||||
case MOVETYPE_TOSS:
|
||||
if( cls.legacymode == PROTO_LEGACY && e->model && e->model->type == mod_studio )
|
||||
if( cls.legacymode && e->model && e->model->type == mod_studio )
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -669,9 +669,9 @@ FRAME PARSING
|
||||
|
||||
=========================================================================
|
||||
*/
|
||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum )
|
||||
{
|
||||
if( proto == PROTO_LEGACY )
|
||||
if( cls.legacymode )
|
||||
{
|
||||
*newnum = MSG_ReadWord( msg );
|
||||
if( *newnum == 0 )
|
||||
@@ -694,7 +694,7 @@ CL_FlushEntityPacket
|
||||
Read and ignore whole entity packet.
|
||||
=================
|
||||
*/
|
||||
static void CL_FlushEntityPacket( sizebuf_t *msg, connprotocol_t proto )
|
||||
static void CL_FlushEntityPacket( sizebuf_t *msg )
|
||||
{
|
||||
int newnum;
|
||||
entity_state_t from, to;
|
||||
@@ -707,7 +707,7 @@ static void CL_FlushEntityPacket( sizebuf_t *msg, connprotocol_t proto )
|
||||
// read it all, but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum, proto ))
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
|
||||
break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
@@ -717,47 +717,6 @@ static void CL_FlushEntityPacket( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
}
|
||||
|
||||
qboolean CL_ValidateDeltaPacket( uint oldpacket, frame_t *oldframe )
|
||||
{
|
||||
int subtracted = ( cls.netchan.incoming_sequence - oldpacket ) & 0xFF;
|
||||
|
||||
if( subtracted == 0 )
|
||||
{
|
||||
Con_NPrintf( 2, "^3Warning:^1 update too old\n^7\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( subtracted >= CL_UPDATE_MASK )
|
||||
{
|
||||
// we can't use this, it is too old
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(( cls.next_client_entities - oldframe->first_entity ) > ( cls.num_client_entities - NUM_PACKET_ENTITIES ))
|
||||
{
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CL_UpdateOldEntNum( int oldindex, frame_t *oldframe, entity_state_t **oldent )
|
||||
{
|
||||
if( !oldframe )
|
||||
{
|
||||
*oldent = NULL;
|
||||
return MAX_ENTNUMBER;
|
||||
}
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
return MAX_ENTNUMBER;
|
||||
|
||||
*oldent = &cls.packet_entities[(oldframe->first_entity + oldindex) % cls.num_client_entities];
|
||||
return (*oldent)->number;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DeltaEntity
|
||||
@@ -828,7 +787,7 @@ An svc_packetentities has just been parsed, deal with the
|
||||
rest of the data stream.
|
||||
==================
|
||||
*/
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto )
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
||||
{
|
||||
frame_t *newframe, *oldframe;
|
||||
int oldindex, newnum, oldnum;
|
||||
@@ -844,7 +803,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
CL_WriteDemoJumpTime();
|
||||
|
||||
// sentinel count. save it for debug checking
|
||||
if( proto == PROTO_LEGACY )
|
||||
if( cls.legacymode )
|
||||
count = MSG_ReadWord( msg );
|
||||
else count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
||||
|
||||
@@ -858,12 +817,32 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
|
||||
if( delta )
|
||||
{
|
||||
uint oldpacket = MSG_ReadByte( msg );
|
||||
int subtracted;
|
||||
|
||||
oldpacket = MSG_ReadByte( msg );
|
||||
subtracted = ( cls.netchan.incoming_sequence - oldpacket ) & 0xFF;
|
||||
|
||||
if( subtracted == 0 )
|
||||
{
|
||||
Con_NPrintf( 2, "^3Warning:^1 update too old\n^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
if( subtracted >= CL_UPDATE_MASK )
|
||||
{
|
||||
// we can't use this, it is too old
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
oldframe = &cl.frames[oldpacket & CL_UPDATE_MASK];
|
||||
|
||||
if( !CL_ValidateDeltaPacket( oldpacket, oldframe ))
|
||||
if(( cls.next_client_entities - oldframe->first_entity ) > ( cls.num_client_entities - NUM_PACKET_ENTITIES ))
|
||||
{
|
||||
CL_FlushEntityPacket( msg, proto );
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
}
|
||||
@@ -881,11 +860,27 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
|
||||
oldent = NULL;
|
||||
oldindex = 0;
|
||||
oldnum = CL_UpdateOldEntNum( oldindex, oldframe, &oldent );
|
||||
|
||||
if( !oldframe )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum, proto ))
|
||||
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
|
||||
break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
@@ -897,7 +892,17 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
{
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_DeltaEntity( msg, newframe, oldnum, oldent, false );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
oldindex++;
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
}
|
||||
|
||||
if( oldnum == newnum )
|
||||
@@ -906,7 +911,17 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
CL_DeltaEntity( msg, newframe, newnum, oldent, true );
|
||||
if( player ) playerbytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
oldindex++;
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -925,7 +940,17 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
{
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_DeltaEntity( msg, newframe, oldnum, oldent, false );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
oldindex++;
|
||||
|
||||
if( oldindex >= oldframe->num_entities )
|
||||
{
|
||||
oldnum = MAX_ENTNUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldent = &cls.packet_entities[(oldframe->first_entity+oldindex) % cls.num_client_entities];
|
||||
oldnum = oldent->number;
|
||||
}
|
||||
}
|
||||
|
||||
if( newframe->num_entities != count && newframe->num_entities != 0 )
|
||||
@@ -947,7 +972,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
cls.signon = SIGNONS;
|
||||
|
||||
// Clear loading plaque.
|
||||
CL_SignonReply( proto );
|
||||
CL_SignonReply ();
|
||||
}
|
||||
|
||||
return playerbytes;
|
||||
@@ -1265,7 +1290,7 @@ static void CL_LinkPacketEntities( frame_t *frame )
|
||||
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
|
||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
||||
else if( cls.legacymode == PROTO_LEGACY && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
|
||||
else if( cls.legacymode && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
|
||||
{
|
||||
if( !CL_InterpolateModel( ent ))
|
||||
continue;
|
||||
|
||||
@@ -34,10 +34,10 @@ GNU General Public License for more details.
|
||||
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
|
||||
#define TEXT_MSGNAME "TextMessage%i"
|
||||
|
||||
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||
static client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
||||
char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||
client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
||||
|
||||
static const dllfunc_t cdll_exports[] =
|
||||
static dllfunc_t cdll_exports[] =
|
||||
{
|
||||
{ "Initialize", (void **)&clgame.dllFuncs.pfnInitialize },
|
||||
{ "HUD_VidInit", (void **)&clgame.dllFuncs.pfnVidInit },
|
||||
@@ -80,7 +80,7 @@ static const dllfunc_t cdll_exports[] =
|
||||
};
|
||||
|
||||
// optional exports
|
||||
static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
|
||||
static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
|
||||
{
|
||||
{ "HUD_GetStudioModelInterface", (void **)&clgame.dllFuncs.pfnGetStudioModelInterface },
|
||||
{ "HUD_DirectorMessage", (void **)&clgame.dllFuncs.pfnDirectorMessage },
|
||||
@@ -140,7 +140,11 @@ returns true if thirdperson is enabled
|
||||
*/
|
||||
qboolean CL_IsThirdPerson( void )
|
||||
{
|
||||
return clgame.dllFuncs.CL_IsThirdPerson() ? true : false;
|
||||
cl.local.thirdperson = clgame.dllFuncs.CL_IsThirdPerson();
|
||||
|
||||
if( cl.local.thirdperson )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -248,18 +252,18 @@ static int CL_AdjustXPos( float x, int width, int totalWidth )
|
||||
|
||||
if( x == -1 )
|
||||
{
|
||||
xPos = ( clgame.scrInfo.iWidth - width ) * 0.5f;
|
||||
xPos = ( refState.width - width ) * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( x < 0 )
|
||||
xPos = (1.0f + x) * clgame.scrInfo.iWidth - totalWidth; // Alight right
|
||||
xPos = (1.0f + x) * refState.width - totalWidth; // Alight right
|
||||
else // align left
|
||||
xPos = x * clgame.scrInfo.iWidth;
|
||||
xPos = x * refState.width;
|
||||
}
|
||||
|
||||
if( xPos + width > clgame.scrInfo.iWidth )
|
||||
xPos = clgame.scrInfo.iWidth - width;
|
||||
if( xPos + width > refState.width )
|
||||
xPos = refState.width - width;
|
||||
else if( xPos < 0 )
|
||||
xPos = 0;
|
||||
|
||||
@@ -279,19 +283,19 @@ static int CL_AdjustYPos( float y, int height )
|
||||
|
||||
if( y == -1 ) // centered?
|
||||
{
|
||||
yPos = ( clgame.scrInfo.iHeight - height ) * 0.5f;
|
||||
yPos = ( refState.height - height ) * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Alight bottom?
|
||||
if( y < 0 )
|
||||
yPos = (1.0f + y) * clgame.scrInfo.iHeight - height; // Alight bottom
|
||||
yPos = (1.0f + y) * refState.height - height; // Alight bottom
|
||||
else // align top
|
||||
yPos = y * clgame.scrInfo.iHeight;
|
||||
yPos = y * refState.height;
|
||||
}
|
||||
|
||||
if( yPos + height > clgame.scrInfo.iHeight )
|
||||
yPos = clgame.scrInfo.iHeight - height;
|
||||
if( yPos + height > refState.height )
|
||||
yPos = refState.height - height;
|
||||
else if( yPos < 0 )
|
||||
yPos = 0;
|
||||
|
||||
@@ -1015,8 +1019,7 @@ void CL_DrawHUD( int state )
|
||||
CL_DrawCrosshair ();
|
||||
CL_DrawCenterPrint ();
|
||||
clgame.dllFuncs.pfnRedraw( cl.time, cl.intermission );
|
||||
if( showpause.value )
|
||||
CL_DrawLoadingOrPaused( cls.pauseIcon );
|
||||
CL_DrawLoadingOrPaused( cls.pauseIcon );
|
||||
break;
|
||||
case CL_LOADING:
|
||||
CL_DrawLoadingOrPaused( cls.loadingBar );
|
||||
|
||||
@@ -30,7 +30,6 @@ GNU General Public License for more details.
|
||||
#define CL_CONNECTION_RETRIES 10
|
||||
#define CL_TEST_RETRIES 5
|
||||
|
||||
CVAR_DEFINE_AUTO( showpause, "1", 0, "show pause logo when paused" );
|
||||
CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" );
|
||||
static CVAR_DEFINE_AUTO( dev_overview, "0", 0, "draw level in overview-mode" );
|
||||
static CVAR_DEFINE_AUTO( cl_resend, "6.0", 0, "time to resend connect" );
|
||||
@@ -76,7 +75,7 @@ static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming
|
||||
|
||||
CVAR_DEFINE_AUTO( cl_lw, "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
|
||||
CVAR_DEFINE_AUTO( cl_charset, "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_stufftext, "0", FCVAR_ARCHIVE, "enable stufftext (server-to-client console commands) tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_stufftext, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable stufftext (server-to-client console commands) tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable events tracing (good for developers)" );
|
||||
static CVAR_DEFINE_AUTO( cl_nat, "0", 0, "show servers running under NAT" );
|
||||
@@ -171,11 +170,6 @@ int CL_IsDevOverviewMode( void )
|
||||
return 0;
|
||||
}
|
||||
|
||||
connprotocol_t CL_Protocol( void )
|
||||
{
|
||||
return cls.legacymode;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_CheckClientState
|
||||
@@ -223,7 +217,7 @@ CL_SignonReply
|
||||
An svc_signonnum has been received, perform a client side setup
|
||||
=====================
|
||||
*/
|
||||
void CL_SignonReply( connprotocol_t proto )
|
||||
void CL_SignonReply( void )
|
||||
{
|
||||
// g-cont. my favorite message :-)
|
||||
Con_Reportf( "%s: %i\n", __func__, cls.signon );
|
||||
@@ -231,7 +225,7 @@ void CL_SignonReply( connprotocol_t proto )
|
||||
switch( cls.signon )
|
||||
{
|
||||
case 1:
|
||||
CL_ServerCommand( true, proto == PROTO_GOLDSRC ? "sendents" : "begin" );
|
||||
CL_ServerCommand( true, "begin" );
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
Mem_PrintStats();
|
||||
break;
|
||||
@@ -599,7 +593,7 @@ static void CL_CreateCmd( void )
|
||||
int input_override;
|
||||
int i, ms;
|
||||
|
||||
if( cls.state <= ca_connected || cls.state == ca_cinematic )
|
||||
if( cls.state < ca_connected || cls.state == ca_cinematic )
|
||||
return;
|
||||
|
||||
// store viewangles in case it's will be freeze
|
||||
@@ -650,7 +644,7 @@ static void CL_CreateCmd( void )
|
||||
active = (( cls.signon == SIGNONS ) && !cl.paused && !cls.demoplayback );
|
||||
Platform_PreCreateMove();
|
||||
clgame.dllFuncs.CL_CreateMove( host.frametime, cmd, active );
|
||||
IN_EngineAppendMove( host.frametime, cmd, active );
|
||||
IN_EngineAppendMove( host.frametime, cmd, active );
|
||||
|
||||
CL_PopPMStates();
|
||||
|
||||
@@ -680,28 +674,26 @@ static void CL_CreateCmd( void )
|
||||
|
||||
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to )
|
||||
{
|
||||
const usercmd_t nullcmd = { 0 };
|
||||
const usercmd_t *f;
|
||||
usercmd_t *t;
|
||||
usercmd_t nullcmd;
|
||||
usercmd_t *f, *t;
|
||||
|
||||
Assert( from == -1 || ( from >= 0 && from < MULTIPLAYER_BACKUP ));
|
||||
Assert( to >= 0 && to < MULTIPLAYER_BACKUP );
|
||||
|
||||
if( from == -1 )
|
||||
{
|
||||
memset( &nullcmd, 0, sizeof( nullcmd ));
|
||||
f = &nullcmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = &cl.commands[from].cmd;
|
||||
}
|
||||
|
||||
t = &cl.commands[to].cmd;
|
||||
|
||||
// write it into the buffer
|
||||
if( cls.legacymode == PROTO_GOLDSRC )
|
||||
{
|
||||
MSG_StartBitWriting( msg );
|
||||
Delta_WriteGSFields( msg, DT_USERCMD_T, f, t, 0.0f );
|
||||
MSG_EndBitWriting( msg );
|
||||
}
|
||||
else MSG_WriteDeltaUsercmd( msg, f, t );
|
||||
MSG_WriteDeltaUsercmd( msg, f, t );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -718,8 +710,8 @@ static void CL_WritePacket( void )
|
||||
qboolean send_command = false;
|
||||
byte data[MAX_CMD_BUFFER];
|
||||
int i, from, to, key, size;
|
||||
int numbackup = 2, maxbackup;
|
||||
int numcmds, maxcmds;
|
||||
int numbackup = 2;
|
||||
int numcmds;
|
||||
int newcmds;
|
||||
int cmdnumber;
|
||||
|
||||
@@ -727,41 +719,24 @@ static void CL_WritePacket( void )
|
||||
if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
|
||||
return;
|
||||
|
||||
if( cls.state <= ca_validate )
|
||||
{
|
||||
Netchan_TransmitBits( &cls.netchan, 0, "" );
|
||||
return;
|
||||
}
|
||||
|
||||
CL_ComputePacketLoss ();
|
||||
|
||||
memset( data, 0, sizeof( data ));
|
||||
MSG_Init( &buf, "ClientData", data, sizeof( data ));
|
||||
|
||||
// Determine number of backup commands to send along
|
||||
switch( cls.legacymode )
|
||||
{
|
||||
case PROTO_GOLDSRC:
|
||||
maxbackup = MAX_GOLDSRC_BACKUP_CMDS;
|
||||
maxcmds = MAX_GOLDSRC_TOTAL_CMDS;
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
maxbackup = MAX_LEGACY_BACKUP_CMDS;
|
||||
maxcmds = MAX_LEGACY_TOTAL_CMDS;
|
||||
break;
|
||||
default:
|
||||
maxbackup = MAX_BACKUP_COMMANDS;
|
||||
maxcmds = MAX_TOTAL_CMDS;
|
||||
break;
|
||||
}
|
||||
|
||||
numbackup = bound( 0, cl_cmdbackup.value, maxbackup );
|
||||
numbackup = bound( 0, cl_cmdbackup.value, cls.legacymode ? MAX_LEGACY_BACKUP_CMDS : MAX_BACKUP_COMMANDS );
|
||||
if( cls.state == ca_connected ) numbackup = 0;
|
||||
|
||||
// clamp cmdrate
|
||||
if( cl_cmdrate.value < 10.0f )
|
||||
{
|
||||
Cvar_DirectSet( &cl_cmdrate, "10" );
|
||||
}
|
||||
else if( cl_cmdrate.value > 100.0f )
|
||||
{
|
||||
Cvar_DirectSet( &cl_cmdrate, "100" );
|
||||
}
|
||||
|
||||
// Check to see if we can actually send this command
|
||||
|
||||
@@ -817,15 +792,12 @@ static void CL_WritePacket( void )
|
||||
// begin a client move command
|
||||
MSG_BeginClientCmd( &buf, clc_move );
|
||||
|
||||
if( cls.legacymode == PROTO_GOLDSRC )
|
||||
MSG_WriteByte( &buf, 0 ); // length
|
||||
|
||||
// save the position for a checksum byte
|
||||
key = MSG_GetRealBytesWritten( &buf );
|
||||
MSG_WriteByte( &buf, 0 );
|
||||
|
||||
// write packet lossage percentation
|
||||
MSG_WriteByte( &buf, bound( 0, (int)cls.packet_loss, 100 ) );
|
||||
MSG_WriteByte( &buf, cls.packet_loss );
|
||||
|
||||
// say how many backups we'll be sending
|
||||
MSG_WriteByte( &buf, numbackup );
|
||||
@@ -834,10 +806,8 @@ static void CL_WritePacket( void )
|
||||
newcmds = ( cls.netchan.outgoing_sequence - cls.lastoutgoingcommand );
|
||||
|
||||
// put an upper/lower bound on this
|
||||
newcmds = bound( 0, newcmds, maxcmds );
|
||||
|
||||
if( cls.state == ca_connected )
|
||||
newcmds = 0;
|
||||
newcmds = bound( 0, newcmds, cls.legacymode ? MAX_LEGACY_TOTAL_CMDS: MAX_TOTAL_CMDS );
|
||||
if( cls.state == ca_connected ) newcmds = 0;
|
||||
|
||||
MSG_WriteByte( &buf, newcmds );
|
||||
|
||||
@@ -858,20 +828,8 @@ static void CL_WritePacket( void )
|
||||
}
|
||||
|
||||
// calculate a checksum over the move commands
|
||||
if( cls.legacymode == PROTO_GOLDSRC )
|
||||
{
|
||||
size = MSG_GetRealBytesWritten( &buf ) - key - 1;
|
||||
|
||||
buf.pData[key - 1] = Q_min( size, 255 );
|
||||
buf.pData[key] = CRC32_BlockSequence( buf.pData + key + 1, size, cls.netchan.outgoing_sequence );
|
||||
COM_Munge( buf.pData + key + 1, Q_min( size, 255 ), cls.netchan.outgoing_sequence );
|
||||
}
|
||||
else
|
||||
{
|
||||
size = MSG_GetRealBytesWritten( &buf ) - key - 1;
|
||||
|
||||
buf.pData[key] = CRC32_BlockSequence( buf.pData + key + 1, size, cls.netchan.outgoing_sequence );
|
||||
}
|
||||
size = MSG_GetRealBytesWritten( &buf ) - key - 1;
|
||||
buf.pData[key] = CRC32_BlockSequence( buf.pData + key + 1, size, cls.netchan.outgoing_sequence );
|
||||
|
||||
// message we are constructing.
|
||||
i = cls.netchan.outgoing_sequence & CL_UPDATE_MASK;
|
||||
@@ -1041,62 +999,6 @@ void CL_Drop( void )
|
||||
CL_Disconnect();
|
||||
}
|
||||
|
||||
static void CL_GetCDKey( char *protinfo, size_t protinfosize )
|
||||
{
|
||||
byte hash[16] = { 0 };
|
||||
MD5Context_t ctx = { 0 };
|
||||
char key[64];
|
||||
int keylength;
|
||||
|
||||
keylength = Q_snprintf( key, sizeof( key ), "%u", COM_RandomLong( 0, 0x7fffffff ));
|
||||
|
||||
MD5Init( &ctx );
|
||||
MD5Update( &ctx, key, keylength );
|
||||
MD5Final( hash, &ctx );
|
||||
|
||||
Q_strnlwr( MD5_Print( hash ), key, sizeof( key ));
|
||||
|
||||
Info_SetValueForKey( protinfo, "cdkey", key, protinfosize );
|
||||
}
|
||||
|
||||
#include "multi_emulator.h"
|
||||
static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" );
|
||||
|
||||
static size_t CL_GenerateSteamTicket( byte *buf, size_t size )
|
||||
{
|
||||
const char *s = ID_GetMD5();
|
||||
uint32_t crc;
|
||||
|
||||
CRC32_Init( &crc );
|
||||
CRC32_ProcessBuffer( &crc, s, Q_strlen( s ));
|
||||
crc = CRC32_Final( crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "revemu2013" ))
|
||||
return GenerateRevEmu2013( buf, crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "sc2009" ))
|
||||
return GenerateSC2009( buf, crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "oldrevemu" ))
|
||||
return GenerateOldRevEmu( buf, crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "steamemu" ))
|
||||
return GenerateSteamEmu( buf, crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "revemu" ))
|
||||
return GenerateRevEmu( buf, crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "setti" ))
|
||||
return GenerateSetti( buf );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "avsmp" ))
|
||||
return GenerateAVSMP( buf, crc, true );
|
||||
|
||||
Con_Printf( "%s: unknown generator %s, supported are: revemu2003, sc2009, oldrevemu, steamemu, revemu, setti, avsmp\n", __func__, cl_ticket_generator.string );
|
||||
memset( buf, 0, size );
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
CL_SendConnectPacket
|
||||
@@ -1136,68 +1038,18 @@ static void CL_SendConnectPacket( void )
|
||||
input_devices = IN_CollectInputDevices();
|
||||
IN_LockInputDevices( true );
|
||||
|
||||
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
|
||||
// it also doesn't need useragent string
|
||||
if( cls.legacymode != PROTO_GOLDSRC )
|
||||
{
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
|
||||
Info_SetValueForKeyf( protinfo, "d", sizeof( protinfo ), "%d", input_devices );
|
||||
Info_SetValueForKey( protinfo, "v", XASH_VERSION, sizeof( protinfo ) );
|
||||
Info_SetValueForKeyf( protinfo, "b", sizeof( protinfo ), "%d", Q_buildnum( ));
|
||||
Info_SetValueForKey( protinfo, "o", Q_buildos(), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "a", Q_buildarch(), sizeof( protinfo ) );
|
||||
}
|
||||
Info_SetValueForKeyf( protinfo, "d", sizeof( protinfo ), "%d", input_devices );
|
||||
Info_SetValueForKey( protinfo, "v", XASH_VERSION, sizeof( protinfo ) );
|
||||
Info_SetValueForKeyf( protinfo, "b", sizeof( protinfo ), "%d", Q_buildnum( ));
|
||||
Info_SetValueForKey( protinfo, "o", Q_buildos(), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "a", Q_buildarch(), sizeof( protinfo ) );
|
||||
}
|
||||
|
||||
if( cls.legacymode == PROTO_GOLDSRC )
|
||||
if( cls.legacymode )
|
||||
{
|
||||
byte send_buf[1024];
|
||||
byte steam_cert[512];
|
||||
string new_name;
|
||||
const char *name;
|
||||
size_t steam_cert_len;
|
||||
sizebuf_t send;
|
||||
|
||||
protinfo[0] = 0;
|
||||
|
||||
steam_cert_len = CL_GenerateSteamTicket( steam_cert, sizeof( steam_cert ));
|
||||
|
||||
Info_SetValueForKey( protinfo, "prot", "3", sizeof( protinfo )); // steam auth type
|
||||
Info_SetValueForKeyf( protinfo, "unique", sizeof( protinfo ), "%i", 0xffffffff );
|
||||
Info_SetValueForKey( protinfo, "raw", "steam", sizeof( protinfo ));
|
||||
CL_GetCDKey( protinfo, sizeof( protinfo ));
|
||||
|
||||
// remove keys set for legacy protocol
|
||||
Info_RemoveKey( cls.userinfo, "cl_maxpacket" );
|
||||
Info_RemoveKey( cls.userinfo, "cl_maxpayload" );
|
||||
|
||||
name = Info_ValueForKey( cls.userinfo, "name" );
|
||||
if( Q_strnicmp( name, "[Xash3D]", 8 ))
|
||||
{
|
||||
Q_snprintf( new_name, sizeof( new_name ), "[Xash3D]%s", name );
|
||||
Info_SetValueForKey( cls.userinfo, "name", new_name, sizeof( cls.userinfo ));
|
||||
}
|
||||
|
||||
MSG_Init( &send, "GoldSrcConnect", send_buf, sizeof( send_buf ));
|
||||
MSG_WriteLong( &send, NET_HEADER_OUTOFBANDPACKET );
|
||||
MSG_WriteStringf( &send, "connect %i %i \"%s\" \"%s\"\n",
|
||||
PROTOCOL_GOLDSRC_VERSION, cls.challenge, protinfo, cls.userinfo );
|
||||
MSG_SeekToBit( &send, -8, SEEK_CUR ); // rewrite null terminator
|
||||
MSG_WriteBytes( &send, steam_cert, steam_cert_len );
|
||||
|
||||
if( MSG_CheckOverflow( &send ))
|
||||
Con_Printf( S_ERROR "%s: %s overflow!\n", __func__, MSG_GetName( &send ) );
|
||||
|
||||
NET_SendPacket( NS_CLIENT, MSG_GetNumBytesWritten( &send ), MSG_GetData( &send ), adr );
|
||||
Con_Printf( "Trying to connect with GoldSrc 48 protocol\n" );
|
||||
}
|
||||
else if( cls.legacymode == PROTO_LEGACY )
|
||||
{
|
||||
// reset nickname from cvar value
|
||||
Info_SetValueForKey( cls.userinfo, "name", name.string, sizeof( cls.userinfo ));
|
||||
|
||||
// set related userinfo keys
|
||||
if( cl_dlmax.value >= 40000 || cl_dlmax.value < 100 )
|
||||
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", "1400", sizeof( cls.userinfo ) );
|
||||
@@ -1211,19 +1063,15 @@ static void CL_SendConnectPacket( void )
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i %i \"%s\" %d \"%s\"\n",
|
||||
PROTOCOL_LEGACY_VERSION, Q_atoi( qport ), cls.challenge, cls.userinfo, NET_LEGACY_EXT_SPLIT, protinfo );
|
||||
Con_Printf( "Trying to connect with legacy protocol\n" );
|
||||
Con_Printf( "Trying to connect by legacy protocol\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
int extensions = NET_EXT_SPLITSIZE;
|
||||
|
||||
// reset nickname from cvar value
|
||||
Info_SetValueForKey( cls.userinfo, "name", name.string, sizeof( cls.userinfo ));
|
||||
|
||||
if( cl_dlmax.value > FRAGMENT_MAX_SIZE || cl_dlmax.value < FRAGMENT_MIN_SIZE )
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
|
||||
|
||||
// remove keys set for legacy protocol
|
||||
Info_RemoveKey( cls.userinfo, "cl_maxpacket" );
|
||||
Info_RemoveKey( cls.userinfo, "cl_maxpayload" );
|
||||
|
||||
@@ -1232,7 +1080,7 @@ static void CL_SendConnectPacket( void )
|
||||
Info_SetValueForKeyf( protinfo, "ext", sizeof( protinfo ), "%d", extensions);
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i \"%s\" \"%s\"\n", PROTOCOL_VERSION, cls.challenge, protinfo, cls.userinfo );
|
||||
Con_Printf( "Trying to connect with modern protocol\n" );
|
||||
Con_Printf( "Trying to connect by modern protocol\n" );
|
||||
}
|
||||
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
@@ -1254,14 +1102,6 @@ static int CL_GetTestFragmentSize( void )
|
||||
return FRAGMENT_MIN_SIZE;
|
||||
}
|
||||
|
||||
static void CL_SendGetChallenge( netadr_t to, connprotocol_t proto )
|
||||
{
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, to, "getchallenge steam\n" );
|
||||
else
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, to, "getchallenge\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_CheckForResend
|
||||
@@ -1275,7 +1115,7 @@ static void CL_CheckForResend( void )
|
||||
net_gai_state_t res;
|
||||
float resendTime;
|
||||
qboolean bandwidthTest;
|
||||
|
||||
|
||||
if( cls.internetservers_wait )
|
||||
CL_SendMasterServerScanRequest();
|
||||
|
||||
@@ -1301,13 +1141,13 @@ static void CL_CheckForResend( void )
|
||||
else if( cl_resend.value > CL_MAX_RESEND_TIME )
|
||||
Cvar_SetValue( "cl_resend", CL_MAX_RESEND_TIME );
|
||||
|
||||
bandwidthTest = cls.legacymode == PROTO_CURRENT && cl_test_bandwidth.value && cls.connect_retry <= CL_TEST_RETRIES;
|
||||
bandwidthTest = !cls.legacymode && cl_test_bandwidth.value && cls.connect_retry <= CL_TEST_RETRIES;
|
||||
resendTime = bandwidthTest ? 1.0f : cl_resend.value;
|
||||
|
||||
if(( host.realtime - cls.connect_time ) < resendTime )
|
||||
return;
|
||||
|
||||
res = NET_StringToAdrNB( cls.servername, &adr, false );
|
||||
res = NET_StringToAdrNB( cls.servername, &adr );
|
||||
|
||||
if( res == NET_EAI_NONAME )
|
||||
{
|
||||
@@ -1336,7 +1176,7 @@ static void CL_CheckForResend( void )
|
||||
// too many fails use default connection method
|
||||
Con_Printf( "Bandwidth test failed, fallback to default connecting method\n" );
|
||||
Con_Printf( "Connecting to %s... (retry #%i)\n", cls.servername, cls.connect_retry + 1 );
|
||||
CL_SendGetChallenge( adr, cls.legacymode );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_MIN_SIZE );
|
||||
cls.connect_time = host.realtime;
|
||||
cls.connect_retry++;
|
||||
@@ -1356,7 +1196,7 @@ static void CL_CheckForResend( void )
|
||||
if( bandwidthTest )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "bandwidth %i %i\n", PROTOCOL_VERSION, cls.max_fragment_size );
|
||||
else
|
||||
CL_SendGetChallenge( adr, cls.legacymode );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
|
||||
}
|
||||
|
||||
static resource_t *CL_AddResource( resourcetype_t type, const char *name, int size, qboolean bFatalIfMissing, int index )
|
||||
@@ -1434,16 +1274,15 @@ static void CL_Connect_f( void )
|
||||
{
|
||||
const char *s = Cmd_Argv( 2 );
|
||||
|
||||
if( !Q_stricmp( s, "current" ) || !Q_strcmp( s, "49" ))
|
||||
if( !Q_strcmp( s, "current" ) || !Q_strcmp( s, "49" ))
|
||||
proto = PROTO_CURRENT;
|
||||
else if( !Q_stricmp( s, "legacy" ) || !Q_strcmp( s, "48" ))
|
||||
else if( !Q_strcmp( s, "legacy" ) || !Q_strcmp( s, "48" ))
|
||||
proto = PROTO_LEGACY;
|
||||
else if( !Q_stricmp( s, "goldsrc" ) || !Q_strcmp( s, "gs" ))
|
||||
proto = PROTO_GOLDSRC;
|
||||
else
|
||||
{
|
||||
// quake protocol only used for demos
|
||||
Con_Printf( "Unknown protocol. Supported are: 49 (current), 48 (legacy), gs (goldsrc)\n" );
|
||||
// goldsrc protocol is not supported yet
|
||||
Con_Printf( "Unknown protocol. Supported are: current, legacy\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1591,7 +1430,7 @@ CL_SendDisconnectMessage
|
||||
Sends a disconnect message to the server
|
||||
=====================
|
||||
*/
|
||||
static void CL_SendDisconnectMessage( connprotocol_t proto )
|
||||
static void CL_SendDisconnectMessage( void )
|
||||
{
|
||||
sizebuf_t buf;
|
||||
byte data[32];
|
||||
@@ -1600,9 +1439,7 @@ static void CL_SendDisconnectMessage( connprotocol_t proto )
|
||||
|
||||
MSG_Init( &buf, "LastMessage", data, sizeof( data ));
|
||||
MSG_BeginClientCmd( &buf, clc_stringcmd );
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
MSG_WriteString( &buf, "dropclient\n" );
|
||||
else MSG_WriteString( &buf, "disconnect" );
|
||||
MSG_WriteString( &buf, "disconnect" );
|
||||
|
||||
if( !cls.netchan.remote_address.type )
|
||||
cls.netchan.remote_address.type = NA_LOOPBACK;
|
||||
@@ -1640,29 +1477,29 @@ static void CL_Reconnect( qboolean setup_netchan )
|
||||
{
|
||||
if( setup_netchan )
|
||||
{
|
||||
uint flags = 0;
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
switch( cls.legacymode )
|
||||
if( cls.legacymode )
|
||||
{
|
||||
case PROTO_GOLDSRC:
|
||||
SetBits( flags, NETCHAN_USE_MUNGE | NETCHAN_USE_BZIP2 | NETCHAN_GOLDSRC );
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
if( FBitSet( Q_atoi( Cmd_Argv( 1 )), NET_LEGACY_EXT_SPLIT ))
|
||||
unsigned int extensions = Q_atoi( Cmd_Argv( 1 ) );
|
||||
|
||||
if( extensions & NET_LEGACY_EXT_SPLIT )
|
||||
{
|
||||
SetBits( flags, NETCHAN_USE_LEGACY_SPLIT );
|
||||
// only enable incoming split for legacy mode
|
||||
cls.netchan.split = true;
|
||||
Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax.value, 65536 );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
cls.extensions = Q_atoi( Info_ValueForKey( Cmd_Argv( 1 ), "ext" ));
|
||||
|
||||
if( FBitSet( cls.extensions, NET_EXT_SPLITSIZE ))
|
||||
if( cls.extensions & NET_EXT_SPLITSIZE )
|
||||
{
|
||||
Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax.value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize, flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1697,6 +1534,8 @@ This is also called on Host_Error, so it shouldn't cause any errors
|
||||
*/
|
||||
void CL_Disconnect( void )
|
||||
{
|
||||
cls.legacymode = PROTO_CURRENT;
|
||||
|
||||
if( cls.state == ca_disconnected )
|
||||
return;
|
||||
|
||||
@@ -1707,7 +1546,7 @@ void CL_Disconnect( void )
|
||||
CL_Stop_f();
|
||||
|
||||
// send a disconnect message to the server
|
||||
CL_SendDisconnectMessage( cls.legacymode );
|
||||
CL_SendDisconnectMessage();
|
||||
CL_ClearState ();
|
||||
|
||||
S_StopBackgroundTrack ();
|
||||
@@ -1723,7 +1562,6 @@ void CL_Disconnect( void )
|
||||
cls.set_lastdemo = false;
|
||||
cls.connect_retry = 0;
|
||||
cls.signon = 0;
|
||||
cls.legacymode = PROTO_CURRENT;
|
||||
|
||||
// back to menu in non-developer mode
|
||||
if( host_developer.value || cls.key_dest == key_menu )
|
||||
@@ -1751,7 +1589,7 @@ void CL_Crashed( void )
|
||||
CL_Stop_f(); // stop any demos
|
||||
|
||||
// send a disconnect message to the server
|
||||
CL_SendDisconnectMessage( cls.legacymode );
|
||||
CL_SendDisconnectMessage();
|
||||
|
||||
Host_WriteOpenGLConfig();
|
||||
Host_WriteConfig(); // write config
|
||||
@@ -1815,7 +1653,7 @@ static size_t NONNULL CL_BuildMasterServerScanRequest( char *buf, size_t size, u
|
||||
|
||||
Q_snprintf( temp, sizeof( temp ), "%d", Q_buildnum() );
|
||||
Info_SetValueForKey( info, "buildnum", temp, remaining );
|
||||
|
||||
|
||||
Q_snprintf( temp, sizeof( temp ), "%x", *key );
|
||||
Info_SetValueForKey( info, "key", temp, remaining );
|
||||
|
||||
@@ -2209,7 +2047,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
Con_Reportf( "%s: %s : %s\n", __func__, NET_AdrToString( from ), c );
|
||||
|
||||
// server connection
|
||||
if( !Q_strcmp( c, "client_connect" ) || !Q_strcmp( c, S2C_CONNECTION ))
|
||||
if( !Q_strcmp( c, "client_connect" ))
|
||||
{
|
||||
if( !CL_IsFromConnectingServer( from ))
|
||||
return;
|
||||
@@ -2249,14 +2087,6 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
Cbuf_AddText( args );
|
||||
Cbuf_AddText( "\n" );
|
||||
}
|
||||
else if( c[0] == 'l' )
|
||||
{
|
||||
char *s = args + 1;
|
||||
|
||||
Con_Printf( S_CYAN "r:" S_DEFAULT " %s", s );
|
||||
if( !COM_CheckStringEmpty( s ) || s[Q_strlen( s ) - 1] != '\n' )
|
||||
Con_Printf( "\n" );
|
||||
}
|
||||
else if( !Q_strcmp( c, "print" ))
|
||||
{
|
||||
// print command from somewhere
|
||||
@@ -2290,7 +2120,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
// too many fails use default connection method
|
||||
Con_Printf( "hi-speed connection is failed, use default method\n" );
|
||||
CL_SendGetChallenge( from, cls.legacymode );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
|
||||
cls.connect_time = host.realtime;
|
||||
return;
|
||||
@@ -2312,7 +2142,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
// packet was sucessfully delivered, adjust the fragment size and get challenge
|
||||
|
||||
Con_DPrintf( "CRC %x is matched, get challenge, fragment size %d\n", crcValue, cls.max_fragment_size );
|
||||
CL_SendGetChallenge( from, cls.legacymode );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", cls.max_fragment_size );
|
||||
cls.connect_time = host.realtime;
|
||||
}
|
||||
@@ -2322,7 +2152,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
// too many fails use default connection method
|
||||
Con_Printf( "hi-speed connection is failed, use default method\n" );
|
||||
CL_SendGetChallenge( from, cls.legacymode );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_MIN_SIZE );
|
||||
cls.connect_time = host.realtime;
|
||||
return;
|
||||
@@ -2339,7 +2169,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
// ping from somewhere
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "ack" );
|
||||
}
|
||||
else if( !Q_strcmp( c, "challenge" ) || !Q_strcmp( c, S2C_CHALLENGE ))
|
||||
else if( !Q_strcmp( c, "challenge" ))
|
||||
{
|
||||
// this message only used during connection
|
||||
// it doesn't make sense after client_connect
|
||||
@@ -2376,7 +2206,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
// dropped the connection but it is still getting packets from us
|
||||
CL_Disconnect_f();
|
||||
}
|
||||
else if( !Q_strcmp( c, "errormsg" ) || c[0] == S2C_REJECT || c[0] == S2C_REJECT_BADPASSWORD )
|
||||
else if( !Q_strcmp( c, "errormsg" ))
|
||||
{
|
||||
char formatted_msg[MAX_VA_STRING];
|
||||
|
||||
@@ -2384,16 +2214,12 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
return;
|
||||
|
||||
args = MSG_ReadString( msg );
|
||||
if( c[0] == S2C_REJECT || c[0] == S2C_REJECT_BADPASSWORD )
|
||||
args++; // skip one byte
|
||||
|
||||
Q_snprintf( formatted_msg, sizeof( formatted_msg ), "^3Server message^7\n%s", args );
|
||||
|
||||
// in case we're in console or it's classic mainui which doesn't support messageboxes
|
||||
if( !UI_IsVisible() || !UI_ShowMessageBox( formatted_msg ))
|
||||
Msg( "%s\n", formatted_msg );
|
||||
|
||||
CL_Disconnect_f();
|
||||
}
|
||||
else if( !Q_strcmp( c, "updatemsg" ))
|
||||
{
|
||||
@@ -2552,8 +2378,6 @@ static void CL_ReadNetMessage( void )
|
||||
parsefn = CL_ParseQuakeMessage;
|
||||
break;
|
||||
case PROTO_GOLDSRC:
|
||||
parsefn = CL_ParseGoldSrcServerMessage;
|
||||
break;
|
||||
default:
|
||||
ASSERT( 0 );
|
||||
return;
|
||||
@@ -2785,11 +2609,10 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
Con_Printf( S_ERROR "server failed to transmit file '%s'\n", CL_CleanFileName( filename ));
|
||||
}
|
||||
|
||||
if( cls.legacymode == PROTO_LEGACY )
|
||||
if( cls.legacymode )
|
||||
{
|
||||
if( host.downloadcount > 0 )
|
||||
host.downloadcount--;
|
||||
|
||||
if( !host.downloadcount )
|
||||
{
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
@@ -2874,7 +2697,7 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
MSG_Init( &msg, "Resource Registration", msg_buf, sizeof( msg_buf ));
|
||||
|
||||
if( CL_PrecacheResources( ))
|
||||
CL_RegisterResources( &msg, cls.legacymode );
|
||||
CL_RegisterResources( &msg );
|
||||
|
||||
if( MSG_GetNumBytesWritten( &msg ) > 0 )
|
||||
{
|
||||
@@ -2934,26 +2757,17 @@ tell server about changed userinfo
|
||||
*/
|
||||
void CL_UpdateInfo( const char *key, const char *value )
|
||||
{
|
||||
switch( cls.legacymode )
|
||||
if( !cls.legacymode )
|
||||
{
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", key, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
case PROTO_LEGACY:
|
||||
if( cls.state != ca_active )
|
||||
break;
|
||||
return;
|
||||
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
|
||||
MSG_WriteString( &cls.netchan.message, cls.userinfo );
|
||||
break;
|
||||
case PROTO_GOLDSRC:
|
||||
if( !Q_stricmp( key, "name" ) && Q_strnicmp( value, "[Xash3D]", 8 ))
|
||||
{
|
||||
// always prepend [Xash3D] on GoldSrc protocol :)
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"[Xash3D]%s\"\n", key, value );
|
||||
break;
|
||||
}
|
||||
// intentional fallthrough
|
||||
default:
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", key, value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3232,9 +3046,6 @@ static void CL_InitLocal( void )
|
||||
cl.resourcesneeded.pNext = cl.resourcesneeded.pPrev = &cl.resourcesneeded;
|
||||
cl.resourcesonhand.pNext = cl.resourcesonhand.pPrev = &cl.resourcesonhand;
|
||||
|
||||
Cvar_RegisterVariable( &cl_ticket_generator );
|
||||
|
||||
Cvar_RegisterVariable( &showpause );
|
||||
Cvar_RegisterVariable( &mp_decals );
|
||||
Cvar_RegisterVariable( &dev_overview );
|
||||
Cvar_RegisterVariable( &cl_resend );
|
||||
|
||||
@@ -63,9 +63,9 @@ static byte netcolors[NETGRAPH_NET_COLORS+NETGRAPH_LERP_HEIGHT][4] =
|
||||
// other will be generated through NetGraph_InitColors()
|
||||
};
|
||||
|
||||
static const byte sendcolor[4] = { 88, 29, 130, 255 };
|
||||
static const byte holdcolor[4] = { 255, 0, 0, 200 };
|
||||
static const byte extrap_base_color[4] = { 255, 255, 255, 255 };
|
||||
static byte sendcolor[4] = { 88, 29, 130, 255 };
|
||||
static byte holdcolor[4] = { 255, 0, 0, 200 };
|
||||
static byte extrap_base_color[4] = { 255, 255, 255, 255 };
|
||||
static netbandwidthgraph_t netstat_graph[NET_TIMINGS];
|
||||
static float packet_loss;
|
||||
static float packet_choke;
|
||||
@@ -79,7 +79,7 @@ NetGraph_DrawRect
|
||||
NetGraph_FillRGBA shortcut
|
||||
==========
|
||||
*/
|
||||
static void NetGraph_DrawRect( const wrect_t *rect, const byte colors[4] )
|
||||
static void NetGraph_DrawRect( wrect_t *rect, byte colors[4] )
|
||||
{
|
||||
ref.dllFuncs.Color4ub( colors[0], colors[1], colors[2], colors[3] ); // color for this quad
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,7 +137,12 @@ static void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
|
||||
//if( FBitSet( flags, SND_SEQUENCE ))
|
||||
//Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
|
||||
//else
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
@@ -315,7 +320,7 @@ dispatch messages
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd;
|
||||
int cmd, param1, param2;
|
||||
int old_background;
|
||||
const char *s;
|
||||
|
||||
@@ -340,9 +345,6 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonDLLMessage( msg, PROTO_LEGACY, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
@@ -357,7 +359,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
Host_AbortCurrentFrame ();
|
||||
break;
|
||||
case svc_legacy_event:
|
||||
CL_ParseEvent( msg, PROTO_LEGACY );
|
||||
CL_ParseEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_legacy_changing:
|
||||
@@ -419,7 +421,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
|
||||
break;
|
||||
case svc_time:
|
||||
CL_ParseServerTime( msg, PROTO_LEGACY );
|
||||
CL_ParseServerTime( msg );
|
||||
break;
|
||||
case svc_print:
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
@@ -444,19 +446,19 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, PROTO_LEGACY );
|
||||
CL_ParseServerData( msg, true );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_LEGACY );
|
||||
CL_ParseLightStyle( msg );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, PROTO_LEGACY );
|
||||
CL_UpdateUserinfo( msg, true );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
break;
|
||||
case svc_clientdata:
|
||||
CL_ParseClientData( msg, PROTO_LEGACY );
|
||||
CL_ParseClientData( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_resource:
|
||||
@@ -466,58 +468,82 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
CL_UpdateUserPings( msg );
|
||||
break;
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg, PROTO_LEGACY );
|
||||
CL_ParseParticles( msg );
|
||||
break;
|
||||
case svc_restoresound:
|
||||
Con_Printf( S_ERROR "%s: svc_restoresound: implement me!\n", __func__ );
|
||||
CL_ParseRestoreSoundPacket( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_LegacyParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
CL_ParseReliableEvent( msg, PROTO_LEGACY );
|
||||
CL_ParseReliableEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
CL_ParseBaseline( msg, PROTO_LEGACY );
|
||||
CL_ParseBaseline( msg, true );
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
CL_ParseTempEntity( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_setpause:
|
||||
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
|
||||
break;
|
||||
case svc_signonnum:
|
||||
CL_ParseSignon( msg, PROTO_LEGACY );
|
||||
CL_ParseSignon( msg );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_intermission:
|
||||
cl.intermission = 1;
|
||||
break;
|
||||
case svc_legacy_modelindex:
|
||||
CL_LegacyPrecacheModel( msg );
|
||||
break;
|
||||
case svc_legacy_soundindex:
|
||||
CL_LegacyPrecacheSound( msg );
|
||||
break;
|
||||
case svc_cdtrack:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
|
||||
param2 = MSG_ReadByte( msg );
|
||||
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
|
||||
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
|
||||
break;
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_legacy_eventindex:
|
||||
CL_LegacyPrecacheEvent(msg);
|
||||
break;
|
||||
case svc_weaponanim:
|
||||
param1 = MSG_ReadByte( msg ); // iAnim
|
||||
param2 = MSG_ReadByte( msg ); // body
|
||||
CL_WeaponAnim( param1, param2 );
|
||||
break;
|
||||
case svc_bspdecal:
|
||||
CL_ParseStaticDecal( msg );
|
||||
break;
|
||||
case svc_roomtype:
|
||||
param1 = MSG_ReadShort( msg );
|
||||
Cvar_SetValue( "room_type", param1 );
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_usermessage:
|
||||
CL_RegisterUserMessage( msg, PROTO_LEGACY );
|
||||
CL_RegisterUserMessage( msg );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, false, PROTO_LEGACY );
|
||||
playerbytes = CL_ParsePacketEntities( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, true, PROTO_LEGACY );
|
||||
playerbytes = CL_ParsePacketEntities( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
@@ -564,6 +590,9 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_director:
|
||||
CL_ParseDirector( msg );
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
@@ -574,7 +603,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
CL_ParseCvarValue( msg, true, PROTO_LEGACY );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||
CL_ParseUserMessage( msg, cmd );
|
||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
}
|
||||
@@ -586,7 +615,7 @@ void CL_LegacyPrecache_f( void )
|
||||
int spawncount, i;
|
||||
model_t *mod;
|
||||
|
||||
if( cls.legacymode != PROTO_LEGACY )
|
||||
if( !cls.legacymode )
|
||||
return;
|
||||
|
||||
spawncount = Q_atoi( Cmd_Argv( 1 ));
|
||||
@@ -629,3 +658,8 @@ void CL_LegacyPrecache_f( void )
|
||||
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
|
||||
cls.signon = SIGNONS - 1;
|
||||
}
|
||||
|
||||
qboolean CL_LegacyMode( void )
|
||||
{
|
||||
return cls.legacymode == PROTO_LEGACY;
|
||||
}
|
||||
|
||||
@@ -1,762 +0,0 @@
|
||||
/*
|
||||
cl_parse.c - parse a message received from the server (GoldSrc 48 protocol)
|
||||
Copyright (C) 2008 Uncle Mike
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
#include "server.h"
|
||||
|
||||
static void CL_ParseExtraInfo( sizebuf_t *msg )
|
||||
{
|
||||
string clientfallback;
|
||||
|
||||
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
|
||||
if( COM_CheckStringEmpty( clientfallback ))
|
||||
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__ );
|
||||
|
||||
if( MSG_ReadByte( msg ))
|
||||
{
|
||||
Cvar_FullSet( "sv_cheats", "1", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
{
|
||||
Delta_InitClient(); // finalize client delta's
|
||||
|
||||
clgame.movevars.gravity = MSG_ReadFloat( msg );
|
||||
clgame.movevars.stopspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.maxspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.spectatormaxspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.accelerate = MSG_ReadFloat( msg );
|
||||
clgame.movevars.airaccelerate = MSG_ReadFloat( msg );
|
||||
clgame.movevars.wateraccelerate = MSG_ReadFloat( msg );
|
||||
clgame.movevars.friction = MSG_ReadFloat( msg );
|
||||
clgame.movevars.edgefriction = MSG_ReadFloat( msg );
|
||||
clgame.movevars.waterfriction = MSG_ReadFloat( msg );
|
||||
clgame.movevars.entgravity = MSG_ReadFloat( msg );
|
||||
clgame.movevars.bounce = MSG_ReadFloat( msg );
|
||||
clgame.movevars.stepsize = MSG_ReadFloat( msg );
|
||||
clgame.movevars.maxvelocity = MSG_ReadFloat( msg );
|
||||
clgame.movevars.zmax = MSG_ReadFloat( msg );
|
||||
clgame.movevars.waveHeight = MSG_ReadFloat( msg );
|
||||
clgame.movevars.footsteps = MSG_ReadByte( msg );
|
||||
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
||||
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_r = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_g = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_b = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_x = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_y = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_z = MSG_ReadFloat( msg );
|
||||
|
||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||
|
||||
// water alpha is not allowed
|
||||
if( !FBitSet( world.flags, FWORLD_WATERALPHA ))
|
||||
clgame.movevars.wateralpha = 1.0f;
|
||||
|
||||
// update sky if changed
|
||||
if( Q_strcmp( clgame.oldmovevars.skyName, clgame.movevars.skyName ) && cl.video_prepped )
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
clgame.oldmovevars = clgame.movevars;
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
|
||||
// keep features an actual!
|
||||
clgame.oldmovevars.features = clgame.movevars.features = host.features;
|
||||
}
|
||||
|
||||
typedef struct delta_header_t
|
||||
{
|
||||
qboolean remove : 1;
|
||||
qboolean custom : 1;
|
||||
qboolean instanced : 1;
|
||||
uint instanced_baseline_index : 6;
|
||||
uint offset : 6;
|
||||
} delta_header_t;
|
||||
|
||||
static int CL_ParseDeltaHeader( sizebuf_t *msg, qboolean delta, int oldnum, struct delta_header_t *hdr )
|
||||
{
|
||||
int entnum = oldnum;
|
||||
memset( hdr, 0, sizeof( *hdr ));
|
||||
|
||||
if( !delta )
|
||||
{
|
||||
// if we have one bit set, then it's a next entity in line
|
||||
// if we have next bit NON set, then it's a one of next 64 entities
|
||||
// if not, it's a new entity
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
entnum++;
|
||||
else if( MSG_ReadOneBit( msg ) == 0 )
|
||||
entnum += MSG_ReadUBitLong( msg, 6 );
|
||||
else
|
||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
}
|
||||
else
|
||||
{
|
||||
// does this packet encode entity deletion?
|
||||
hdr->remove = MSG_ReadOneBit( msg );
|
||||
|
||||
// same logic as above
|
||||
if( MSG_ReadOneBit( msg ) == 0 )
|
||||
entnum += MSG_ReadUBitLong( msg, 6 );
|
||||
else entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
}
|
||||
|
||||
// if we are not removing this entity
|
||||
if( !hdr->remove )
|
||||
{
|
||||
hdr->custom = MSG_ReadOneBit( msg );
|
||||
|
||||
// do we got instanced baselines in svc_spawnbaselines?
|
||||
if( cl.instanced_baseline_count )
|
||||
{
|
||||
hdr->instanced = MSG_ReadOneBit( msg );
|
||||
if( hdr->instanced )
|
||||
hdr->instanced_baseline_index = MSG_ReadUBitLong( msg, 6 );
|
||||
}
|
||||
|
||||
if( !delta && !hdr->instanced )
|
||||
{
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
hdr->offset = MSG_ReadUBitLong( msg, 6 );
|
||||
}
|
||||
}
|
||||
|
||||
return entnum;
|
||||
}
|
||||
|
||||
static int CL_GetEntityDelta( const struct delta_header_t *hdr, int entnum )
|
||||
{
|
||||
if( hdr->custom )
|
||||
return DT_CUSTOM_ENTITY_STATE_T;
|
||||
|
||||
if( CL_IsPlayerIndex( entnum ))
|
||||
return DT_ENTITY_STATE_PLAYER_T;
|
||||
|
||||
return DT_ENTITY_STATE_T;
|
||||
}
|
||||
|
||||
static void CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
|
||||
{
|
||||
frame->valid = false;
|
||||
cl.validsequence = 0; // can't render a frame
|
||||
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int num = 0;
|
||||
entity_state_t from = { 0 }, to;
|
||||
delta_header_t hdr;
|
||||
|
||||
if( MSG_ReadWord( msg ) != 0 )
|
||||
{
|
||||
MSG_SeekToBit( msg, -16, SEEK_CUR );
|
||||
num = CL_ParseDeltaHeader( msg, false, num, &hdr );
|
||||
}
|
||||
else break;
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
if( hdr.remove )
|
||||
continue;
|
||||
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, num ), &from, &to, cl.mtime[0] );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t *frame, int newnum, const entity_state_t *from )
|
||||
{
|
||||
cl_entity_t *ent;
|
||||
entity_state_t *to;
|
||||
qboolean newent = from == NULL;
|
||||
int pack = frame->num_entities;
|
||||
qboolean has_update = msg != NULL;
|
||||
|
||||
// alloc next slot to store update
|
||||
to = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
||||
|
||||
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
Host_Error( "%s: bad delta entity number: %i", __func__, newnum );
|
||||
return;
|
||||
}
|
||||
|
||||
ent = CL_EDICT_NUM( newnum );
|
||||
if( hdr->remove )
|
||||
{
|
||||
if( !newent )
|
||||
CL_KillDeadBeams( ent );
|
||||
else
|
||||
Con_Printf( S_WARN "%s: entity remove on non-delta update (%d)\n", __func__, newnum );
|
||||
return;
|
||||
}
|
||||
|
||||
ent->index = newnum; // enumerate entity index
|
||||
if( newent )
|
||||
{
|
||||
if( hdr->instanced )
|
||||
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
||||
else if( hdr->offset != 0 )
|
||||
from = &cls.packet_entities[(cls.next_client_entities - hdr->offset) % cls.num_client_entities];
|
||||
else
|
||||
from = &ent->baseline;
|
||||
}
|
||||
|
||||
if( has_update )
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( hdr, newnum ), from, to, cl.mtime[0] );
|
||||
else memcpy( to, from, sizeof( entity_state_t ));
|
||||
|
||||
to->entityType = hdr->custom ? ENTITY_BEAM : ENTITY_NORMAL;
|
||||
to->number = newnum;
|
||||
|
||||
if( newent )
|
||||
{
|
||||
// interpolation must be reset
|
||||
SETVISBIT( frame->flags, pack );
|
||||
|
||||
// release beams from previous entity
|
||||
CL_KillDeadBeams( ent );
|
||||
}
|
||||
|
||||
// add entity to packet
|
||||
cls.next_client_entities++;
|
||||
frame->num_entities++;
|
||||
}
|
||||
|
||||
static void CL_CopyPacketEntity( frame_t *frame, int num, const entity_state_t *from )
|
||||
{
|
||||
delta_header_t fakehdr =
|
||||
{
|
||||
.custom = FBitSet( from->entityType, ENTITY_BEAM ) == ENTITY_BEAM,
|
||||
};
|
||||
CL_DeltaEntityGS( &fakehdr, NULL, frame, num, from );
|
||||
}
|
||||
|
||||
static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
|
||||
{
|
||||
frame_t *frame, *oldframe;
|
||||
int oldindex, newnum, oldnum, numbase = 0;
|
||||
entity_state_t *oldent;
|
||||
int count;
|
||||
int playerbytes = 0;
|
||||
|
||||
// save first uncompressed packet as timestamp
|
||||
if( cls.changelevel && !delta && cls.demorecording )
|
||||
CL_WriteDemoJumpTime();
|
||||
|
||||
count = MSG_ReadWord( msg );
|
||||
|
||||
frame = &cl.frames[cl.parsecountmod];
|
||||
memset( frame->flags, 0, sizeof( frame->flags ));
|
||||
frame->first_entity = cls.next_client_entities;
|
||||
frame->num_entities = 0;
|
||||
frame->valid = true;
|
||||
|
||||
if( delta )
|
||||
{
|
||||
uint oldpacket = MSG_ReadByte( msg );
|
||||
oldframe = &cl.frames[oldpacket & CL_UPDATE_MASK];
|
||||
|
||||
if( !CL_ValidateDeltaPacket( oldpacket, oldframe ))
|
||||
{
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_FlushEntityPacketGS( frame, msg );
|
||||
MSG_EndBitWriting( msg );
|
||||
return playerbytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oldframe = NULL;
|
||||
cl.send_reply = true;
|
||||
cls.demowaiting = false;
|
||||
}
|
||||
|
||||
cl.validsequence = cls.netchan.incoming_sequence;
|
||||
|
||||
MSG_StartBitWriting( msg );
|
||||
|
||||
oldent = NULL;
|
||||
oldindex = 0;
|
||||
oldnum = CL_UpdateOldEntNum( oldindex, oldframe, &oldent );
|
||||
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int bufstart;
|
||||
qboolean player;
|
||||
delta_header_t hdr;
|
||||
int val = MSG_ReadWord( msg );
|
||||
|
||||
if( val )
|
||||
{
|
||||
MSG_SeekToBit( msg, -16, SEEK_CUR );
|
||||
numbase = newnum = CL_ParseDeltaHeader( msg, delta, numbase, &hdr );
|
||||
}
|
||||
else break;
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
while( oldnum < newnum )
|
||||
{
|
||||
if( !delta )
|
||||
Con_Printf( S_WARN "%s: old frame copy on non-delta update (%d < %d)\n", __func__, oldnum, newnum );
|
||||
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_CopyPacketEntity( frame, oldnum, oldent );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
}
|
||||
|
||||
bufstart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
if( oldnum == newnum )
|
||||
{
|
||||
if( !delta )
|
||||
Con_Printf( S_WARN "%s: delta entity on non-delta update (%d)\n", __func__, oldnum );
|
||||
|
||||
// from delta
|
||||
CL_DeltaEntityGS( &hdr, msg, frame, newnum, oldent );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
}
|
||||
else if( oldnum > newnum )
|
||||
{
|
||||
// from baseline
|
||||
CL_DeltaEntityGS( &hdr, msg, frame, newnum, NULL );
|
||||
}
|
||||
|
||||
if( player ) playerbytes += MSG_GetNumBytesRead( msg ) - bufstart;
|
||||
}
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
// any remaining entities in the old frame are copied over
|
||||
while( oldnum != MAX_ENTNUMBER )
|
||||
{
|
||||
// one or more entities from the old packet are unchanged
|
||||
CL_CopyPacketEntity( frame, oldnum, oldent );
|
||||
oldnum = CL_UpdateOldEntNum( ++oldindex, oldframe, &oldent );
|
||||
}
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
|
||||
if( frame->num_entities != count )
|
||||
Con_Reportf( S_WARN "CL_Parse%sPacketEntitiesGS: (%i should be %i)\n", delta ? "Delta" : "", frame->num_entities, count );
|
||||
|
||||
if( !frame->valid )
|
||||
return playerbytes;
|
||||
|
||||
CL_ProcessPacket( frame );
|
||||
CL_SetSolidEntities();
|
||||
|
||||
// first update, received world, remove loading plaque
|
||||
if( cls.signon == ( SIGNONS - 1 ))
|
||||
{
|
||||
cls.signon = SIGNONS;
|
||||
CL_SignonReply( PROTO_GOLDSRC );
|
||||
}
|
||||
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
static float MSG_ReadGSBitCoord( sizebuf_t *sb )
|
||||
{
|
||||
float value = 0;
|
||||
int ival, fval;
|
||||
|
||||
ival = MSG_ReadOneBit( sb );
|
||||
fval = MSG_ReadOneBit( sb );
|
||||
|
||||
if( ival || fval )
|
||||
{
|
||||
int sign = MSG_ReadOneBit( sb );
|
||||
|
||||
if( ival )
|
||||
ival = MSG_ReadUBitLong( sb, 12 );
|
||||
if( fval )
|
||||
fval = MSG_ReadUBitLong( sb, 3 );
|
||||
|
||||
value = (float)( fval / 8.0 + ival );
|
||||
if( sign )
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void MSG_ReadGSBitVec3Coord( sizebuf_t *sb, vec3_t fa )
|
||||
{
|
||||
qboolean x, y, z;
|
||||
|
||||
VectorClear( fa );
|
||||
|
||||
x = MSG_ReadOneBit( sb );
|
||||
y = MSG_ReadOneBit( sb );
|
||||
z = MSG_ReadOneBit( sb );
|
||||
if( x )
|
||||
fa[0] = MSG_ReadGSBitCoord( sb );
|
||||
if( y )
|
||||
fa[1] = MSG_ReadGSBitCoord( sb );
|
||||
if( z )
|
||||
fa[2] = MSG_ReadGSBitCoord( sb );
|
||||
}
|
||||
|
||||
static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int chan, sound;
|
||||
float volume, attn;
|
||||
int flags, pitch, entnum;
|
||||
sound_t handle = 0;
|
||||
|
||||
MSG_StartBitWriting( msg );
|
||||
|
||||
flags = MSG_ReadUBitLong( msg, 9 );
|
||||
|
||||
if( FBitSet( flags, SND_VOLUME ))
|
||||
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
else volume = VOL_NORM;
|
||||
|
||||
if( FBitSet( flags, SND_ATTENUATION ))
|
||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
|
||||
chan = MSG_ReadUBitLong( msg, 3 );
|
||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
if( FBitSet( flags, SND_LEGACY_LARGE_INDEX ))
|
||||
sound = MSG_ReadWord( msg );
|
||||
else sound = MSG_ReadByte( msg );
|
||||
MSG_ReadGSBitVec3Coord( msg, pos );
|
||||
|
||||
if( FBitSet( flags, SND_PITCH ))
|
||||
pitch = MSG_ReadByte( msg );
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
|
||||
ClearBits( flags, SND_LEGACY_LARGE_INDEX );
|
||||
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
|
||||
if( !cl.audio_prepped )
|
||||
return; // too early
|
||||
|
||||
// g-cont. sound and ambient sound have only difference with channel
|
||||
if( chan == CHAN_STATIC )
|
||||
{
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_ParseSpawnStaticSound( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int handle, entnum, pitch, flags;
|
||||
float volume, attn;
|
||||
|
||||
MSG_ReadVec3Coord( msg, pos );
|
||||
handle = MSG_ReadShort( msg );
|
||||
volume = MSG_ReadByte( msg ) * ( 1.0f / 255.0f );
|
||||
attn = MSG_ReadByte( msg ) * ( 1.0f / 64.0f );
|
||||
entnum = MSG_ReadShort( msg );
|
||||
pitch = MSG_ReadByte( msg );
|
||||
flags = MSG_ReadByte( msg );
|
||||
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
ACTION MESSAGES
|
||||
|
||||
=====================================================================
|
||||
*/
|
||||
/*
|
||||
=====================
|
||||
CL_ParseGoldSrcServerMessage
|
||||
|
||||
dispatch messages
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd, param1;
|
||||
const char *s;
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: overflow!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark start position
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
// end of message (align bits)
|
||||
if( MSG_GetNumBitsLeft( msg ) < 8 )
|
||||
break;
|
||||
|
||||
cmd = MSG_ReadServerCmd( msg );
|
||||
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonDLLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
case svc_bad:
|
||||
Host_Error( "svc_bad\n" );
|
||||
break;
|
||||
case svc_nop:
|
||||
case svc_spawnstatic:
|
||||
case svc_goldsrc_damage:
|
||||
case svc_goldsrc_killedmonster:
|
||||
case svc_goldsrc_foundsecret:
|
||||
// this does nothing
|
||||
break;
|
||||
case svc_disconnect:
|
||||
s = MSG_ReadString( msg );
|
||||
if( COM_CheckStringEmpty( s ))
|
||||
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
||||
CL_Drop ();
|
||||
Host_AbortCurrentFrame ();
|
||||
break;
|
||||
case svc_event:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseEvent( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_goldsrc_version:
|
||||
param1 = MSG_ReadLong( msg );
|
||||
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
||||
break;
|
||||
case svc_setview:
|
||||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
CL_ParseSoundPacketGS( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_time:
|
||||
CL_ParseServerTime( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_print:
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
break;
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
if( cl_trace_stufftext.value )
|
||||
{
|
||||
size_t len = Q_strlen( s );
|
||||
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
||||
}
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// disable Cry Of Fear antisave protection
|
||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||
break; // too early
|
||||
#endif
|
||||
Cbuf_AddFilteredText( s );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
break;
|
||||
case svc_goldsrc_serverinfo:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_goldsrc_deltadescription:
|
||||
Delta_ParseTableField_GS( msg );
|
||||
break;
|
||||
case svc_clientdata:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseClientData( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_goldsrc_stopsound:
|
||||
param1 = MSG_ReadWord( msg );
|
||||
S_StopSound( param1 >> 3, param1 & 7, NULL );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_pings:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_UpdateUserPings( msg );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseReliableEvent( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseBaseline( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_setpause:
|
||||
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
||||
break;
|
||||
case svc_signonnum:
|
||||
CL_ParseSignon( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_goldsrc_spawnstaticsound:
|
||||
CL_ParseSpawnStaticSound( msg );
|
||||
break;
|
||||
case svc_finale:
|
||||
CL_ParseFinaleCutscene( msg, 2 );
|
||||
break;
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_cutscene:
|
||||
CL_ParseFinaleCutscene( msg, 3 );
|
||||
break;
|
||||
case svc_goldsrc_decalname:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
s = MSG_ReadString( msg );
|
||||
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_goldsrc_newusermsg:
|
||||
CL_RegisterUserMessage( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntitiesGS( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_choke:
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||
break;
|
||||
case svc_resourcelist:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_goldsrc_newmovevars:
|
||||
CL_ParseNewMovevars( msg );
|
||||
break;
|
||||
case svc_resourcerequest:
|
||||
CL_ParseResourceRequest( msg );
|
||||
break;
|
||||
case svc_customization:
|
||||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
case svc_soundfade:
|
||||
CL_ParseSoundFade( msg );
|
||||
break;
|
||||
case svc_filetxferfailed:
|
||||
CL_ParseFileTransferFailed( msg );
|
||||
break;
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_voiceinit:
|
||||
CL_ParseVoiceInit( msg );
|
||||
break;
|
||||
case svc_voicedata:
|
||||
CL_ParseVoiceData( msg, PROTO_GOLDSRC );
|
||||
cl.frames[cl.parsecountmod].graphdata.voicebytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_goldsrc_sendextrainfo:
|
||||
CL_ParseExtraInfo( msg );
|
||||
break;
|
||||
case svc_goldsrc_timescale:
|
||||
// we can set sys_timescale to anything we want but in GoldSrc it's locked for
|
||||
// HLTV and demoplayback. Do we really want to have it then if both are out of scope?
|
||||
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
||||
MSG_ReadFloat( msg );
|
||||
break;
|
||||
case svc_goldsrc_sendcvarvalue:
|
||||
CL_ParseCvarValue( msg, false, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_goldsrc_sendcvarvalue2:
|
||||
CL_ParseCvarValue( msg, true, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_exec:
|
||||
CL_ParseExec( msg );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ void GAME_EXPORT CL_PopPMStates( void )
|
||||
CL_IsPredicted
|
||||
===============
|
||||
*/
|
||||
static qboolean CL_IsPredicted( void )
|
||||
qboolean CL_IsPredicted( void )
|
||||
{
|
||||
if( cl_nopred.value || cl.intermission )
|
||||
return false;
|
||||
|
||||
@@ -431,7 +431,7 @@ static void CL_ParseQuakeEntityData( sizebuf_t *msg, int bits )
|
||||
cls.signon = SIGNONS;
|
||||
|
||||
// Clear loading plaque.
|
||||
CL_SignonReply( PROTO_QUAKE );
|
||||
CL_SignonReply ();
|
||||
}
|
||||
|
||||
// alloc next slot to store update
|
||||
@@ -626,7 +626,7 @@ CL_ParseStaticEntity
|
||||
|
||||
===================
|
||||
*/
|
||||
static void CL_ParseQuakeStaticEntity( sizebuf_t *msg )
|
||||
static void CL_ParseStaticEntity( sizebuf_t *msg )
|
||||
{
|
||||
entity_state_t state;
|
||||
cl_entity_t *ent;
|
||||
@@ -950,7 +950,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
break;
|
||||
case svc_time:
|
||||
Cbuf_AddText( "\n" ); // new frame was started
|
||||
CL_ParseServerTime( msg, PROTO_QUAKE );
|
||||
CL_ParseServerTime( msg );
|
||||
break;
|
||||
case svc_print:
|
||||
str = MSG_ReadString( msg );
|
||||
@@ -1006,7 +1006,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
CL_ParseQuakeDamage( msg );
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_ParseQuakeStaticEntity( msg );
|
||||
CL_ParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_spawnbinary:
|
||||
// never used in Quake
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -77,6 +77,7 @@ void R_MultiGunshot( const vec3_t org, const vec3_t dir, const vec3_t noise, int
|
||||
void R_FireField( float *org, int radius, int modelIndex, int count, int flags, float life );
|
||||
void R_PlayerSprites( int client, int modelIndex, int count, int size );
|
||||
void R_Sprite_WallPuff( struct tempent_s *pTemp, float scale );
|
||||
void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b );
|
||||
void R_RicochetSound( const vec3_t pos );
|
||||
struct dlight_s *CL_AllocDlight( int key );
|
||||
struct dlight_s *CL_AllocElight( int key );
|
||||
|
||||
@@ -129,6 +129,7 @@ typedef struct
|
||||
|
||||
// misc local info
|
||||
qboolean repredicting; // repredicting in progress
|
||||
qboolean thirdperson;
|
||||
qboolean apply_effects; // local player will not added but we should apply their effects: flashlight etc
|
||||
float idealpitch;
|
||||
int viewmodel;
|
||||
@@ -277,8 +278,6 @@ typedef struct
|
||||
int lostpackets; // count lost packets and show dialog in menu
|
||||
|
||||
double frametime_remainder;
|
||||
|
||||
uint worldmapCRC;
|
||||
} client_t;
|
||||
|
||||
/*
|
||||
@@ -310,6 +309,14 @@ typedef enum
|
||||
CL_CHANGELEVEL, // draw 'loading' during changelevel
|
||||
} scrstate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROTO_CURRENT = 0, // Xash3D 49
|
||||
PROTO_LEGACY = 1, // Xash3D 48
|
||||
PROTO_QUAKE = 2, // Quake 15
|
||||
PROTO_GOLDSRC = 3, // GoldSrc 48
|
||||
} connprotocol_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
@@ -653,7 +660,6 @@ extern gameui_static_t gameui;
|
||||
//
|
||||
// cvars
|
||||
//
|
||||
extern convar_t showpause;
|
||||
extern convar_t mp_decals;
|
||||
extern convar_t cl_logomaxdim;
|
||||
extern convar_t cl_allow_download;
|
||||
@@ -754,7 +760,7 @@ qboolean CL_PrecacheResources( void );
|
||||
void CL_SetupOverviewParams( void );
|
||||
void CL_UpdateFrameLerp( void );
|
||||
int CL_IsDevOverviewMode( void );
|
||||
void CL_SignonReply( connprotocol_t proto );
|
||||
void CL_SignonReply( void );
|
||||
void CL_ClearState( void );
|
||||
|
||||
//
|
||||
@@ -784,8 +790,8 @@ int CL_GetDemoComment( const char *demoname, char *comment );
|
||||
//
|
||||
// cl_events.c
|
||||
//
|
||||
void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseEvent( sizebuf_t *msg );
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg );
|
||||
void CL_SetEventIndex( const char *szEvName, int ev_index );
|
||||
void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin,
|
||||
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
|
||||
@@ -862,21 +868,20 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
|
||||
// cl_parse.c
|
||||
//
|
||||
void CL_ParseSetAngle( sizebuf_t *msg );
|
||||
void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseLightStyle( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy );
|
||||
void CL_ParseLightStyle( sizebuf_t *msg );
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy );
|
||||
void CL_ParseResource( sizebuf_t *msg );
|
||||
void CL_ParseClientData( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseClientData( sizebuf_t *msg );
|
||||
void CL_UpdateUserPings( sizebuf_t *msg );
|
||||
void CL_ParseParticles( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseParticles( sizebuf_t *msg );
|
||||
void CL_ParseRestoreSoundPacket( sizebuf_t *msg );
|
||||
void CL_ParseBaseline( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseSignon( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy );
|
||||
void CL_ParseSignon( sizebuf_t *msg );
|
||||
void CL_ParseRestore( sizebuf_t *msg );
|
||||
void CL_ParseStaticDecal( sizebuf_t *msg );
|
||||
void CL_ParseAddAngle( sizebuf_t *msg );
|
||||
void CL_RegisterUserMessage( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseResourceList( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_RegisterUserMessage( sizebuf_t *msg );
|
||||
void CL_ParseMovevars( sizebuf_t *msg );
|
||||
void CL_ParseResourceRequest( sizebuf_t *msg );
|
||||
void CL_ParseCustomization( sizebuf_t *msg );
|
||||
@@ -885,22 +890,18 @@ void CL_ParseSoundFade( sizebuf_t *msg );
|
||||
void CL_ParseFileTransferFailed( sizebuf_t *msg );
|
||||
void CL_ParseHLTV( sizebuf_t *msg );
|
||||
void CL_ParseDirector( sizebuf_t *msg );
|
||||
void CL_ParseVoiceInit( sizebuf_t *msg );
|
||||
void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseResLocation( sizebuf_t *msg );
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext, const connprotocol_t proto );
|
||||
void CL_ParseServerMessage( sizebuf_t *msg );
|
||||
qboolean CL_ParseCommonDLLMessage( sizebuf_t *msg, connprotocol_t proto, int svc_num, int startoffset );
|
||||
void CL_ParseTempEntity( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseTempEntity( sizebuf_t *msg );
|
||||
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
|
||||
qboolean CL_RequestMissingResources( void );
|
||||
void CL_RegisterResources( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_RegisterResources ( sizebuf_t *msg );
|
||||
void CL_ParseViewEntity( sizebuf_t *msg );
|
||||
void CL_ParseServerTime( sizebuf_t *msg, connprotocol_t proto );
|
||||
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num, connprotocol_t proto );
|
||||
void CL_ParseServerTime( sizebuf_t *msg );
|
||||
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
|
||||
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
|
||||
void CL_ParseTextMessage( sizebuf_t *msg );
|
||||
void CL_ParseExec( sizebuf_t *msg );
|
||||
void CL_BatchResourceRequest( qboolean initialize );
|
||||
int CL_EstimateNeededResources( void );
|
||||
|
||||
@@ -910,11 +911,6 @@ int CL_EstimateNeededResources( void );
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg );
|
||||
void CL_LegacyPrecache_f( void );
|
||||
|
||||
//
|
||||
// cl_parse_gs.c
|
||||
//
|
||||
void CL_ParseGoldSrcServerMessage( sizebuf_t *msg );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
//
|
||||
@@ -956,6 +952,7 @@ void CL_SetSolidPlayers( int playernum );
|
||||
void CL_InitClientMove( void );
|
||||
void CL_PredictMovement( qboolean repredicting );
|
||||
void CL_CheckPredictionError( void );
|
||||
qboolean CL_IsPredicted( void );
|
||||
int CL_WaterEntity( const float *rgflPos );
|
||||
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
|
||||
pmtrace_t *CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
|
||||
@@ -978,9 +975,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg );
|
||||
//
|
||||
struct channel_s;
|
||||
struct rawchan_s;
|
||||
qboolean CL_ValidateDeltaPacket( uint oldpacket, frame_t *oldframe );
|
||||
int CL_UpdateOldEntNum( int oldindex, frame_t *oldframe, entity_state_t **oldent );
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto );
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta );
|
||||
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
|
||||
void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
|
||||
qboolean CL_GetEntitySpatialization( struct channel_s *ch );
|
||||
@@ -1030,6 +1025,7 @@ void CL_InitParticles( void );
|
||||
void CL_ClearParticles( void );
|
||||
void CL_FreeParticles( void );
|
||||
void CL_InitTempEnts( void );
|
||||
void CL_ClearTempEnts( void );
|
||||
void CL_FreeTempEnts( void );
|
||||
void CL_TempEntUpdate( void );
|
||||
void CL_InitViewBeams( void );
|
||||
|
||||
@@ -569,9 +569,10 @@ IN_EngineAppendMove
|
||||
Called from cl_main.c after generating command in client
|
||||
================
|
||||
*/
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active )
|
||||
void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
|
||||
{
|
||||
float forward, side, pitch, yaw;
|
||||
usercmd_t *cmd = cmd1;
|
||||
|
||||
if( clgame.dllFuncs.pfnLookEvent )
|
||||
return;
|
||||
|
||||
@@ -25,7 +25,6 @@ INPUT
|
||||
*/
|
||||
|
||||
#include "keydefs.h"
|
||||
#include "usercmd.h"
|
||||
|
||||
//
|
||||
// input.c
|
||||
@@ -44,7 +43,7 @@ void IN_ToggleClientMouse( int newstate, int oldstate );
|
||||
|
||||
uint IN_CollectInputDevices( void );
|
||||
void IN_LockInputDevices( qboolean lock );
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active );
|
||||
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
|
||||
|
||||
extern convar_t m_yaw;
|
||||
extern convar_t m_pitch;
|
||||
|
||||
@@ -524,11 +524,8 @@ static void SND_Spatialize( channel_t *ch )
|
||||
dist = VectorNormalizeLength( source_vec );
|
||||
dot = DotProduct( s_listener.right, source_vec );
|
||||
|
||||
if( !FBitSet( host.bugcomp, BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE ))
|
||||
{
|
||||
// don't pan sounds with no attenuation
|
||||
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
|
||||
}
|
||||
// don't pan sounds with no attenuation
|
||||
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
|
||||
|
||||
// fill out channel volumes for single location
|
||||
S_SpatializeChannel( &ch->leftvol, &ch->rightvol, ch->master_vol, gain, dot, dist * ch->dist_mult );
|
||||
@@ -1894,7 +1891,7 @@ S_VoiceRecordStart_f
|
||||
*/
|
||||
static void S_VoiceRecordStart_f( void )
|
||||
{
|
||||
if( cls.state != ca_active )
|
||||
if( cls.state != ca_active || cls.legacymode )
|
||||
return;
|
||||
|
||||
Voice_RecordStart();
|
||||
|
||||
@@ -248,12 +248,6 @@ static const char *VOX_GetDirectory( char *szpath, const char *psz, int nsize )
|
||||
const char *p;
|
||||
int len;
|
||||
|
||||
// HACKHACK: some modders send strings like "/fvox/_period four"
|
||||
// which should get parsed as "_period four" said by fvox
|
||||
// it might be incorrect but ignore first slash here for now
|
||||
if( psz[0] == '/' )
|
||||
psz++;
|
||||
|
||||
// search / backwards
|
||||
p = Q_strrchr( psz, '/' );
|
||||
|
||||
@@ -601,8 +595,8 @@ static void Test_VOX_GetDirectory( void )
|
||||
{
|
||||
"", "", "vox/",
|
||||
"bark bark", "bark bark", "vox/",
|
||||
"barney/meow", "meow", "barney/",
|
||||
"/fvox/_period", "_period", "fvox/",
|
||||
"barney/meow", "meow", "barney/"
|
||||
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
@@ -396,9 +396,6 @@ void Voice_RecordStart( void )
|
||||
{
|
||||
Voice_RecordStop();
|
||||
|
||||
if( !voice.initialized )
|
||||
return;
|
||||
|
||||
if( voice_inputfromfile.value )
|
||||
{
|
||||
voice.input_file = FS_LoadSound( "voice_input.wav", NULL, 0 );
|
||||
@@ -418,7 +415,7 @@ void Voice_RecordStart( void )
|
||||
}
|
||||
}
|
||||
|
||||
if( !Voice_IsRecording( ) && voice.device_opened )
|
||||
if( !Voice_IsRecording() )
|
||||
voice.is_recording = VoiceCapture_Activate( true );
|
||||
|
||||
if( Voice_IsRecording() )
|
||||
@@ -630,8 +627,7 @@ qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit )
|
||||
{
|
||||
if( Q_strcmp( pszCodecName, VOICE_OPUS_CUSTOM_CODEC ))
|
||||
{
|
||||
if( COM_CheckStringEmpty( pszCodecName ))
|
||||
Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName );
|
||||
Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName );
|
||||
|
||||
// reset saved codec name, we won't enable voice for this connection
|
||||
voice_codec_init[0] = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef enum
|
||||
T_COUNT
|
||||
} cvartype_t;
|
||||
|
||||
static const char *const cvartypes[] = { NULL, "BOOL", "NUMBER", "LIST", "STRING" };
|
||||
const char *cvartypes[] = { NULL, "BOOL", "NUMBER", "LIST", "STRING" };
|
||||
|
||||
typedef struct parserstate_s
|
||||
{
|
||||
|
||||
@@ -24,27 +24,18 @@ GNU General Public License for more details.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte *const data;
|
||||
const int maxsize;
|
||||
int cursize;
|
||||
byte *data;
|
||||
int cursize;
|
||||
int maxsize;
|
||||
} cmdbuf_t;
|
||||
|
||||
static qboolean cmd_wait;
|
||||
static byte cmd_text_buf[MAX_CMD_BUFFER];
|
||||
static byte filteredcmd_text_buf[MAX_CMD_BUFFER];
|
||||
static cmdbuf_t cmd_text =
|
||||
{
|
||||
.data = cmd_text_buf,
|
||||
.maxsize = ARRAYSIZE( cmd_text_buf ),
|
||||
};
|
||||
static cmdbuf_t filteredcmd_text =
|
||||
{
|
||||
.data = filteredcmd_text_buf,
|
||||
.maxsize = ARRAYSIZE( filteredcmd_text_buf ),
|
||||
};
|
||||
static cmdalias_t *cmd_alias;
|
||||
static uint cmd_condition;
|
||||
static int cmd_condlevel;
|
||||
qboolean cmd_wait;
|
||||
cmdbuf_t cmd_text, filteredcmd_text;
|
||||
byte cmd_text_buf[MAX_CMD_BUFFER];
|
||||
byte filteredcmd_text_buf[MAX_CMD_BUFFER];
|
||||
cmdalias_t *cmd_alias;
|
||||
uint cmd_condition;
|
||||
int cmd_condlevel;
|
||||
static qboolean cmd_currentCommandIsPrivileged;
|
||||
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
|
||||
@@ -57,6 +48,20 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Init
|
||||
============
|
||||
*/
|
||||
static void Cbuf_Init( void )
|
||||
{
|
||||
cmd_text.data = cmd_text_buf;
|
||||
filteredcmd_text.data = filteredcmd_text_buf;
|
||||
|
||||
filteredcmd_text.maxsize = cmd_text.maxsize = MAX_CMD_BUFFER;
|
||||
filteredcmd_text.cursize = cmd_text.cursize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Clear
|
||||
@@ -1382,6 +1387,8 @@ Cmd_Init
|
||||
*/
|
||||
void Cmd_Init( void )
|
||||
{
|
||||
Cbuf_Init();
|
||||
|
||||
cmd_functions = NULL;
|
||||
cmd_condition = 0;
|
||||
cmd_alias = NULL;
|
||||
|
||||
@@ -23,7 +23,7 @@ GNU General Public License for more details.
|
||||
#include "client.h"
|
||||
#include "library.h"
|
||||
|
||||
static const char *const file_exts[] =
|
||||
static const char *file_exts[] =
|
||||
{
|
||||
// ban text files that don't make sense as resource
|
||||
"cfg", "lst", "ini", "log",
|
||||
@@ -759,6 +759,25 @@ void GAME_EXPORT COM_FreeFile( void *buffer )
|
||||
free( buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
COM_NormalizeAngles
|
||||
|
||||
=============
|
||||
*/
|
||||
void COM_NormalizeAngles( vec3_t angles )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( angles[i] > 180.0f )
|
||||
angles[i] -= 360.0f;
|
||||
else if( angles[i] < -180.0f )
|
||||
angles[i] += 360.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnGetModelType
|
||||
@@ -824,7 +843,7 @@ int GAME_EXPORT COM_CompareFileTime( const char *filename1, const char *filename
|
||||
if( ft1 == -1 || ft2 == -1 )
|
||||
return bRet;
|
||||
|
||||
*iCompare = ft1 < ft2 ? -1 : ( ft1 > ft2 ? 1 : 0 );
|
||||
*iCompare = Host_CompareFileTime( ft1, ft2 );
|
||||
bRet = 1;
|
||||
}
|
||||
|
||||
@@ -879,40 +898,18 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
char lwrfilename[4096];
|
||||
const char *first, *last;
|
||||
const char *ext;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
return false;
|
||||
|
||||
ext = COM_FileExtension( filename );
|
||||
len = Q_strlen( filename );
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
// only allow extensionless files that start with !MD5
|
||||
if( !Q_strncmp( filename, "!MD5", 4 ))
|
||||
{
|
||||
if( COM_CheckStringEmpty( ext ))
|
||||
return false;
|
||||
|
||||
len = Q_strlen( filename );
|
||||
|
||||
if( len != 36 )
|
||||
return false;
|
||||
|
||||
for( i = 4; i < len; i++ )
|
||||
{
|
||||
if(( filename[i] >= '0' && filename[i] <= '9' ) ||
|
||||
( filename[i] >= 'A' && filename[i] <= 'F' ))
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !Q_strncmp( filename, "!MD5", 4 ) && ext[0] == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ) )
|
||||
return false;
|
||||
@@ -1045,13 +1042,28 @@ void GAME_EXPORT pfnResetTutorMessageDecayData( void )
|
||||
|
||||
void Test_RunCommon( void )
|
||||
{
|
||||
Msg( "Checking COM_IsSafeFileToDownload...\n" );
|
||||
char *file = (char *)"q asdf \"qwerty\" \"f \\\"f\" meowmeow\n// comment \"stuff ignored\"\nbark";
|
||||
int len;
|
||||
char buf[5];
|
||||
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302BC732" ), true );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD56f1ffd8c96bd64c9c27955309f6ecfe6" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302B.exe" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5/../../valve/resource/GameMenu.res" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "not-a-virus-trust-me.bat" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "a-texture.png" ), true );
|
||||
Msg( "Checking COM_ParseFile...\n" );
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "q" ) && len == 1);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "asdf" ) && len == 4);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "qwer" ) && len == -1);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "f \"f" ) && len == 4);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "meow" ) && len == -1);
|
||||
|
||||
file = COM_ParseFileSafe( file, buf, sizeof( buf ), 0, &len, NULL );
|
||||
TASSERT( !Q_strcmp( buf, "bark" ) && len == 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -112,9 +112,6 @@ typedef enum
|
||||
#include "con_nprint.h"
|
||||
#include "crclib.h"
|
||||
#include "ref_api.h"
|
||||
#define FSCALLBACK_OVERRIDE_OPEN
|
||||
#define FSCALLBACK_OVERRIDE_LOADFILE
|
||||
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
|
||||
#include "fscallback.h"
|
||||
|
||||
// PERFORMANCE INFO
|
||||
@@ -168,7 +165,6 @@ extern convar_t sys_timescale;
|
||||
extern convar_t cl_filterstuffcmd;
|
||||
extern convar_t rcon_password;
|
||||
extern convar_t hpk_custom_file;
|
||||
extern convar_t con_gamemaps;
|
||||
|
||||
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
|
||||
|
||||
@@ -277,9 +273,6 @@ typedef enum bugcomp_e
|
||||
// rewrites mod's attempts to write GoldSrc-specific messages into Xash protocol
|
||||
// (new wrappers are added by request)
|
||||
BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG = BIT( 1 ),
|
||||
|
||||
// makes sound with no attenuation spatialized, like in GoldSrc
|
||||
BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE = BIT( 2 ),
|
||||
} bugcomp_t;
|
||||
|
||||
typedef struct host_parm_s
|
||||
@@ -366,49 +359,12 @@ extern host_parm_t host;
|
||||
|
||||
typedef void (*xcommand_t)( void );
|
||||
|
||||
//
|
||||
// zone.c
|
||||
//
|
||||
void Memory_Init( void );
|
||||
void _Mem_Free( void *data, const char *filename, int fileline );
|
||||
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
|
||||
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline )
|
||||
WARN_UNUSED_RESULT;
|
||||
void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline );
|
||||
void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline );
|
||||
void _Mem_Check( const char *filename, int fileline );
|
||||
qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data );
|
||||
void Mem_PrintList( size_t minallocationsize );
|
||||
void Mem_PrintStats( void );
|
||||
|
||||
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
|
||||
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
|
||||
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
|
||||
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
|
||||
#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ )
|
||||
#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ )
|
||||
#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ )
|
||||
#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem )
|
||||
#define Mem_Check() _Mem_Check( __FILE__, __LINE__ )
|
||||
|
||||
//
|
||||
// filesystem_engine.c
|
||||
//
|
||||
void FS_Init( const char *basedir );
|
||||
void FS_Shutdown( void );
|
||||
void *FS_GetNativeObject( const char *obj );
|
||||
int FS_Close( file_t *file );
|
||||
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
|
||||
MALLOC_LIKE( FS_Close, 1 ) WARN_UNUSED_RESULT;
|
||||
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
|
||||
//
|
||||
// cmd.c
|
||||
@@ -441,6 +397,30 @@ void Cmd_ExecuteString( const char *text );
|
||||
void Cmd_ForwardToServer( void );
|
||||
void Cmd_Escape( char *newCommand, const char *oldCommand, int len );
|
||||
|
||||
//
|
||||
// zone.c
|
||||
//
|
||||
void Memory_Init( void );
|
||||
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 3 );
|
||||
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 2 );
|
||||
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline );
|
||||
void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline );
|
||||
void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline );
|
||||
void _Mem_Free( void *data, const char *filename, int fileline );
|
||||
void _Mem_Check( const char *filename, int fileline );
|
||||
qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data );
|
||||
void Mem_PrintList( size_t minallocationsize );
|
||||
void Mem_PrintStats( void );
|
||||
|
||||
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
|
||||
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
|
||||
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
|
||||
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
|
||||
#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ )
|
||||
#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ )
|
||||
#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ )
|
||||
#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem )
|
||||
#define Mem_Check() _Mem_Check( __FILE__, __LINE__ )
|
||||
|
||||
//
|
||||
// imagelib
|
||||
@@ -451,10 +431,10 @@ void Image_Setup( void );
|
||||
void Image_Init( void );
|
||||
void Image_Shutdown( void );
|
||||
void Image_AddCmdFlags( uint flags );
|
||||
void FS_FreeImage( rgbdata_t *pack );
|
||||
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeImage, 1 ) WARN_UNUSED_RESULT;
|
||||
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size );
|
||||
qboolean FS_SaveImage( const char *filename, rgbdata_t *pix );
|
||||
rgbdata_t *FS_CopyImage( rgbdata_t *in ) MALLOC_LIKE( FS_FreeImage, 1 ) WARN_UNUSED_RESULT;
|
||||
rgbdata_t *FS_CopyImage( rgbdata_t *in );
|
||||
void FS_FreeImage( rgbdata_t *pack );
|
||||
extern const bpc_desc_t PFDesc[]; // image get pixelformat
|
||||
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float reserved );
|
||||
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size );
|
||||
@@ -509,14 +489,14 @@ typedef struct
|
||||
//
|
||||
void Sound_Init( void );
|
||||
void Sound_Shutdown( void );
|
||||
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size );
|
||||
void FS_FreeSound( wavdata_t *pack );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT;
|
||||
stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT;
|
||||
stream_t *FS_OpenStream( const char *filename );
|
||||
wavdata_t *FS_StreamInfo( stream_t *stream );
|
||||
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
|
||||
int FS_SetStreamPos( stream_t *stream, int newpos );
|
||||
int FS_GetStreamPos( stream_t *stream );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint flags );
|
||||
uint Sound_GetApproxWavePlayLen( const char *filepath );
|
||||
qboolean Sound_SupportedFileFormat( const char *fileext );
|
||||
@@ -529,6 +509,7 @@ typedef void( *pfnChangeGame )( const char *progname );
|
||||
qboolean Host_IsQuakeCompatible( void );
|
||||
void EXPORT Host_Shutdown( void );
|
||||
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func );
|
||||
int Host_CompareFileTime( int ft1, int ft2 );
|
||||
void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 );
|
||||
void Host_AbortCurrentFrame( void ) NORETURN;
|
||||
void Host_WriteServerConfig( const char *name );
|
||||
@@ -580,7 +561,7 @@ qboolean SV_Active( void );
|
||||
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
|
||||
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
|
||||
int COM_SaveFile( const char *filename, const void *data, int len );
|
||||
byte *COM_LoadFileForMe( const char *filename, int *pLength ) MALLOC_LIKE( free, 1 );
|
||||
byte* COM_LoadFileForMe( const char *filename, int *pLength );
|
||||
qboolean COM_IsSafeFileToDownload( const char *filename );
|
||||
cvar_t *pfnCVarGetPointer( const char *szVarName );
|
||||
int pfnDrawConsoleString( int x, int y, char *string );
|
||||
@@ -670,15 +651,6 @@ void HPAK_FlushHostQueue( void );
|
||||
#define INPUT_DEVICE_JOYSTICK (1<<2)
|
||||
#define INPUT_DEVICE_VR (1<<3)
|
||||
|
||||
|
||||
typedef enum connprotocol_e
|
||||
{
|
||||
PROTO_CURRENT = 0, // Xash3D 49
|
||||
PROTO_LEGACY, // Xash3D 48
|
||||
PROTO_QUAKE, // Quake 15
|
||||
PROTO_GOLDSRC, // GoldSrc 48
|
||||
} connprotocol_t;
|
||||
|
||||
// shared calls
|
||||
struct physent_s;
|
||||
struct sv_client_s;
|
||||
@@ -689,9 +661,10 @@ qboolean CL_IsThirdPerson( void );
|
||||
qboolean CL_IsIntermission( void );
|
||||
qboolean CL_Initialized( void );
|
||||
char *CL_Userinfo( void );
|
||||
void CL_LegacyUpdateInfo( void );
|
||||
void CL_CharEvent( int key );
|
||||
qboolean CL_DisableVisibility( void );
|
||||
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ) MALLOC_LIKE( free, 1 );
|
||||
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength );
|
||||
struct cmd_s *Cmd_GetFirstFunctionHandle( void );
|
||||
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
|
||||
struct cmdalias_s *Cmd_AliasGetList( void );
|
||||
@@ -769,34 +742,13 @@ void UI_ShowConnectionWarning( void );
|
||||
void Cmd_Null_f( void );
|
||||
void Rcon_Print( host_redirect_t *rd, const char *pMsg );
|
||||
qboolean COM_ParseVector( char **pfile, float *v, size_t size );
|
||||
void COM_NormalizeAngles( vec3_t angles );
|
||||
int COM_FileSize( const char *filename );
|
||||
void COM_FreeFile( void *buffer );
|
||||
int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare );
|
||||
char *va( const char *format, ... ) _format( 1 );
|
||||
qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multiplayer );
|
||||
|
||||
static inline void COM_NormalizeAngles( vec3_t angles )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( angles[i] > 180.0f )
|
||||
angles[i] -= 360.0f;
|
||||
else if( angles[i] < -180.0f )
|
||||
angles[i] += 360.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
connprotocol_t CL_Protocol( void );
|
||||
#else
|
||||
static inline connprotocol_t CL_Protocol( void )
|
||||
{
|
||||
return PROTO_CURRENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline qboolean Host_IsLocalGame( void )
|
||||
{
|
||||
if( SV_Active( ))
|
||||
@@ -846,16 +798,6 @@ void NET_MasterClear( void );
|
||||
void NET_MasterShutdown( void );
|
||||
qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat );
|
||||
|
||||
//
|
||||
// munge.c
|
||||
//
|
||||
void COM_Munge( byte *data, size_t len, int seq );
|
||||
void COM_UnMunge( byte *data, size_t len, int seq );
|
||||
void COM_Munge2( byte *data, size_t len, int seq );
|
||||
void COM_UnMunge2( byte *data, size_t len, int seq );
|
||||
void COM_Munge3( byte *data, size_t len, int seq );
|
||||
void COM_UnMunge3( byte *data, size_t len, int seq );
|
||||
|
||||
//
|
||||
// sounds.c
|
||||
//
|
||||
|
||||
@@ -18,6 +18,8 @@ GNU General Public License for more details.
|
||||
#include "const.h"
|
||||
#include "kbutton.h"
|
||||
|
||||
extern convar_t con_gamemaps;
|
||||
|
||||
#define CON_MAXCMDS 4096 // auto-complete intermediate list
|
||||
|
||||
typedef struct autocomplete_list_s
|
||||
@@ -1010,7 +1012,7 @@ int GAME_EXPORT Cmd_CheckMapsList( int fRefresh )
|
||||
return Cmd_CheckMapsList_R( fRefresh, true );
|
||||
}
|
||||
|
||||
static const autocomplete_list_t cmd_list[] =
|
||||
autocomplete_list_t cmd_list[] =
|
||||
{
|
||||
{ "map_background", 1, Cmd_GetMapList },
|
||||
{ "changelevel2", 1, Cmd_GetMapList },
|
||||
@@ -1073,7 +1075,7 @@ for various cmds
|
||||
*/
|
||||
static qboolean Cmd_AutocompleteName( const char *source, int arg, char *buffer, size_t bufsize )
|
||||
{
|
||||
const autocomplete_list_t *list;
|
||||
autocomplete_list_t *list;
|
||||
|
||||
for( list = cmd_list; list->name; list++ )
|
||||
{
|
||||
|
||||
@@ -18,17 +18,17 @@ GNU General Public License for more details.
|
||||
#include "base_cmd.h"
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
|
||||
static convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
typedef struct cvar_filter_quirks_s
|
||||
{
|
||||
const char *gamedir; // gamedir to enable for
|
||||
const char *cvars; // list of cvars should be excluded from filter
|
||||
} cvar_filter_quirks_t;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
static const cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
static cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
{
|
||||
// EXAMPLE:
|
||||
//{
|
||||
@@ -44,9 +44,9 @@ static const cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
"cl_dodmusic" // Day of Defeat Beta 1.3 cvar
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static const cvar_filter_quirks_t *cvar_active_filter_quirks = NULL;
|
||||
static cvar_filter_quirks_t *cvar_active_filter_quirks = NULL;
|
||||
#endif
|
||||
|
||||
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
|
||||
|
||||
@@ -70,14 +70,15 @@ find the specified variable by name
|
||||
*/
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group )
|
||||
{
|
||||
convar_t *var;
|
||||
// TODO: ignore group for cvar
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
return (convar_t *)BaseCmd_Find( HM_CVAR, var_name );
|
||||
#else
|
||||
convar_t *var;
|
||||
|
||||
if( !var_name )
|
||||
return NULL;
|
||||
|
||||
#if defined(XASH_HASHED_VARS) // TODO: ignore_group
|
||||
var = BaseCmd_Find( HM_CVAR, var_name );
|
||||
#else
|
||||
for( var = cvar_vars; var; var = var->next )
|
||||
{
|
||||
if( ignore_group && FBitSet( ignore_group, var->flags ))
|
||||
@@ -86,13 +87,9 @@ convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group )
|
||||
if( !Q_stricmp( var_name, var->name ))
|
||||
return var;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
// HACKHACK: HL25 compatibility
|
||||
if( !var && !Q_stricmp( var_name, "gl_widescreen_yfov" ))
|
||||
var = Cvar_FindVarExt( "r_adjust_fov", ignore_group );
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -275,15 +272,6 @@ static qboolean Cvar_ValidateVarName( const char *s, qboolean isvalue )
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Cvar_Free( convar_t *var )
|
||||
{
|
||||
freestring( var->name );
|
||||
freestring( var->string );
|
||||
freestring( var->def_string );
|
||||
freestring( var->desc );
|
||||
Mem_Free( var );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_UnlinkVar
|
||||
@@ -323,13 +311,17 @@ static int Cvar_UnlinkVar( const char *var_name, int group )
|
||||
#endif
|
||||
|
||||
// unlink variable from list
|
||||
freestring( var->string );
|
||||
*prev = var->next;
|
||||
|
||||
// only allocated cvars can throw these fields
|
||||
if( FBitSet( var->flags, FCVAR_ALLOCATED ))
|
||||
Cvar_Free( var );
|
||||
else
|
||||
freestring( var->string );
|
||||
{
|
||||
freestring( var->name );
|
||||
freestring( var->def_string );
|
||||
freestring( var->desc );
|
||||
Mem_Free( var );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -618,7 +610,7 @@ static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
return Cvar_Get( var_name, value, FCVAR_USER_CREATED, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if( !Cmd_CurrentCommandIsPrivileged( ))
|
||||
{
|
||||
if( FBitSet( var->flags, FCVAR_PRIVILEGED ))
|
||||
@@ -974,6 +966,7 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// check if game-specific filter exceptions should be applied
|
||||
// TODO: for cmd exceptions, make generic function
|
||||
if( cvar_active_filter_quirks )
|
||||
@@ -1004,6 +997,7 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( FBitSet( v->flags, FCVAR_FILTERABLE ))
|
||||
return false;
|
||||
@@ -1223,20 +1217,6 @@ static void Cvar_List_f( void )
|
||||
Con_Printf( "\n%i cvars\n", count );
|
||||
}
|
||||
|
||||
static qboolean Cvar_ValidateUnlinkGroup( int group )
|
||||
{
|
||||
if( FBitSet( group, FCVAR_EXTDLL ) && !Cvar_VariableInteger( "host_gameloaded" ))
|
||||
return false;
|
||||
|
||||
if( FBitSet( group, FCVAR_CLIENTDLL ) && !Cvar_VariableInteger( "host_clientloaded" ))
|
||||
return false;
|
||||
|
||||
if( FBitSet( group, FCVAR_GAMEUIDLL ) && !Cvar_VariableInteger( "host_gameuiloaded" ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Unlink
|
||||
@@ -1248,95 +1228,19 @@ void Cvar_Unlink( int group )
|
||||
{
|
||||
int count;
|
||||
|
||||
if( !Cvar_ValidateUnlinkGroup( group ))
|
||||
if( Cvar_VariableInteger( "host_gameloaded" ) && FBitSet( group, FCVAR_EXTDLL ))
|
||||
return;
|
||||
|
||||
if( Cvar_VariableInteger( "host_clientloaded" ) && FBitSet( group, FCVAR_CLIENTDLL ))
|
||||
return;
|
||||
|
||||
if( Cvar_VariableInteger( "host_gameuiloaded" ) && FBitSet( group, FCVAR_GAMEUIDLL ))
|
||||
return;
|
||||
|
||||
count = Cvar_UnlinkVar( NULL, group );
|
||||
Con_Reportf( "unlink %i cvars\n", count );
|
||||
}
|
||||
|
||||
pending_cvar_t *Cvar_PrepareToUnlink( int group )
|
||||
{
|
||||
pending_cvar_t *list = NULL;
|
||||
pending_cvar_t *tail = NULL;
|
||||
convar_t *cv;
|
||||
|
||||
for( cv = cvar_vars; cv != NULL; cv = cv->next )
|
||||
{
|
||||
size_t namelen;
|
||||
pending_cvar_t *p;
|
||||
|
||||
if( !FBitSet( cv->flags, group ))
|
||||
continue;
|
||||
|
||||
namelen = Q_strlen( cv->name ) + 1;
|
||||
p = Mem_Malloc( host.mempool, sizeof( *list ) + namelen );
|
||||
p->next = NULL;
|
||||
p->cv_cur = cv;
|
||||
p->cv_next = cv->next;
|
||||
p->cv_allocated = FBitSet( cv->flags, FCVAR_ALLOCATED ) ? true : false;
|
||||
Q_strncpy( p->cv_name, cv->name, namelen );
|
||||
|
||||
if( list == NULL )
|
||||
list = p;
|
||||
else
|
||||
tail->next = p;
|
||||
|
||||
tail = p;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void Cvar_UnlinkPendingCvars( pending_cvar_t *list )
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while( list != NULL )
|
||||
{
|
||||
pending_cvar_t *next = list->next;
|
||||
convar_t *cv_prev, *cv;
|
||||
|
||||
for( cv_prev = NULL, cv = cvar_vars; cv != NULL; cv_prev = cv, cv = cv->next )
|
||||
{
|
||||
if( cv == list->cv_cur )
|
||||
break;
|
||||
}
|
||||
|
||||
if( cv == NULL )
|
||||
{
|
||||
Con_Reportf( "%s: can't find %s in variable list\n", __func__, list->cv_name );
|
||||
Mem_Free( list );
|
||||
list = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
// unlink cvar from list
|
||||
BaseCmd_Remove( HM_CVAR, list->cv_name );
|
||||
if( cv_prev != NULL )
|
||||
cv_prev->next = list->cv_next;
|
||||
else cvar_vars = list->cv_next;
|
||||
|
||||
if( list->cv_allocated )
|
||||
Cvar_Free( list->cv_cur );
|
||||
else
|
||||
{
|
||||
// TODO: can't free cvar string here because
|
||||
// it's not safe to access cv_cur and
|
||||
// can't save string pointer because it could've been changed
|
||||
// and pointer to it is already lost
|
||||
// freestring( list->cv_string );
|
||||
}
|
||||
|
||||
// now free pending cvar
|
||||
Mem_Free( list );
|
||||
list = next;
|
||||
count++;
|
||||
}
|
||||
|
||||
Con_Reportf( "unlink %i cvars\n", count );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Init
|
||||
|
||||
@@ -18,18 +18,6 @@ GNU General Public License for more details.
|
||||
|
||||
#include "cvardef.h"
|
||||
|
||||
// As some mods dynamically allocate cvars and free them without notifying the engine
|
||||
// let's construct a list of cvars that must be removed
|
||||
typedef struct pending_cvar_s
|
||||
{
|
||||
struct pending_cvar_s *next;
|
||||
|
||||
convar_t *cv_cur; // preserve the data that might get freed
|
||||
convar_t *cv_next;
|
||||
qboolean cv_allocated; // if it's allocated by us, it's safe to access cv_cur
|
||||
char cv_name[];
|
||||
} pending_cvar_t;
|
||||
|
||||
cvar_t *Cvar_GetList( void );
|
||||
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
|
||||
@@ -55,7 +43,4 @@ void Cvar_Init( void );
|
||||
void Cvar_PostFSInit( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
pending_cvar_t *Cvar_PrepareToUnlink( int group );
|
||||
void Cvar_UnlinkPendingCvars( pending_cvar_t *pending_cvars );
|
||||
|
||||
#endif//CVAR_H
|
||||
|
||||
@@ -134,6 +134,11 @@ void GAME_EXPORT S_StopSound(int entnum, int channel, const char *soundname)
|
||||
|
||||
}
|
||||
|
||||
int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GAME_EXPORT CL_GetMaxClients( void )
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -27,31 +27,6 @@ fs_globals_t *FI;
|
||||
static pfnCreateInterface_t fs_pfnCreateInterface;
|
||||
static HINSTANCE fs_hInstance;
|
||||
|
||||
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
|
||||
{
|
||||
return g_fsapi.Search( pattern, caseinsensitive, gamedironly );
|
||||
}
|
||||
|
||||
int FS_Close( file_t *file )
|
||||
{
|
||||
return g_fsapi.Close( file );
|
||||
}
|
||||
|
||||
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
|
||||
{
|
||||
return g_fsapi.Open( filepath, mode, gamedironly );
|
||||
}
|
||||
|
||||
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
|
||||
{
|
||||
return g_fsapi.LoadFile( path, filesizeptr, gamedironly );
|
||||
}
|
||||
|
||||
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
|
||||
{
|
||||
return g_fsapi.LoadDirectFile( path, filesizeptr );
|
||||
}
|
||||
|
||||
static void COM_StripDirectorySlash( char *pname )
|
||||
{
|
||||
size_t len;
|
||||
|
||||
@@ -40,7 +40,7 @@ GNU General Public License for more details.
|
||||
#include "render_api.h" // decallist_t
|
||||
#include "tests.h"
|
||||
|
||||
static pfnChangeGame pChangeGame = NULL;
|
||||
pfnChangeGame pChangeGame = NULL;
|
||||
host_parm_t host; // host parms
|
||||
|
||||
#ifdef XASH_ENGINE_TESTS
|
||||
@@ -49,8 +49,8 @@ struct tests_stats_s tests_stats;
|
||||
|
||||
CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in development-mode" );
|
||||
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_FILTERABLE, "scale frame time" );
|
||||
CVAR_DEFINE_AUTO( sys_ticrate, "100", FCVAR_SERVER, "framerate in dedicated mode" );
|
||||
|
||||
static CVAR_DEFINE_AUTO( sys_ticrate, "100", FCVAR_SERVER, "framerate in dedicated mode" );
|
||||
static CVAR_DEFINE_AUTO( host_serverstate, "0", FCVAR_READ_ONLY, "displays current server state" );
|
||||
static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
|
||||
static CVAR_DEFINE_AUTO( host_clientloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
|
||||
@@ -69,14 +69,13 @@ typedef struct feature_message_s
|
||||
const char *arg;
|
||||
} feature_message_t;
|
||||
|
||||
static const feature_message_t bugcomp_features[] =
|
||||
static feature_message_t bugcomp_features[] =
|
||||
{
|
||||
{ BUGCOMP_PENTITYOFENTINDEX_FLAG, "pfnPEntityOfEntIndex bugfix revert", "peoei" },
|
||||
{ BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG, "GoldSrc Message Rewrite Facility", "gsmrf" },
|
||||
{ BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE, "spatialize sounds with zero attenuation", "sp_attn_none" },
|
||||
};
|
||||
|
||||
static const feature_message_t engine_features[] =
|
||||
static feature_message_t engine_features[] =
|
||||
{
|
||||
{ ENGINE_WRITE_LARGE_COORD, "Big World Support" },
|
||||
{ ENGINE_QUAKE_COMPATIBLE, "Quake Compatibility" },
|
||||
@@ -200,6 +199,19 @@ static void Sys_PrintUsage( const char *exename )
|
||||
Sys_Quit();
|
||||
}
|
||||
|
||||
int Host_CompareFileTime( int ft1, int ft2 )
|
||||
{
|
||||
if( ft1 < ft2 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if( ft1 > ft2 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Host_ShutdownServer( void )
|
||||
{
|
||||
SV_Shutdown( "Server was killed\n" );
|
||||
@@ -210,7 +222,7 @@ void Host_ShutdownServer( void )
|
||||
Host_PrintEngineFeatures
|
||||
================
|
||||
*/
|
||||
static void Host_PrintFeatures( uint32_t flags, const char *s, const feature_message_t *features, size_t size )
|
||||
static void Host_PrintFeatures( uint32_t flags, const char *s, feature_message_t *features, size_t size )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -233,20 +245,8 @@ void Host_ValidateEngineFeatures( uint32_t features )
|
||||
uint32_t mask = ENGINE_FEATURES_MASK;
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ))
|
||||
{
|
||||
switch( cls.legacymode )
|
||||
{
|
||||
case PROTO_CURRENT:
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
break;
|
||||
default:
|
||||
mask = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !Host_IsDedicated( ) && cls.legacymode )
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
#endif
|
||||
|
||||
// don't allow unsupported bits
|
||||
@@ -1071,9 +1071,6 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
Host_RunTests( 0 );
|
||||
#endif
|
||||
|
||||
#if XASH_DEDICATED
|
||||
Platform_SetupSigtermHandling();
|
||||
#endif
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
|
||||
FS_Init( basedir );
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ void Image_Reset( void )
|
||||
image.size = 0;
|
||||
}
|
||||
|
||||
static MALLOC_LIKE( FS_FreeImage, 1 ) rgbdata_t *ImagePack( void )
|
||||
static rgbdata_t *ImagePack( void )
|
||||
{
|
||||
rgbdata_t *pack;
|
||||
|
||||
@@ -547,7 +547,7 @@ static void Test_CheckImage( const char *name, rgbdata_t *rgb )
|
||||
TASSERT( load->size == rgb->size )
|
||||
TASSERT( memcmp(load->buffer, rgb->buffer, rgb->size ) == 0 )
|
||||
|
||||
FS_FreeImage( load );
|
||||
Mem_Free( load );
|
||||
}
|
||||
|
||||
void Test_RunImagelib( void )
|
||||
|
||||
@@ -21,7 +21,6 @@ typedef struct master_s
|
||||
struct master_s *next;
|
||||
qboolean sent; // TODO: get rid of this internal state
|
||||
qboolean save;
|
||||
qboolean v6only;
|
||||
string address;
|
||||
netadr_t adr; // temporary, rewritten after each send
|
||||
|
||||
@@ -46,7 +45,7 @@ NET_GetMasterHostByName
|
||||
*/
|
||||
static net_gai_state_t NET_GetMasterHostByName( master_t *m )
|
||||
{
|
||||
net_gai_state_t res = NET_StringToAdrNB( m->address, &m->adr, m->v6only );
|
||||
net_gai_state_t res = NET_StringToAdrNB( m->address, &m->adr );
|
||||
|
||||
if( res == NET_EAI_OK )
|
||||
return res;
|
||||
@@ -252,7 +251,7 @@ NET_AddMaster
|
||||
Add master to the list
|
||||
========================
|
||||
*/
|
||||
static void NET_AddMaster( const char *addr, qboolean save, qboolean v6only )
|
||||
static void NET_AddMaster( const char *addr, qboolean save )
|
||||
{
|
||||
master_t *master, *last;
|
||||
|
||||
@@ -262,11 +261,10 @@ static void NET_AddMaster( const char *addr, qboolean save, qboolean v6only )
|
||||
return;
|
||||
}
|
||||
|
||||
master = Mem_Malloc( host.mempool, sizeof( *master ) );
|
||||
master = Mem_Malloc( host.mempool, sizeof( master_t ) );
|
||||
Q_strncpy( master->address, addr, sizeof( master->address ));
|
||||
master->sent = false;
|
||||
master->save = save;
|
||||
master->v6only = v6only;
|
||||
master->next = NULL;
|
||||
master->adr.type = 0;
|
||||
|
||||
@@ -285,7 +283,7 @@ static void NET_AddMaster_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
NET_AddMaster( Cmd_Argv( 1 ), true, false ); // save them into config
|
||||
NET_AddMaster( Cmd_Argv( 1 ), true ); // save them into config
|
||||
ml.modified = true; // save config
|
||||
}
|
||||
|
||||
@@ -318,14 +316,15 @@ static void NET_ListMasters_f( void )
|
||||
master_t *list;
|
||||
int i;
|
||||
|
||||
Con_Printf( "Master servers:\n" );
|
||||
Msg( "Master servers\n=============\n" );
|
||||
|
||||
|
||||
for( i = 1, list = ml.list; list; i++, list = list->next )
|
||||
{
|
||||
Con_Printf( "%d\t%s", i, list->address );
|
||||
Msg( "%d\t%s", i, list->address );
|
||||
if( list->adr.type != 0 )
|
||||
Con_Printf( "\t%s\n", NET_AdrToString( list->adr ));
|
||||
else Con_Printf( "\n" );
|
||||
Msg( "\t%s\n", NET_AdrToString( list->adr ));
|
||||
else Msg( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,15 +354,11 @@ static void NET_LoadMasters( void )
|
||||
// format: master <addr>\n
|
||||
while( ( pfile = COM_ParseFile( pfile, token, sizeof( token ) ) ) )
|
||||
{
|
||||
if( !Q_strcmp( token, "master" )) // load addr
|
||||
if( !Q_strcmp( token, "master" ) ) // load addr
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token, sizeof( token ) );
|
||||
NET_AddMaster( token, true, false );
|
||||
}
|
||||
else if( !Q_strcmp( token, "master6" ))
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token, sizeof( token ) );
|
||||
NET_AddMaster( token, true, true );
|
||||
|
||||
NET_AddMaster( token, true );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +396,7 @@ void NET_SaveMasters( void )
|
||||
for( m = ml.list; m; m = m->next )
|
||||
{
|
||||
if( m->save )
|
||||
FS_Printf( f, "%s %s\n", m->v6only ? "master6" : "master", m->address );
|
||||
FS_Printf( f, "master %s\n", m->address );
|
||||
}
|
||||
|
||||
FS_Close( f );
|
||||
@@ -423,10 +418,9 @@ void NET_InitMasters( void )
|
||||
Cvar_RegisterVariable( &sv_verbose_heartbeats );
|
||||
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false, false );
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false, true ); // IPv6-only
|
||||
NET_AddMaster( "mentality.rip:27011", false, false ); // testing server, might be offline
|
||||
NET_AddMaster( "aaaa.mentality.rip:27011", false, true ); // IPv6-only, testing server, might be offline
|
||||
NET_AddMaster( MASTERSERVER_ADR, false );
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false ); // IPv6-only
|
||||
NET_AddMaster( "mentality.rip:27011", false );
|
||||
|
||||
NET_LoadMasters( );
|
||||
}
|
||||
|
||||
@@ -30,6 +30,13 @@ GNU General Public License for more details.
|
||||
|
||||
#define MIPTEX_CUSTOM_PALETTE_SIZE_BYTES ( sizeof( int16_t ) + 768 )
|
||||
|
||||
typedef struct wadlist_s
|
||||
{
|
||||
char wadnames[MAX_MAP_WADS][32];
|
||||
int wadusage[MAX_MAP_WADS];
|
||||
int count;
|
||||
} wadlist_t;
|
||||
|
||||
typedef struct leaflist_s
|
||||
{
|
||||
int count;
|
||||
@@ -129,6 +136,7 @@ typedef struct
|
||||
dclipnode32_t *clipnodes_out; // temporary 32-bit array to hold clipnodes
|
||||
|
||||
// misc stuff
|
||||
wadlist_t wadlist;
|
||||
int lightmap_samples; // samples per lightmap (1 or 3)
|
||||
int version; // model version
|
||||
qboolean isworld;
|
||||
@@ -198,7 +206,7 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
{ LUMP_MODELS, 1, MAX_MAP_MODELS, sizeof( dmodel_t ), -1, "models", CHECK_OVERFLOW, (const void **)&srcmodel.submodels, &srcmodel.numsubmodels },
|
||||
};
|
||||
|
||||
static const mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
static mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
{
|
||||
{ LUMP_LIGHTVECS, 0, MAX_MAP_LIGHTING, sizeof( byte ), -1, "deluxmaps", USE_EXTRAHEADER, (const void **)&srcmodel.deluxdata, &srcmodel.deluxdatasize },
|
||||
{ LUMP_FACEINFO, 0, MAX_MAP_FACEINFO, sizeof( dfaceinfo_t ), -1, "faceinfos", CHECK_OVERFLOW|USE_EXTRAHEADER, (const void **)&srcmodel.faceinfo, &srcmodel.numfaceinfo },
|
||||
@@ -347,7 +355,7 @@ Mod_LoadLump
|
||||
generic loader
|
||||
=================
|
||||
*/
|
||||
static void Mod_LoadLump( const byte *in, const mlumpinfo_t *info, mlumpstat_t *stat, int flags )
|
||||
static void Mod_LoadLump( const byte *in, mlumpinfo_t *info, mlumpstat_t *stat, int flags )
|
||||
{
|
||||
int version = ((dheader_t *)in)->version;
|
||||
size_t numelems, real_entrysize;
|
||||
@@ -1669,9 +1677,10 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
|
||||
// mark models that have origin brushes
|
||||
if( !VectorIsNull( bm->origin ))
|
||||
SetBits( mod->flags, MODEL_HAS_ORIGIN );
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// c2a1 doesn't have origin brush it's just placed at center of the level
|
||||
if( !Q_stricmp( name, "maps/c2a1.bsp" ) && ( i == 11 ))
|
||||
if( i == 11 && !Q_stricmp( name, "maps/c2a1.bsp" ))
|
||||
SetBits( mod->flags, MODEL_HAS_ORIGIN );
|
||||
#endif
|
||||
}
|
||||
@@ -1827,7 +1836,9 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
world.generator[0] = '\0';
|
||||
world.compiler[0] = '\0';
|
||||
world.message[0] = '\0';
|
||||
world.wadlist.count = 0;
|
||||
world.litwater_minlight = -1;
|
||||
world.litwater_scale = -1.0f;
|
||||
bmod->wadlist.count = 0;
|
||||
|
||||
// parse all the wads for loading textures in right ordering
|
||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||
@@ -1870,12 +1881,12 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
// make sure that wad is really exist
|
||||
if( FS_FileExists( va( "%s.wad", token ), false ))
|
||||
{
|
||||
int num = world.wadlist.count++;
|
||||
Q_strncpy( world.wadlist.wadnames[num], token, sizeof( world.wadlist.wadnames[0] ));
|
||||
world.wadlist.wadusage[num] = 0;
|
||||
int num = bmod->wadlist.count++;
|
||||
Q_strncpy( bmod->wadlist.wadnames[num], token, sizeof( bmod->wadlist.wadnames[0] ));
|
||||
bmod->wadlist.wadusage[num] = 0;
|
||||
}
|
||||
|
||||
if( world.wadlist.count >= MAX_MAP_WADS )
|
||||
if( bmod->wadlist.count >= MAX_MAP_WADS )
|
||||
break; // too many wads...
|
||||
}
|
||||
}
|
||||
@@ -1885,6 +1896,15 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
Q_strncpy( world.compiler, token, sizeof( world.compiler ));
|
||||
else if( !Q_stricmp( keyname, "generator" ) || !Q_stricmp( keyname, "_generator" ))
|
||||
Q_strncpy( world.generator, token, sizeof( world.generator ));
|
||||
else if( !Q_stricmp( keyname, "_litwater" ))
|
||||
{
|
||||
if( Q_atoi( token ) != 0 )
|
||||
SetBits( world.flags, FWORLD_HAS_LITWATER );
|
||||
}
|
||||
else if( !Q_stricmp( keyname, "_litwater_minlight" ))
|
||||
world.litwater_minlight = Q_atoi( token );
|
||||
else if( !Q_stricmp( keyname, "_litwater_scale" ))
|
||||
world.litwater_scale = Q_atof( token );
|
||||
}
|
||||
return; // all done
|
||||
}
|
||||
@@ -2022,35 +2042,24 @@ static void Mod_LoadMarkSurfaces( model_t *mod, dbspmodel_t *bmod )
|
||||
|
||||
if( bmod->version == QBSP2_VERSION )
|
||||
{
|
||||
const dmarkface32_t *in = bmod->markfaces32;
|
||||
dmarkface32_t *in = bmod->markfaces32;
|
||||
|
||||
for( i = 0; i < bmod->nummarkfaces; i++ )
|
||||
for( i = 0; i < bmod->nummarkfaces; i++, in++ )
|
||||
{
|
||||
if( in[i] < 0 || in[i] >= mod->numsurfaces )
|
||||
Host_Error( "%s: bad surface number %i at %i (max %i) in '%s'\n", __func__, in[i], i, mod->numsurfaces, mod->name );
|
||||
out[i] = mod->surfaces + in[i];
|
||||
if( *in < 0 || *in >= mod->numsurfaces )
|
||||
Host_Error( "%s: bad surface number in '%s'\n", __func__, mod->name );
|
||||
out[i] = mod->surfaces + *in;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const dmarkface_t *in = bmod->markfaces;
|
||||
dmarkface_t *in = bmod->markfaces;
|
||||
|
||||
for( i = 0; i < bmod->nummarkfaces; i++ )
|
||||
for( i = 0; i < bmod->nummarkfaces; i++, in++ )
|
||||
{
|
||||
// NOTE: some of the buggy compilers have written a broken BSP file
|
||||
// with marksurface pointing at negative surface, for example darkf6.bsp
|
||||
// and darkf26.bsp in darkfuture mod. GoldSrc straight up writes
|
||||
// invalid pointer to a surface. Try to fix up these cases...
|
||||
if( mod->numsurfaces <= INT16_MAX && (int16_t)in[i] < 0 )
|
||||
{
|
||||
Con_Printf( S_WARN "%s: fixing up bad surface number %i at %i (max %i) in '%s'\n", __func__, in[i], i, mod->numsurfaces, mod->name );
|
||||
out[i] = mod->surfaces;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( in[i] < 0 || in[i] >= mod->numsurfaces )
|
||||
Host_Error( "%s: bad surface number %i at %i (max %i) in '%s'\n", __func__, in[i], i, mod->numsurfaces, mod->name );
|
||||
out[i] = mod->surfaces + in[i];
|
||||
if( *in < 0 || *in >= mod->numsurfaces )
|
||||
Host_Error( "%s: bad surface number in '%s'\n", __func__, mod->name );
|
||||
out[i] = mod->surfaces + *in;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2312,9 +2321,9 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
}
|
||||
|
||||
// Try WAD texture (force while r_wadtextures is 1)
|
||||
if( !texture->gl_texturenum && (( r_wadtextures.value && world.wadlist.count > 0 ) || mipTex->offsets[0] <= 0 ))
|
||||
if( !texture->gl_texturenum && (( r_wadtextures.value && bmod->wadlist.count > 0 ) || mipTex->offsets[0] <= 0 ))
|
||||
{
|
||||
int wadIndex = Mod_FindTextureInWadList( &world.wadlist, mipTex->name, texpath, sizeof( texpath ));
|
||||
int wadIndex = Mod_FindTextureInWadList( &bmod->wadlist, mipTex->name, texpath, sizeof( texpath ));
|
||||
|
||||
if( wadIndex >= 0 )
|
||||
{
|
||||
@@ -2322,7 +2331,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
if( !Host_IsDedicated( ))
|
||||
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
||||
#endif // !XASH_DEDICATED
|
||||
world.wadlist.wadusage[wadIndex]++;
|
||||
bmod->wadlist.wadusage[wadIndex]++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2380,12 +2389,12 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
// doesn't exist there. The original texture is already loaded, but cannot be modified.
|
||||
// Instead, load the original texture again and convert it to luma.
|
||||
|
||||
wadIndex = Mod_FindTextureInWadList( &world.wadlist, texture->name, texpath, sizeof( texpath ));
|
||||
wadIndex = Mod_FindTextureInWadList( &bmod->wadlist, texture->name, texpath, sizeof( texpath ));
|
||||
|
||||
if( wadIndex >= 0 )
|
||||
{
|
||||
src = FS_LoadFile( texpath, &srcSize, false );
|
||||
world.wadlist.wadusage[wadIndex]++;
|
||||
bmod->wadlist.wadusage[wadIndex]++;
|
||||
}
|
||||
|
||||
// OK, loading it from wad or hi-res version
|
||||
@@ -3418,14 +3427,18 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
|
||||
Mod_CalcPHS( mod );
|
||||
}
|
||||
|
||||
for( i = 0; i < world.wadlist.count; i++ )
|
||||
for( i = 0; i < bmod->wadlist.count; i++ )
|
||||
{
|
||||
string wadname;
|
||||
|
||||
if( !world.wadlist.wadusage[i] )
|
||||
if( !bmod->wadlist.wadusage[i] )
|
||||
continue;
|
||||
|
||||
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", world.wadlist.wadnames[i] );
|
||||
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", bmod->wadlist.wadnames[i] );
|
||||
|
||||
// a1ba: automatically precache used wad files so client will download it
|
||||
if( SV_Active( ))
|
||||
SV_GenericIndex( wadname );
|
||||
|
||||
if( !wadlist_warn )
|
||||
{
|
||||
|
||||
@@ -83,12 +83,6 @@ typedef struct
|
||||
uint num_polys;
|
||||
} hull_model_t;
|
||||
|
||||
typedef struct wadlist_s
|
||||
{
|
||||
char wadnames[MAX_MAP_WADS][32];
|
||||
int wadusage[MAX_MAP_WADS];
|
||||
int count;
|
||||
} wadlist_t;
|
||||
|
||||
typedef struct world_static_s
|
||||
{
|
||||
@@ -126,7 +120,9 @@ typedef struct world_static_s
|
||||
byte *compressed_phs;
|
||||
size_t *phsofs;
|
||||
|
||||
wadlist_t wadlist;
|
||||
// lightmapped water extra info
|
||||
float litwater_scale;
|
||||
int litwater_minlight;
|
||||
} world_static_t;
|
||||
|
||||
#ifndef REF_DLL
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
munge.c - protocol mangling for GoldSrc
|
||||
Copyright (C) ReHLDS developers
|
||||
Copyright (C) 2023 Alibek Omarov
|
||||
|
||||
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.
|
||||
*/
|
||||
#include "common.h"
|
||||
|
||||
static const byte mungify_table[] =
|
||||
{
|
||||
0x7A, 0x64, 0x05, 0xF1, 0x1B, 0x9B, 0xA0, 0xB5,
|
||||
0xCA, 0xED, 0x61, 0x0D, 0x4A, 0xDF, 0x8E, 0xC7,
|
||||
};
|
||||
|
||||
static const byte mungify_table2[] =
|
||||
{
|
||||
0x05, 0x61, 0x7A, 0xED, 0x1B, 0xCA, 0x0D, 0x9B,
|
||||
0x4A, 0xF1, 0x64, 0xC7, 0xB5, 0x8E, 0xDF, 0xA0,
|
||||
};
|
||||
|
||||
static const byte mungify_table3[] =
|
||||
{
|
||||
0x20, 0x07, 0x13, 0x61, 0x03, 0x45, 0x17, 0x72,
|
||||
0x0A, 0x2D, 0x48, 0x0C, 0x4A, 0x12, 0xA9, 0xB5,
|
||||
};
|
||||
|
||||
static int COM_SwapLong( int c )
|
||||
{
|
||||
return ((( c >> 0 ) & 0xFF) << 24 ) +
|
||||
((( c >> 8 ) & 0xFF) << 16 ) +
|
||||
((( c >> 16 ) & 0xFF) << 8 ) +
|
||||
((( c >> 24 ) & 0xFF) << 0 );
|
||||
}
|
||||
|
||||
static void COM_GenericMunge( byte *data, const size_t len, const int seq, const byte *table, const qboolean reverse )
|
||||
{
|
||||
const size_t mungelen = len / 4;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < mungelen; i++ )
|
||||
{
|
||||
uint *pc, c;
|
||||
byte *p;
|
||||
int j;
|
||||
|
||||
pc = (uint *)&data[i * 4];
|
||||
c = *pc;
|
||||
c ^= seq;
|
||||
if( !reverse )
|
||||
c = COM_SwapLong( c );
|
||||
|
||||
p = (byte *)&c;
|
||||
for( j = 0; j < 4; j++ )
|
||||
*p++ ^= (0xa5 | (j << j) | j | table[(i + j) & 0x0f]);
|
||||
|
||||
if( reverse )
|
||||
c = COM_SwapLong( c );
|
||||
c ^= ~seq;
|
||||
*pc = c;
|
||||
}
|
||||
}
|
||||
|
||||
// Anti-proxy/aimbot obfuscation code
|
||||
// COM_UnMunge should reversably fixup the data
|
||||
void COM_Munge( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table, false );
|
||||
}
|
||||
|
||||
void COM_UnMunge( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table, true );
|
||||
}
|
||||
|
||||
void COM_Munge2( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table2, false );
|
||||
}
|
||||
|
||||
void COM_UnMunge2( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table2, true );
|
||||
}
|
||||
|
||||
void COM_Munge3( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table3, false );
|
||||
}
|
||||
|
||||
void COM_UnMunge3( byte *data, size_t len, int seq )
|
||||
{
|
||||
COM_GenericMunge( data, len, seq, mungify_table3, true );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
void Test_RunMunge( void )
|
||||
{
|
||||
const char *msg = "0123456789qwertyuiopasdfghjklzxcvbnmaa";
|
||||
const char *expected[][3] =
|
||||
{
|
||||
{
|
||||
"\x33\x2a\x61\x30\x2d\x6e\x35\x74\x2d\x79\x79\x78\x73\x34\x32\x25\x30\x2f\x39\x35\x26\x3c\x33\x61\x31\x22\x78\x67\x29\x68\x6a\x6c\x7d\x7e\x72\x36\x61\x61",
|
||||
"\x69\x2a\x31\x30\x2d\x36\x25\x74\x77\x61\x79\x38\x6b\x34\x62\x25\x30\x7f\x39\x35\x76\x34\x33\x61\x39\x2a\x78\x67\x23\x68\x7a\x6c\x7d\x66\x72\x76\x61\x61",
|
||||
"\x69\x6a\x71\x30\x6f\x7e\x25\x74\x3f\x69\x69\x38\x63\x2c\x62\x25\x28\x77\x29\x75\x7c\x2c\x73\x21\x23\x62\x38\x27\x6b\x28\x2a\x6c\x3d\x3e\x72\x36\x61\x61",
|
||||
}, {
|
||||
"\x32\x2a\x61\x31\x2c\x6e\x35\x75\x2c\x79\x79\x79\x72\x34\x32\x24\x31\x2f\x39\x34\x27\x3c\x33\x60\x30\x22\x78\x66\x28\x68\x6a\x6d\x7c\x7e\x72\x37\x61\x61",
|
||||
"\x68\x2a\x31\x31\x2c\x36\x25\x75\x76\x61\x79\x39\x6a\x34\x62\x24\x31\x7f\x39\x34\x77\x34\x33\x60\x38\x2a\x78\x66\x22\x68\x7a\x6d\x7c\x66\x72\x77\x61\x61",
|
||||
"\x68\x6a\x71\x31\x6e\x7e\x25\x75\x3e\x69\x69\x39\x62\x2c\x62\x24\x29\x77\x29\x74\x7d\x2c\x73\x20\x22\x62\x38\x26\x6a\x28\x2a\x6d\x3c\x3e\x72\x37\x61\x61",
|
||||
}
|
||||
};
|
||||
string buf;
|
||||
size_t msglen = Q_strlen( msg ) + 1;
|
||||
int i;
|
||||
|
||||
Q_strncpy( buf, msg, msglen );
|
||||
|
||||
for( i = 0; i < 0xFF; i++ )
|
||||
{
|
||||
COM_Munge( buf, msglen, i );
|
||||
if( i < sizeof( expected ) / sizeof( expected[0] ))
|
||||
{
|
||||
//for( int j = 0; j < msglen; j++ )
|
||||
// printf( "\\x%02x", buf[j] );
|
||||
//printf( "\n" );
|
||||
TASSERT( !memcmp( buf, expected[i][0], msglen ));
|
||||
}
|
||||
COM_UnMunge( buf, msglen, i );
|
||||
|
||||
TASSERT( !Q_strcmp( buf, msg ));
|
||||
|
||||
COM_Munge2( buf, msglen, i );
|
||||
if( i < sizeof( expected ) / sizeof( expected[0] ))
|
||||
{
|
||||
TASSERT( !memcmp( buf, expected[i][1], msglen ));
|
||||
}
|
||||
COM_UnMunge2( buf, msglen, i );
|
||||
|
||||
TASSERT( !Q_strcmp( buf, msg ));
|
||||
|
||||
COM_Munge3( buf, msglen, i );
|
||||
if( i < sizeof( expected ) / sizeof( expected[0] ))
|
||||
{
|
||||
TASSERT( !memcmp( buf, expected[i][2], msglen ));
|
||||
}
|
||||
COM_UnMunge3( buf, msglen, i );
|
||||
|
||||
TASSERT( !Q_strcmp( buf, msg ));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -17,13 +17,15 @@ GNU General Public License for more details.
|
||||
#include "protocol.h"
|
||||
#include "net_buffer.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
//#define DEBUG_NET_MESSAGES_SEND
|
||||
//#define DEBUG_NET_MESSAGES_READ
|
||||
|
||||
// precalculated bit masks for WriteUBitLong.
|
||||
// Using these tables instead of doing the calculations
|
||||
// gives a 33% speedup in WriteUBitLong.
|
||||
static uint32_t BitWriteMasks[32][33];
|
||||
static uint32_t ExtraMasks[32];
|
||||
const char *const svc_strings[svc_lastmsg+1] =
|
||||
const char *svc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
@@ -79,7 +81,7 @@ const char *const svc_strings[svc_lastmsg+1] =
|
||||
"svc_director",
|
||||
"svc_voiceinit",
|
||||
"svc_voicedata",
|
||||
"svc_unused54",
|
||||
"svc_deltapacketbones",
|
||||
"svc_unused55",
|
||||
"svc_resourcelocation",
|
||||
"svc_querycvarvalue",
|
||||
@@ -87,7 +89,7 @@ const char *const svc_strings[svc_lastmsg+1] =
|
||||
"svc_exec",
|
||||
};
|
||||
|
||||
const char *const svc_legacy_strings[svc_lastmsg+1] =
|
||||
const char *svc_legacy_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_legacy_changing] = "svc_legacy_changing",
|
||||
[svc_legacy_ambientsound] = "svc_legacy_ambientsound",
|
||||
@@ -98,7 +100,7 @@ const char *const svc_legacy_strings[svc_lastmsg+1] =
|
||||
[svc_legacy_chokecount] = "svc_legacy_chokecount",
|
||||
};
|
||||
|
||||
const char *const svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
const char *svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_goldsrc_version] = "svc_goldsrc_version",
|
||||
[svc_goldsrc_serverinfo] = "svc_goldsrc_serverinfo",
|
||||
@@ -117,7 +119,7 @@ const char *const svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
[svc_goldsrc_sendcvarvalue2] = "svc_goldsrc_sendcvarvalue2",
|
||||
};
|
||||
|
||||
const char *const svc_quake_strings[svc_lastmsg+1] =
|
||||
const char *svc_quake_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_updatestat] = "svc_quake_updatestat",
|
||||
[svc_version] = "svc_quake_version",
|
||||
@@ -211,23 +213,17 @@ void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits )
|
||||
// do we have a valid # of bits to encode with?
|
||||
Assert( numbits >= 1 && numbits <= 32 );
|
||||
|
||||
if( sb->iAlternateSign )
|
||||
// NOTE: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
|
||||
// (Some old code writes direct integers right into the buffer).
|
||||
if( data < 0 )
|
||||
{
|
||||
MSG_WriteOneBit( sb, data < 0 ? 1 : 0 );
|
||||
MSG_WriteUBitLong( sb, (uint)abs( data ), numbits - 1 );
|
||||
MSG_WriteUBitLong( sb, (uint)( 0x80000000 + data ), numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( data < 0 )
|
||||
{
|
||||
MSG_WriteUBitLong( sb, (uint)( 0x80000000 + data ), numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteUBitLong( sb, (uint)data, numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 0 );
|
||||
}
|
||||
MSG_WriteUBitLong( sb, (uint)data, numbits - 1 );
|
||||
MSG_WriteOneBit( sb, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,30 +317,28 @@ void MSG_WriteVec3Angles( sizebuf_t *sb, const float *fa )
|
||||
|
||||
void MSG_WriteCmdExt( sizebuf_t *sb, int cmd, netsrc_t type, const char *name )
|
||||
{
|
||||
if( unlikely( net_send_debug.value ))
|
||||
#ifdef DEBUG_NET_MESSAGES_SEND
|
||||
if( name != NULL )
|
||||
{
|
||||
if( name != NULL )
|
||||
// get custom name
|
||||
Con_Printf( "^1sv^7 write: %s\n", name );
|
||||
}
|
||||
else if( type == NS_SERVER )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get custom name
|
||||
Con_Printf( "^1sv^7 (%d) write: %s\n", sb->iCurBit, name );
|
||||
}
|
||||
else if( type == NS_SERVER )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get engine message name
|
||||
Con_Printf( "^1sv^7 (%d) write: %s\n", sb->iCurBit, svc_strings[cmd] );
|
||||
}
|
||||
}
|
||||
else if( type == NS_CLIENT )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1cl^7 (%d) write: %s\n", sb->iCurBit, clc_strings[cmd] );
|
||||
}
|
||||
// get engine message name
|
||||
Con_Printf( "^1sv^7 write: %s\n", svc_strings[cmd] );
|
||||
}
|
||||
}
|
||||
|
||||
else if( type == NS_CLIENT )
|
||||
{
|
||||
if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1cl^7 write: %s\n", clc_strings[cmd] );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
MSG_WriteUBitLong( sb, cmd, sizeof( uint8_t ) << 3 );
|
||||
}
|
||||
|
||||
@@ -539,22 +533,12 @@ int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
|
||||
{
|
||||
int r, sign;
|
||||
|
||||
if( sb->iAlternateSign )
|
||||
{
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
|
||||
if( sign )
|
||||
r = -r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
|
||||
if( sign )
|
||||
r = -( BIT( numbits - 1 ) - r );
|
||||
}
|
||||
// NOTE: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
|
||||
// (Some old code writes direct integers right into the buffer).
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
if( sign ) r = -( BIT( numbits - 1 ) - r );
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -570,30 +554,22 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
|
||||
{
|
||||
int cmd = MSG_ReadUBitLong( sb, sizeof( uint8_t ) << 3 );
|
||||
|
||||
if( unlikely( net_recv_debug.value ))
|
||||
#ifdef DEBUG_NET_MESSAGES_READ
|
||||
if( type == NS_SERVER )
|
||||
{
|
||||
if( type == NS_SERVER )
|
||||
{
|
||||
Con_Printf( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
|
||||
}
|
||||
else if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1sv^7 read: %s\n", clc_strings[cmd] );
|
||||
}
|
||||
Con_Printf( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
|
||||
}
|
||||
|
||||
else if( cmd >= 0 && cmd <= clc_lastmsg )
|
||||
{
|
||||
Con_Printf( "^1sv^7 read: %s\n", clc_strings[cmd] );
|
||||
}
|
||||
#endif
|
||||
return cmd;
|
||||
}
|
||||
|
||||
int MSG_ReadChar( sizebuf_t *sb )
|
||||
{
|
||||
int alt = sb->iAlternateSign, ret;
|
||||
|
||||
sb->iAlternateSign = 0;
|
||||
ret = MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 );
|
||||
sb->iAlternateSign = alt;
|
||||
|
||||
return ret;
|
||||
return MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 );
|
||||
}
|
||||
|
||||
int MSG_ReadByte( sizebuf_t *sb )
|
||||
@@ -603,13 +579,7 @@ int MSG_ReadByte( sizebuf_t *sb )
|
||||
|
||||
int MSG_ReadShort( sizebuf_t *sb )
|
||||
{
|
||||
int alt = sb->iAlternateSign, ret;
|
||||
|
||||
sb->iAlternateSign = 0;
|
||||
ret = MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 );
|
||||
sb->iAlternateSign = alt;
|
||||
|
||||
return ret;
|
||||
return MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 );
|
||||
}
|
||||
|
||||
int MSG_ReadWord( sizebuf_t *sb )
|
||||
@@ -641,13 +611,7 @@ void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa )
|
||||
|
||||
int MSG_ReadLong( sizebuf_t *sb )
|
||||
{
|
||||
int alt = sb->iAlternateSign, ret;
|
||||
|
||||
sb->iAlternateSign = 0;
|
||||
ret = MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 );
|
||||
sb->iAlternateSign = alt;
|
||||
|
||||
return ret;
|
||||
return MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 );
|
||||
}
|
||||
|
||||
uint MSG_ReadDword( sizebuf_t *sb )
|
||||
|
||||
@@ -42,9 +42,6 @@ struct sizebuf_s
|
||||
int iCurBit;
|
||||
int nDataBits;
|
||||
const char *pDebugName; // buffer name (pointer to const name)
|
||||
|
||||
// to support GoldSrc broken signed integers
|
||||
int iAlternateSign;
|
||||
};
|
||||
|
||||
#define MSG_StartReading MSG_StartWriting
|
||||
@@ -74,7 +71,6 @@ static inline void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pDa
|
||||
sb->nDataBits = nBits;
|
||||
|
||||
sb->pDebugName = pDebugName;
|
||||
sb->iAlternateSign = 0;
|
||||
}
|
||||
|
||||
static inline void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
|
||||
@@ -173,26 +169,6 @@ static inline qboolean MSG_Overflow( sizebuf_t *sb, int nBits )
|
||||
return sb->bOverflow;
|
||||
}
|
||||
|
||||
static inline void MSG_EndBitWriting( sizebuf_t *sb )
|
||||
{
|
||||
sb->iAlternateSign--;
|
||||
|
||||
if( sb->iAlternateSign < 0 )
|
||||
{
|
||||
Con_Printf( "%s: non-even MSG_Start/EndBitWriting\n", __func__ );
|
||||
sb->iAlternateSign = 0;
|
||||
}
|
||||
|
||||
// we have native bit ops here, just pad to closest byte
|
||||
if(( sb->iCurBit & 7 ) != 0 )
|
||||
MSG_SeekToBit( sb, 8 - ( sb->iCurBit & 7 ), SEEK_CUR );
|
||||
}
|
||||
|
||||
static inline void MSG_StartBitWriting( sizebuf_t *sb )
|
||||
{
|
||||
sb->iAlternateSign++;
|
||||
}
|
||||
|
||||
void MSG_InitMasks( void ); // called once at startup engine
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ GNU General Public License for more details.
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "net_encode.h"
|
||||
#include "protocol.h"
|
||||
#if !XASH_DEDICATED
|
||||
#include <bzlib.h>
|
||||
#endif // !XASH_DEDICATED
|
||||
|
||||
#define MAKE_FRAGID( id, count ) ((( id & 0xffff ) << 16 ) | ( count & 0xffff ))
|
||||
#define FRAG_GETID( fragid ) (( fragid >> 16 ) & 0xffff )
|
||||
@@ -87,12 +84,10 @@ such as during the connection stage while waiting for the client to load,
|
||||
then a packet only needs to be delivered if there is something in the
|
||||
unacknowledged reliable
|
||||
*/
|
||||
CVAR_DEFINE_AUTO( net_showpackets, "0", FCVAR_PRIVILEGED, "show network packets" );
|
||||
CVAR_DEFINE_AUTO( net_showpackets, "0", 0, "show network packets" );
|
||||
static CVAR_DEFINE_AUTO( net_chokeloop, "0", 0, "apply bandwidth choke to loopback packets" );
|
||||
static CVAR_DEFINE_AUTO( net_showdrop, "0", 0, "show packets that are dropped" );
|
||||
static CVAR_DEFINE_AUTO( net_qport, "0", FCVAR_READ_ONLY, "current quake netport" );
|
||||
CVAR_DEFINE_AUTO( net_send_debug, "0", FCVAR_PRIVILEGED, "enable debugging output for outgoing messages" );
|
||||
CVAR_DEFINE_AUTO( net_recv_debug, "0", FCVAR_PRIVILEGED, "enable debugging output for incoming messages" );
|
||||
|
||||
int net_drop;
|
||||
netadr_t net_from;
|
||||
@@ -100,58 +95,12 @@ sizebuf_t net_message;
|
||||
static poolhandle_t net_mempool;
|
||||
byte net_message_buffer[NET_MAX_MESSAGE];
|
||||
|
||||
static const char *const ns_strings[NS_COUNT] =
|
||||
const char *ns_strings[NS_COUNT] =
|
||||
{
|
||||
"Client",
|
||||
"Server",
|
||||
};
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
void bz_internal_error( int errcode );
|
||||
void bz_internal_error( int errcode )
|
||||
{
|
||||
Con_Printf( S_ERROR "bzip2/libbzip2: internal error number %d.\n"
|
||||
"This is a bug in bzip2/libbzip2, %s.\n"
|
||||
"Please report it at: https://gitlab.com/bzip2/bzip2/-/issues\n"
|
||||
"If this happened when you were using some program which uses\n"
|
||||
"libbzip2 as a component, you should also report this bug to\n"
|
||||
"the author(s) of that program.\n"
|
||||
"Please make an effort to report this bug;\n"
|
||||
"timely and accurate bug reports eventually lead to higher\n"
|
||||
"quality software. Thanks.\n\n",
|
||||
errcode, BZ2_bzlibVersion( ));
|
||||
|
||||
if (errcode == 1007) {
|
||||
Con_Printf(
|
||||
"\n*** A special note about internal error number 1007 ***\n"
|
||||
"\n"
|
||||
"Experience suggests that a common cause of i.e. 1007\n"
|
||||
"is unreliable memory or other hardware. The 1007 assertion\n"
|
||||
"just happens to cross-check the results of huge numbers of\n"
|
||||
"memory reads/writes, and so acts (unintendedly) as a stress\n"
|
||||
"test of your memory system.\n"
|
||||
"\n"
|
||||
"I suggest the following: try compressing the file again,\n"
|
||||
"possibly monitoring progress in detail with the -vv flag.\n"
|
||||
"\n"
|
||||
"* If the error cannot be reproduced, and/or happens at different\n"
|
||||
" points in compression, you may have a flaky memory system.\n"
|
||||
" Try a memory-test program. I have used Memtest86\n"
|
||||
" (www.memtest86.com). At the time of writing it is free (GPLd).\n"
|
||||
" Memtest86 tests memory much more thorougly than your BIOSs\n"
|
||||
" power-on test, and may find failures that the BIOS doesn't.\n"
|
||||
"\n"
|
||||
"* If the error can be repeatably reproduced, this is a bug in\n"
|
||||
" bzip2, and I would very much like to hear about it. Please\n"
|
||||
" let me know, and, ideally, save a copy of the file causing the\n"
|
||||
" problem -- without which I will be unable to investigate it.\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
Sys_Error( "bzip2/libbzip2: internal error number %d\n", errcode );
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
/*
|
||||
=================================
|
||||
@@ -267,8 +216,6 @@ void Netchan_Init( void )
|
||||
Cvar_RegisterVariable( &net_chokeloop );
|
||||
Cvar_RegisterVariable( &net_showdrop );
|
||||
Cvar_RegisterVariable( &net_qport );
|
||||
Cvar_RegisterVariable( &net_send_debug );
|
||||
Cvar_RegisterVariable( &net_recv_debug );
|
||||
Cvar_FullSet( net_qport.name, buf, net_qport.flags );
|
||||
|
||||
net_mempool = Mem_AllocPool( "Network Pool" );
|
||||
@@ -318,7 +265,7 @@ Netchan_Setup
|
||||
called to open a channel to a remote system
|
||||
==============
|
||||
*/
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ), uint flags )
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ))
|
||||
{
|
||||
Netchan_Clear( chan );
|
||||
|
||||
@@ -334,10 +281,6 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, voi
|
||||
chan->qport = qport;
|
||||
chan->client = client;
|
||||
chan->pfnBlockSize = pfnBlockSize;
|
||||
chan->split = FBitSet( flags, NETCHAN_USE_LEGACY_SPLIT ) ? true : false;
|
||||
chan->use_munge = FBitSet( flags, NETCHAN_USE_MUNGE ) ? true : false;
|
||||
chan->use_bz2 = FBitSet( flags, NETCHAN_USE_BZIP2 ) ? true : false;
|
||||
chan->gs_netchan = FBitSet( flags, NETCHAN_GOLDSRC ) ? true : false;
|
||||
|
||||
MSG_Init( &chan->message, "NetData", chan->message_buf, sizeof( chan->message_buf ));
|
||||
}
|
||||
@@ -744,35 +687,15 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
|
||||
|
||||
wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t ));
|
||||
|
||||
if( chan->use_bz2 && memcmp( MSG_GetData( msg ), "BZ2", 4 ))
|
||||
if( !LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
byte pbOut[0x10000];
|
||||
uint uSourceSize = MSG_GetNumBytesWritten( msg );
|
||||
uint uCompressedSize = MSG_GetNumBytesWritten( msg ) - 4;
|
||||
if( !BZ2_bzBuffToBuffCompress( pbOut, &uCompressedSize, MSG_GetData( msg ), uSourceSize, 9, 0, 30 ))
|
||||
{
|
||||
if( uCompressedSize < uSourceSize )
|
||||
{
|
||||
Con_Reportf( "Compressing split packet with BZip2 (%d -> %d bytes)\n", uSourceSize, uCompressedSize );
|
||||
memcpy( msg->pData, "BZ2", 4 );
|
||||
memcpy( msg->pData + 4, pbOut, uCompressedSize );
|
||||
MSG_SeekToBit( msg, uCompressedSize << 3, SEEK_SET );
|
||||
}
|
||||
}
|
||||
#else
|
||||
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
|
||||
#endif
|
||||
}
|
||||
else if( !chan->use_bz2 && !LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
{
|
||||
uint uCompressedSize = 0;
|
||||
uint uSourceSize = MSG_GetNumBytesWritten( msg );
|
||||
byte *pbOut = LZSS_Compress( msg->pData, uSourceSize, &uCompressedSize );
|
||||
uint uCompressedSize = 0;
|
||||
uint uSourceSize = MSG_GetNumBytesWritten( msg );
|
||||
byte *pbOut = LZSS_Compress( msg->pData, uSourceSize, &uCompressedSize );
|
||||
|
||||
if( pbOut && uCompressedSize > 0 && uCompressedSize < uSourceSize )
|
||||
{
|
||||
Con_Reportf( "Compressing split packet with LZSS (%d -> %d bytes)\n", uSourceSize, uCompressedSize );
|
||||
Con_Reportf( "Compressing split packet (%d -> %d bytes)\n", uSourceSize, uCompressedSize );
|
||||
memcpy( msg->pData, pbOut, uCompressedSize );
|
||||
MSG_SeekToBit( msg, uCompressedSize << 3, SEEK_SET );
|
||||
}
|
||||
@@ -1017,7 +940,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
||||
Con_Printf( S_WARN "Unable to transfer %s due to path length overflow\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(( filesize = FS_FileSize( filename, false )) <= 0 )
|
||||
{
|
||||
Con_Printf( S_WARN "Unable to open %s for transfer\n", filename );
|
||||
@@ -1175,20 +1098,7 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
|
||||
p = n;
|
||||
}
|
||||
|
||||
if( chan->use_bz2 && !memcmp( MSG_GetData( msg ), "BZ2", 4 ) )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
byte buf[0x10000];
|
||||
uint uDecompressedLen = sizeof( buf );
|
||||
|
||||
BZ2_bzBuffToBuffDecompress( buf, &uDecompressedLen, MSG_GetData( msg ) + 4, MSG_GetNumBytesWritten( msg ) - 4, 1, 0 );
|
||||
memcpy( msg->pData, buf, uDecompressedLen );
|
||||
size = uDecompressedLen;
|
||||
#else
|
||||
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
|
||||
#endif
|
||||
}
|
||||
else if( !chan->use_bz2 && LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
if( LZSS_IsCompressed( MSG_GetData( msg )))
|
||||
{
|
||||
uint uDecompressedLen = LZSS_GetActualSize( MSG_GetData( msg ));
|
||||
byte buf[NET_MAX_MESSAGE];
|
||||
@@ -1225,8 +1135,7 @@ Netchan_CopyFileFragments
|
||||
*/
|
||||
qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
||||
{
|
||||
char filename[MAX_OSPATH], compressor[32];
|
||||
uint uncompressedSize;
|
||||
char filename[MAX_OSPATH];
|
||||
int nsize, pos;
|
||||
byte *buffer;
|
||||
fragbuf_t *p, *n;
|
||||
@@ -1249,12 +1158,6 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
||||
MSG_Clear( msg );
|
||||
|
||||
Q_strncpy( filename, MSG_ReadString( msg ), sizeof( filename ));
|
||||
compressor[0] = 0;
|
||||
if( chan->gs_netchan )
|
||||
{
|
||||
Q_strncpy( compressor, MSG_ReadString( msg ), sizeof( compressor ));
|
||||
uncompressedSize = MSG_ReadLong( msg );
|
||||
}
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
{
|
||||
@@ -1325,26 +1228,10 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
||||
p = n;
|
||||
}
|
||||
|
||||
if( chan->gs_netchan && chan->use_bz2 && !Q_stricmp( compressor, "bz2" ))
|
||||
if( LZSS_IsCompressed( buffer ))
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
byte *uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize );
|
||||
|
||||
Con_DPrintf( "Decompressing file %s (%d -> %d bytes)\n", filename, nsize, uncompressedSize );
|
||||
BZ2_bzBuffToBuffDecompress( uncompressedBuffer, &uncompressedSize, buffer, nsize, 1, 0 );
|
||||
Mem_Free( buffer );
|
||||
nsize = uncompressedSize;
|
||||
buffer = uncompressedBuffer;
|
||||
#else
|
||||
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
|
||||
#endif
|
||||
}
|
||||
else if( LZSS_IsCompressed( buffer ))
|
||||
{
|
||||
byte *uncompressedBuffer;
|
||||
|
||||
uncompressedSize = LZSS_GetActualSize( buffer ) + 1;
|
||||
uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize );
|
||||
uint uncompressedSize = LZSS_GetActualSize( buffer ) + 1;
|
||||
byte *uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize );
|
||||
|
||||
nsize = LZSS_Decompress( buffer, uncompressedBuffer );
|
||||
Mem_Free( buffer );
|
||||
@@ -1706,7 +1593,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
MSG_WriteLong( &send, w2 );
|
||||
|
||||
// send the qport if we are a client
|
||||
if( chan->sock == NS_CLIENT && !chan->gs_netchan )
|
||||
if( chan->sock == NS_CLIENT )
|
||||
{
|
||||
MSG_WriteWord( &send, (int)net_qport.value );
|
||||
}
|
||||
@@ -1719,16 +1606,8 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
{
|
||||
MSG_WriteByte( &send, 1 );
|
||||
MSG_WriteLong( &send, chan->reliable_fragid[i] );
|
||||
if( chan->gs_netchan )
|
||||
{
|
||||
MSG_WriteShort( &send, chan->frag_startpos[i] >> 3 );
|
||||
MSG_WriteShort( &send, chan->frag_length[i] >> 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteLong( &send, chan->frag_startpos[i] );
|
||||
MSG_WriteLong( &send, chan->frag_length[i] );
|
||||
}
|
||||
MSG_WriteLong( &send, chan->frag_startpos[i] );
|
||||
MSG_WriteLong( &send, chan->frag_length[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1785,10 +1664,6 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
int splitsize = 0;
|
||||
if( chan->pfnBlockSize )
|
||||
splitsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
|
||||
if( chan->use_munge )
|
||||
COM_Munge2( send.pData + 8, MSG_GetNumBytesWritten( &send ) - 8, (byte)( chan->outgoing_sequence - 1 ));
|
||||
|
||||
NET_SendPacketEx( chan->sock, MSG_GetNumBytesWritten( &send ), MSG_GetData( &send ), chan->remote_address, splitsize );
|
||||
}
|
||||
|
||||
@@ -1837,9 +1712,6 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
||||
sequence = MSG_ReadLong( msg );
|
||||
sequence_ack = MSG_ReadLong( msg );
|
||||
|
||||
if( chan->use_munge )
|
||||
COM_UnMunge2( msg->pData + 8, ( msg->nDataBits >> 3 ) - 8, sequence & 0xFF );
|
||||
|
||||
// read the qport if we are a server
|
||||
if( chan->sock == NS_SERVER )
|
||||
qport = MSG_ReadShort( msg );
|
||||
@@ -1857,16 +1729,8 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
||||
{
|
||||
frag_message[i] = true;
|
||||
fragid[i] = MSG_ReadLong( msg );
|
||||
if( chan->gs_netchan )
|
||||
{
|
||||
frag_offset[i] = MSG_ReadShort( msg ) << 3;
|
||||
frag_length[i] = MSG_ReadShort( msg ) << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
frag_offset[i] = MSG_ReadLong( msg );
|
||||
frag_length[i] = MSG_ReadLong( msg );
|
||||
}
|
||||
frag_offset[i] = MSG_ReadLong( msg );
|
||||
frag_length[i] = MSG_ReadLong( msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ GNU General Public License for more details.
|
||||
#define DT_TIMEWINDOW_BIG BIT( 6 ) // and re-encoded on the client relative to the client's clock
|
||||
#define DT_STRING BIT( 7 ) // A null terminated string, sent as 8 byte chars
|
||||
#define DT_SIGNED BIT( 8 ) // sign modificator
|
||||
#define DT_SIGNED_GS BIT( 31 ) // GoldSrc-specific sign modificator
|
||||
|
||||
#define NUM_FIELDS( x ) ((sizeof( x ) / sizeof( x[0] )) - 1)
|
||||
|
||||
@@ -48,7 +47,6 @@ GNU General Public License for more details.
|
||||
#define PHYS_DEF( x ) #x, offsetof( movevars_t, x ), sizeof( ((movevars_t *)0)->x )
|
||||
#define CLDT_DEF( x ) #x, offsetof( clientdata_t, x ), sizeof( ((clientdata_t *)0)->x )
|
||||
#define WPDT_DEF( x ) #x, offsetof( weapon_data_t, x ), sizeof( ((weapon_data_t *)0)->x )
|
||||
#define DESC_DEF( x ) #x, offsetof( goldsrc_delta_t, x ), sizeof( ((goldsrc_delta_t *)0)->x )
|
||||
|
||||
static qboolean delta_init = false;
|
||||
|
||||
@@ -317,18 +315,6 @@ static const delta_field_t ent_fields[] =
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static const delta_field_t meta_fields[] =
|
||||
{
|
||||
{ DESC_DEF( fieldType ), },
|
||||
{ DESC_DEF( fieldName ), },
|
||||
{ DESC_DEF( fieldOffset ), },
|
||||
{ DESC_DEF( fieldSize ), },
|
||||
{ DESC_DEF( significant_bits ), },
|
||||
{ DESC_DEF( premultiply ), },
|
||||
{ DESC_DEF( postmultiply ), },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
typedef struct delta_test_struct_t
|
||||
{
|
||||
@@ -366,6 +352,22 @@ static const delta_field_t test_fields[] =
|
||||
};
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
DT_EVENT_T = 0,
|
||||
DT_MOVEVARS_T,
|
||||
DT_USERCMD_T,
|
||||
DT_CLIENTDATA_T,
|
||||
DT_WEAPONDATA_T,
|
||||
DT_ENTITY_STATE_T,
|
||||
DT_ENTITY_STATE_PLAYER_T,
|
||||
DT_CUSTOM_ENTITY_STATE_T,
|
||||
#if XASH_ENGINE_TESTS
|
||||
DT_DELTA_TEST_STRUCT_T,
|
||||
#endif
|
||||
DT_STRUCT_COUNT
|
||||
};
|
||||
|
||||
static delta_info_t dt_info[] =
|
||||
{
|
||||
[DT_EVENT_T] = { "event_t", ev_fields, NUM_FIELDS( ev_fields ) },
|
||||
@@ -373,7 +375,7 @@ static delta_info_t dt_info[] =
|
||||
[DT_USERCMD_T] = { "usercmd_t", cmd_fields, NUM_FIELDS( cmd_fields ) },
|
||||
[DT_CLIENTDATA_T] = { "clientdata_t", cd_fields, NUM_FIELDS( cd_fields ) },
|
||||
[DT_WEAPONDATA_T] = { "weapon_data_t", wd_fields, NUM_FIELDS( wd_fields ) },
|
||||
[DT_ENTITY_STATE_T] = { "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
[DT_ENTITY_STATE_T] = { "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
[DT_ENTITY_STATE_PLAYER_T] = { "entity_state_player_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
[DT_CUSTOM_ENTITY_STATE_T] = { "custom_entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
|
||||
#if XASH_ENGINE_TESTS
|
||||
@@ -382,68 +384,6 @@ static delta_info_t dt_info[] =
|
||||
[DT_STRUCT_COUNT] = { NULL },
|
||||
};
|
||||
|
||||
// meta description is special, it cannot be overriden
|
||||
static const delta_info_t dt_goldsrc_meta =
|
||||
{
|
||||
.pName = "goldsrc_delta_t",
|
||||
.pInfo = meta_fields,
|
||||
.maxFields = NUM_FIELDS( meta_fields ),
|
||||
.numFields = NUM_FIELDS( meta_fields ),
|
||||
.pFields = (delta_t[NUM_FIELDS( meta_fields )])
|
||||
{
|
||||
{
|
||||
DESC_DEF( fieldType ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 32,
|
||||
},
|
||||
{
|
||||
DESC_DEF( fieldName ),
|
||||
.flags = DT_STRING,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 1,
|
||||
},
|
||||
{
|
||||
DESC_DEF( fieldOffset ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 16,
|
||||
},
|
||||
{
|
||||
DESC_DEF( fieldSize ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 8,
|
||||
},
|
||||
{
|
||||
DESC_DEF( significant_bits ),
|
||||
.flags = DT_INTEGER,
|
||||
.multiplier = 1.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 8,
|
||||
},
|
||||
{
|
||||
DESC_DEF( premultiply ),
|
||||
.flags = DT_FLOAT,
|
||||
.multiplier = 4000.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 32,
|
||||
},
|
||||
{
|
||||
DESC_DEF( postmultiply ),
|
||||
.flags = DT_FLOAT,
|
||||
.multiplier = 4000.0f,
|
||||
.post_multiplier = 1.0f,
|
||||
.bits = 32,
|
||||
},
|
||||
},
|
||||
.bInitialized = true
|
||||
};
|
||||
|
||||
static delta_info_t *Delta_FindStruct( const char *name )
|
||||
{
|
||||
int i;
|
||||
@@ -553,7 +493,7 @@ static qboolean Delta_AddField( delta_info_t *dt, const char *pName, int flags,
|
||||
int i;
|
||||
|
||||
// check for coexisting field
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields && pField; i++, pField++ )
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
if( !Q_strcmp( pField->name, pName ))
|
||||
{
|
||||
@@ -1048,7 +988,7 @@ compare fields by offsets
|
||||
assume from and to is valid
|
||||
=====================
|
||||
*/
|
||||
static qboolean Delta_CompareField( delta_t *pField, const void *from, const void *to )
|
||||
static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timebase )
|
||||
{
|
||||
int signbit = ( pField->flags & DT_SIGNED ) ? 1 : 0;
|
||||
float val_a, val_b;
|
||||
@@ -1169,7 +1109,7 @@ Delta_TestBaseline
|
||||
compare baselines to find optimal
|
||||
=====================
|
||||
*/
|
||||
int Delta_TestBaseline( const entity_state_t *from, const entity_state_t *to, qboolean player, double timebase )
|
||||
int Delta_TestBaseline( entity_state_t *from, entity_state_t *to, qboolean player, double timebase )
|
||||
{
|
||||
delta_info_t *dt = NULL;
|
||||
delta_t *pField;
|
||||
@@ -1205,7 +1145,7 @@ int Delta_TestBaseline( const entity_state_t *from, const entity_state_t *to, qb
|
||||
// flag about field change (sets always)
|
||||
countBits++;
|
||||
|
||||
if( !Delta_CompareField( pField, from, to ))
|
||||
if( !Delta_CompareField( pField, from, to, timebase ))
|
||||
{
|
||||
// strings are handled differently
|
||||
if( FBitSet( pField->flags, DT_STRING ))
|
||||
@@ -1226,7 +1166,7 @@ write fields by offsets
|
||||
assume from and to is valid
|
||||
=====================
|
||||
*/
|
||||
static void Delta_WriteField_( sizebuf_t *msg, delta_t *pField, const void *from, const void *to, double timebase )
|
||||
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
|
||||
{
|
||||
int signbit = FBitSet( pField->flags, DT_SIGNED ) ? 1 : 0;
|
||||
float flValue, flAngle;
|
||||
@@ -1234,6 +1174,14 @@ static void Delta_WriteField_( sizebuf_t *msg, delta_t *pField, const void *from
|
||||
int dt;
|
||||
const char *pStr;
|
||||
|
||||
if( Delta_CompareField( pField, from, to, timebase ))
|
||||
{
|
||||
MSG_WriteOneBit( msg, 0 ); // unchanged
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_WriteOneBit( msg, 1 ); // changed
|
||||
|
||||
if( pField->flags & DT_BYTE )
|
||||
{
|
||||
if( signbit )
|
||||
@@ -1307,20 +1255,6 @@ static void Delta_WriteField_( sizebuf_t *msg, delta_t *pField, const void *from
|
||||
pStr = (char *)((byte *)to + pField->offset );
|
||||
MSG_WriteString( msg, pStr );
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, const void *from, const void *to, double timebase )
|
||||
{
|
||||
if( Delta_CompareField( pField, from, to ))
|
||||
{
|
||||
MSG_WriteOneBit( msg, 0 ); // unchanged
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_WriteOneBit( msg, 1 ); // changed
|
||||
|
||||
Delta_WriteField_( msg, pField, from, to, timebase );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1330,7 +1264,7 @@ Delta_CopyField
|
||||
|
||||
====================
|
||||
*/
|
||||
static void Delta_CopyField( delta_t *pField, const void *from, void *to, double timebase )
|
||||
static void Delta_CopyField( delta_t *pField, void *from, void *to, double timebase )
|
||||
{
|
||||
qboolean bSigned = FBitSet( pField->flags, DT_SIGNED );
|
||||
uint8_t *to_field = (uint8_t *)to + pField->offset;
|
||||
@@ -1379,7 +1313,7 @@ read fields by offsets
|
||||
assume 'from' and 'to' is valid
|
||||
=====================
|
||||
*/
|
||||
static void Delta_ReadField_( sizebuf_t *msg, delta_t *pField, void *to, double timebase )
|
||||
static qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
|
||||
{
|
||||
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
|
||||
float flValue, flAngle, flTime;
|
||||
@@ -1387,6 +1321,12 @@ static void Delta_ReadField_( sizebuf_t *msg, delta_t *pField, void *to, double
|
||||
const char *pStr;
|
||||
char *pOut;
|
||||
|
||||
if( !MSG_ReadOneBit( msg ) )
|
||||
{
|
||||
Delta_CopyField( pField, from, to, timebase );
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert( pField->multiplier != 0.0f );
|
||||
|
||||
if( pField->flags & DT_BYTE )
|
||||
@@ -1470,85 +1410,9 @@ static void Delta_ReadField_( sizebuf_t *msg, delta_t *pField, void *to, double
|
||||
pOut = (char *)((byte *)to + pField->offset );
|
||||
Q_strncpy( pOut, pStr, pField->size );
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, const void *from, void *to, double timebase )
|
||||
{
|
||||
if( !MSG_ReadOneBit( msg ))
|
||||
{
|
||||
Delta_CopyField( pField, from, to, timebase );
|
||||
return false;
|
||||
}
|
||||
|
||||
Delta_ReadField_( msg, pField, to, timebase );
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Delta_ParseGSFields( sizebuf_t *msg, const delta_info_t *dt, const void *from, void *to, double timebase )
|
||||
{
|
||||
uint8_t bits[8] = { 0 };
|
||||
delta_t *pField;
|
||||
byte c;
|
||||
int i;
|
||||
|
||||
c = MSG_ReadUBitLong( msg, 3 );
|
||||
|
||||
for( i = 0; i < c; i++ )
|
||||
bits[i] = MSG_ReadByte( msg );
|
||||
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
int b = i >> 3;
|
||||
int n = 1 << ( i & 7 );
|
||||
|
||||
if( FBitSet( bits[b], n ))
|
||||
Delta_ReadField_( msg, pField, to, timebase );
|
||||
else Delta_CopyField( pField, from, to, timebase );
|
||||
}
|
||||
}
|
||||
|
||||
void Delta_ReadGSFields( sizebuf_t *msg, int index, const void *from, void *to, double timebase )
|
||||
{
|
||||
const delta_info_t *dt = Delta_FindStructByIndex( index );
|
||||
Delta_ParseGSFields( msg, dt, from, to, timebase );
|
||||
}
|
||||
|
||||
void Delta_WriteGSFields( sizebuf_t *msg, int index, const void *from, const void *to, double timebase )
|
||||
{
|
||||
delta_info_t *dt = Delta_FindStructByIndex( index );
|
||||
delta_t *pField;
|
||||
uint8_t bits[8] = { 0 };
|
||||
uint c = 0;
|
||||
int i;
|
||||
|
||||
Delta_CustomEncode( dt, from, to );
|
||||
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
if( !Delta_CompareField( pField, from, to ))
|
||||
{
|
||||
int b = i >> 3;
|
||||
int n = 1 << ( i & 7 );
|
||||
|
||||
SetBits( bits[b], n );
|
||||
c = b + 1;
|
||||
}
|
||||
}
|
||||
|
||||
MSG_WriteUBitLong( msg, c, 3 );
|
||||
for( i = 0; i < c; i++ )
|
||||
MSG_WriteByte( msg, bits[i] );
|
||||
|
||||
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
int b = i >> 3;
|
||||
int n = 1 << ( i & 7 );
|
||||
|
||||
if( FBitSet( bits[b], n ))
|
||||
Delta_WriteField_( msg, pField, from, to, timebase );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
@@ -1561,7 +1425,7 @@ usercmd_t communication
|
||||
MSG_WriteDeltaUsercmd
|
||||
=====================
|
||||
*/
|
||||
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, const usercmd_t *from, const usercmd_t *to )
|
||||
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1588,7 +1452,7 @@ void MSG_WriteDeltaUsercmd( sizebuf_t *msg, const usercmd_t *from, const usercmd
|
||||
MSG_ReadDeltaUsercmd
|
||||
=====================
|
||||
*/
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, const usercmd_t *from, usercmd_t *to )
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1623,7 +1487,7 @@ event_args_t communication
|
||||
MSG_WriteDeltaEvent
|
||||
=====================
|
||||
*/
|
||||
void MSG_WriteDeltaEvent( sizebuf_t *msg, const event_args_t *from, const event_args_t *to )
|
||||
void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1650,7 +1514,7 @@ void MSG_WriteDeltaEvent( sizebuf_t *msg, const event_args_t *from, const event_
|
||||
MSG_ReadDeltaEvent
|
||||
=====================
|
||||
*/
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, const event_args_t *from, event_args_t *to )
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1678,7 +1542,7 @@ movevars_t communication
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, const movevars_t *from, const movevars_t *to )
|
||||
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1714,7 +1578,7 @@ qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, const movevars_t *from, const m
|
||||
return true;
|
||||
}
|
||||
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, const movevars_t *from, movevars_t *to )
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1750,7 +1614,7 @@ Writes current client data only for local client
|
||||
Other clients can grab the client state from entity_state_t
|
||||
==================
|
||||
*/
|
||||
void MSG_WriteClientData( sizebuf_t *msg, const clientdata_t *from, const clientdata_t *to, double timebase )
|
||||
void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, double timebase )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1790,7 +1654,7 @@ MSG_ReadClientData
|
||||
Read the clientdata
|
||||
==================
|
||||
*/
|
||||
void MSG_ReadClientData( sizebuf_t *msg, const clientdata_t *from, clientdata_t *to, double timebase )
|
||||
void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, double timebase )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
delta_t *pField;
|
||||
@@ -1831,7 +1695,7 @@ Writes current client data only for local client
|
||||
Other clients can grab the client state from entity_state_t
|
||||
==================
|
||||
*/
|
||||
void MSG_WriteWeaponData( sizebuf_t *msg, const weapon_data_t *from, const weapon_data_t *to, double timebase, int index )
|
||||
void MSG_WriteWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, double timebase, int index )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1870,7 +1734,7 @@ MSG_ReadWeaponData
|
||||
Read the clientdata
|
||||
==================
|
||||
*/
|
||||
void MSG_ReadWeaponData( sizebuf_t *msg, const weapon_data_t *from, weapon_data_t *to, double timebase )
|
||||
void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, double timebase )
|
||||
{
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
@@ -1907,7 +1771,7 @@ If force is not set, then nothing at all will be generated if the entity is
|
||||
identical, under the assumption that the in-order delta code will catch it.
|
||||
==================
|
||||
*/
|
||||
void MSG_WriteDeltaEntity( const entity_state_t *from, const entity_state_t *to, sizebuf_t *msg, qboolean force, int delta_type, double timebase, int baseline )
|
||||
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, int delta_type, double timebase, int baseline )
|
||||
{
|
||||
delta_info_t *dt = NULL;
|
||||
delta_t *pField;
|
||||
@@ -2009,7 +1873,7 @@ If the delta removes the entity, entity_state_t->number will be set to MAX_EDICT
|
||||
Can go from either a baseline or a previous packet_entity
|
||||
==================
|
||||
*/
|
||||
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity_state_t *to, int number, int delta_type, double timebase )
|
||||
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int delta_type, double timebase )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
delta_info_t *dt = NULL;
|
||||
@@ -2018,10 +1882,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
int baseline_offset = 0;
|
||||
|
||||
if( number < 0 || number >= clgame.maxEntities )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: bad delta entity number: %i\n", __func__, number );
|
||||
return false;
|
||||
}
|
||||
Host_Error( "%s: bad delta entity number: %i\n", __func__, number );
|
||||
|
||||
fRemoveType = MSG_ReadUBitLong( msg, 2 );
|
||||
|
||||
@@ -2043,8 +1904,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
return false;
|
||||
}
|
||||
|
||||
Con_Printf( S_ERROR "%s: unknown update type %i\n", __func__, fRemoveType );
|
||||
return false;
|
||||
Host_Error( "%s: unknown update type %i\n", __func__, fRemoveType );
|
||||
}
|
||||
|
||||
if( !cls.legacymode )
|
||||
@@ -2092,11 +1952,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
|
||||
}
|
||||
|
||||
if( !dt || !dt->bInitialized )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: broken delta\n", __func__ );
|
||||
return true;
|
||||
}
|
||||
Assert( dt && dt->bInitialized );
|
||||
|
||||
pField = dt->pFields;
|
||||
Assert( pField != NULL );
|
||||
@@ -2111,44 +1967,6 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity
|
||||
return true;
|
||||
}
|
||||
|
||||
void Delta_ParseTableField_GS( sizebuf_t *msg )
|
||||
{
|
||||
const char *s = MSG_ReadString( msg );
|
||||
delta_info_t *dt = Delta_FindStruct( s );
|
||||
goldsrc_delta_t null = { 0 };
|
||||
int i, num_fields;
|
||||
|
||||
// delta encoders it's already initialized on this machine (local game)
|
||||
if( delta_init )
|
||||
Delta_Shutdown();
|
||||
|
||||
if( !dt )
|
||||
Host_Error( "%s: not initialized", __func__ );
|
||||
|
||||
num_fields = MSG_ReadShort( msg );
|
||||
if( num_fields > dt->maxFields )
|
||||
Host_Error( "%s: numFields > maxFields", __func__ );
|
||||
|
||||
MSG_StartBitWriting( msg );
|
||||
|
||||
for( i = 0; i < num_fields; i++ )
|
||||
{
|
||||
goldsrc_delta_t to;
|
||||
|
||||
Delta_ParseGSFields( msg, &dt_goldsrc_meta, &null, &to, 0.0f );
|
||||
|
||||
// patch our DT_SIGNED flag
|
||||
if( FBitSet( to.fieldType, DT_SIGNED_GS ))
|
||||
{
|
||||
ClearBits( to.fieldType, DT_SIGNED_GS );
|
||||
SetBits( to.fieldType, DT_SIGNED );
|
||||
}
|
||||
Delta_AddField( dt, to.fieldName, to.fieldType, to.significant_bits, to.premultiply, to.postmultiply );
|
||||
}
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Delta_WriteDescriptionToClient
|
||||
|
||||
@@ -33,22 +33,6 @@ enum
|
||||
DELTA_STATIC,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DT_EVENT_T = 0,
|
||||
DT_MOVEVARS_T,
|
||||
DT_USERCMD_T,
|
||||
DT_CLIENTDATA_T,
|
||||
DT_WEAPONDATA_T,
|
||||
DT_ENTITY_STATE_T,
|
||||
DT_ENTITY_STATE_PLAYER_T,
|
||||
DT_CUSTOM_ENTITY_STATE_T,
|
||||
#if XASH_ENGINE_TESTS
|
||||
DT_DELTA_TEST_STRUCT_T,
|
||||
#endif
|
||||
DT_STRUCT_COUNT
|
||||
};
|
||||
|
||||
// struct info (filled by engine)
|
||||
typedef struct
|
||||
{
|
||||
@@ -70,17 +54,6 @@ struct delta_s
|
||||
qboolean bInactive; // unsetted by user request
|
||||
};
|
||||
|
||||
typedef struct goldsrc_delta_s
|
||||
{
|
||||
int fieldType;
|
||||
char fieldName[32];
|
||||
int fieldOffset;
|
||||
short fieldSize;
|
||||
int significant_bits;
|
||||
float premultiply;
|
||||
float postmultiply;
|
||||
} goldsrc_delta_t;
|
||||
|
||||
typedef void (*pfnDeltaEncode)( struct delta_s *pFields, const byte *from, const byte *to );
|
||||
|
||||
typedef struct
|
||||
@@ -114,7 +87,6 @@ void Delta_UnsetFieldByIndex( delta_t *pFields, int fieldNumber );
|
||||
// send table over network
|
||||
void Delta_WriteDescriptionToClient( sizebuf_t *msg );
|
||||
void Delta_ParseTableField( sizebuf_t *msg );
|
||||
void Delta_ParseTableField_GS( sizebuf_t *msg );
|
||||
|
||||
|
||||
// encode routines
|
||||
@@ -124,20 +96,18 @@ struct event_args_s;
|
||||
struct movevars_s;
|
||||
struct clientdata_s;
|
||||
struct weapon_data_s;
|
||||
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, const struct usercmd_s *from, const struct usercmd_s *to );
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, const struct usercmd_s *from, struct usercmd_s *to );
|
||||
void MSG_WriteDeltaEvent( sizebuf_t *msg, const struct event_args_s *from, const struct event_args_s *to );
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, const struct event_args_s *from, struct event_args_s *to );
|
||||
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, const struct movevars_s *from, const struct movevars_s *to );
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, const struct movevars_s *from, struct movevars_s *to );
|
||||
void MSG_WriteClientData( sizebuf_t *msg, const struct clientdata_s *from, const struct clientdata_s *to, double timebase );
|
||||
void MSG_ReadClientData( sizebuf_t *msg, const struct clientdata_s *from, struct clientdata_s *to, double timebase );
|
||||
void MSG_WriteWeaponData( sizebuf_t *msg, const struct weapon_data_s *from, const struct weapon_data_s *to, double timebase, int index );
|
||||
void MSG_ReadWeaponData( sizebuf_t *msg, const struct weapon_data_s *from, struct weapon_data_s *to, double timebase );
|
||||
void MSG_WriteDeltaEntity( const struct entity_state_s *from, const struct entity_state_s *to, sizebuf_t *msg, qboolean force, int type, double timebase, int ofs );
|
||||
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const struct entity_state_s *from, struct entity_state_s *to, int num, int type, double timebase );
|
||||
int Delta_TestBaseline( const struct entity_state_s *from, const struct entity_state_s *to, qboolean player, double timebase );
|
||||
void Delta_ReadGSFields( sizebuf_t *msg, int index, const void *from, void *to, double timebase );
|
||||
void Delta_WriteGSFields( sizebuf_t *msg, int index, const void *from, const void *to, double timebase );
|
||||
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
void MSG_WriteDeltaEvent( sizebuf_t *msg, struct event_args_s *from, struct event_args_s *to );
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, struct event_args_s *from, struct event_args_s *to );
|
||||
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, struct movevars_s *from, struct movevars_s *to );
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, struct movevars_s *from, struct movevars_s *to );
|
||||
void MSG_WriteClientData( sizebuf_t *msg, struct clientdata_s *from, struct clientdata_s *to, double timebase );
|
||||
void MSG_ReadClientData( sizebuf_t *msg, struct clientdata_s *from, struct clientdata_s *to, double timebase );
|
||||
void MSG_WriteWeaponData( sizebuf_t *msg, struct weapon_data_s *from, struct weapon_data_s *to, double timebase, int index );
|
||||
void MSG_ReadWeaponData( sizebuf_t *msg, struct weapon_data_s *from, struct weapon_data_s *to, double timebase );
|
||||
void MSG_WriteDeltaEntity( struct entity_state_s *from, struct entity_state_s *to, sizebuf_t *msg, qboolean force, int type, double timebase, int ofs );
|
||||
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, struct entity_state_s *from, struct entity_state_s *to, int num, int type, double timebase );
|
||||
int Delta_TestBaseline( struct entity_state_s *from, struct entity_state_s *to, qboolean player, double timebase );
|
||||
|
||||
#endif//NET_ENCODE_H
|
||||
|
||||
@@ -18,20 +18,16 @@ GNU General Public License for more details.
|
||||
#include "netchan.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "ipv6text.h"
|
||||
|
||||
#if XASH_NO_NETWORK
|
||||
#include "platform/stub/net_stub.h"
|
||||
#elif XASH_WIN32
|
||||
#if XASH_WIN32
|
||||
#include "platform/win32/net.h"
|
||||
#elif XASH_PSVITA
|
||||
#include "platform/psvita/net_psvita.h"
|
||||
static const struct in6_addr in6addr_any;
|
||||
#elif defined XASH_NO_NETWORK
|
||||
#include "platform/stub/net_stub.h"
|
||||
#else
|
||||
#include "platform/posix/net.h"
|
||||
#endif
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL_thread.h>
|
||||
#if XASH_PSVITA
|
||||
#include "platform/psvita/net_psvita.h"
|
||||
static const struct in6_addr in6addr_any;
|
||||
#endif
|
||||
|
||||
#define NET_USE_FRAGMENTS
|
||||
@@ -39,11 +35,10 @@ static const struct in6_addr in6addr_any;
|
||||
#define MAX_LOOPBACK 4
|
||||
#define MASK_LOOPBACK (MAX_LOOPBACK - 1)
|
||||
|
||||
#define MAX_ROUTEABLE_PACKET 1400
|
||||
#define SPLITPACKET_MIN_SIZE 508 // RFC 791: 576(min ip packet) - 60 (ip header) - 8 (udp header)
|
||||
#define SPLITPACKET_MAX_SIZE 64000
|
||||
#define NET_MAX_FRAGMENTS ( NET_MAX_FRAGMENT / (SPLITPACKET_MIN_SIZE - sizeof( SPLITPACKET )))
|
||||
#define NET_MAX_GOLDSRC_FRAGMENTS 5 // magic number
|
||||
#define MAX_ROUTEABLE_PACKET 1400
|
||||
#define SPLITPACKET_MIN_SIZE 508 // RFC 791: 576(min ip packet) - 60 (ip header) - 8 (udp header)
|
||||
#define SPLITPACKET_MAX_SIZE 64000
|
||||
#define NET_MAX_FRAGMENTS ( NET_MAX_FRAGMENT / (SPLITPACKET_MIN_SIZE - sizeof( SPLITPACKET )))
|
||||
|
||||
// ff02:1
|
||||
static const uint8_t k_ipv6Bytes_LinkLocalAllNodes[16] =
|
||||
@@ -88,13 +83,6 @@ typedef struct
|
||||
int sequence_number;
|
||||
short packet_id;
|
||||
} SPLITPACKET;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int net_id;
|
||||
int sequence_number;
|
||||
unsigned char packet_id;
|
||||
} SPLITPACKETGS;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct
|
||||
@@ -127,7 +115,6 @@ static CVAR_DEFINE( net_ipclientport, "ip_clientport", "0", FCVAR_READ_ONLY, "ne
|
||||
static CVAR_DEFINE( net_clientport, "clientport", "0", FCVAR_READ_ONLY, "network default client port" );
|
||||
static CVAR_DEFINE( net_fakelag, "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." );
|
||||
static CVAR_DEFINE( net_fakeloss, "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
|
||||
static CVAR_DEFINE_AUTO( net_resolve_debug, "0", FCVAR_PRIVILEGED, "print resolve thread debug messages" );
|
||||
CVAR_DEFINE( net_clockwindow, "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
|
||||
|
||||
netadr_t net_local;
|
||||
@@ -139,14 +126,12 @@ static CVAR_DEFINE( net_ip6hostport, "ip6_hostport", "0", FCVAR_READ_ONLY, "netw
|
||||
static CVAR_DEFINE( net_ip6clientport, "ip6_clientport", "0", FCVAR_READ_ONLY, "network ip6 client port" );
|
||||
static CVAR_DEFINE_AUTO( net6_address, "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local IPv6 address of current client" );
|
||||
|
||||
static void NET_ClearLagData( qboolean bClient, qboolean bServer );
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_ErrorString
|
||||
====================
|
||||
*/
|
||||
static const char *NET_ErrorString( void )
|
||||
static char *NET_ErrorString( void )
|
||||
{
|
||||
#if XASH_WIN32
|
||||
int err = WSANOTINITIALISED;
|
||||
@@ -207,7 +192,7 @@ static const char *NET_ErrorString( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline socklen_t NET_SockAddrLen( const struct sockaddr_storage *addr )
|
||||
_inline socklen_t NET_SockAddrLen( const struct sockaddr_storage *addr )
|
||||
{
|
||||
switch ( addr->ss_family )
|
||||
{
|
||||
@@ -220,7 +205,7 @@ static inline socklen_t NET_SockAddrLen( const struct sockaddr_storage *addr )
|
||||
}
|
||||
}
|
||||
|
||||
static inline qboolean NET_IsSocketError( int retval )
|
||||
_inline qboolean NET_IsSocketError( int retval )
|
||||
{
|
||||
#if XASH_WIN32 || XASH_DOS4GW
|
||||
return retval == SOCKET_ERROR ? true : false;
|
||||
@@ -229,7 +214,7 @@ static inline qboolean NET_IsSocketError( int retval )
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline qboolean NET_IsSocketValid( int socket )
|
||||
_inline qboolean NET_IsSocketValid( int socket )
|
||||
{
|
||||
#if XASH_WIN32 || XASH_DOS4GW
|
||||
return socket != INVALID_SOCKET;
|
||||
@@ -264,27 +249,40 @@ static void NET_NetadrToSockadr( netadr_t *a, struct sockaddr_storage *s )
|
||||
|
||||
if( a->type == NA_BROADCAST )
|
||||
{
|
||||
s->ss_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
||||
}
|
||||
else if( a->type == NA_IP )
|
||||
{
|
||||
s->ss_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||
((struct sockaddr_in *)s)->sin_addr.s_addr = a->ip4;
|
||||
}
|
||||
else if( a->type6 == NA_IP6 )
|
||||
{
|
||||
s->ss_family = AF_INET6;
|
||||
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
||||
NET_NetadrToIP6Bytes(((struct sockaddr_in6 *)s)->sin6_addr.s6_addr, a );
|
||||
struct in6_addr ip6;
|
||||
|
||||
NET_NetadrToIP6Bytes( ip6.s6_addr, a );
|
||||
|
||||
if( IN6_IS_ADDR_V4MAPPED( &ip6 ))
|
||||
{
|
||||
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_addr.s_addr = *(uint32_t *)(ip6.s6_addr + 12);
|
||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||
}
|
||||
else
|
||||
{
|
||||
((struct sockaddr_in6 *)s)->sin6_family = AF_INET6;
|
||||
memcpy( &((struct sockaddr_in6 *)s)->sin6_addr, &ip6, sizeof( struct in6_addr ));
|
||||
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
||||
}
|
||||
}
|
||||
else if( a->type6 == NA_MULTICAST_IP6 )
|
||||
{
|
||||
s->ss_family = AF_INET6;
|
||||
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
||||
((struct sockaddr_in6 *)s)->sin6_family = AF_INET6;
|
||||
memcpy(((struct sockaddr_in6 *)s)->sin6_addr.s6_addr, k_ipv6Bytes_LinkLocalAllNodes, sizeof( struct in6_addr ));
|
||||
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,8 +301,13 @@ static void NET_SockadrToNetadr( const struct sockaddr_storage *s, netadr_t *a )
|
||||
}
|
||||
else if( s->ss_family == AF_INET6 )
|
||||
{
|
||||
a->type6 = NA_IP6;
|
||||
NET_IP6BytesToNetadr( a, ((struct sockaddr_in6 *)s)->sin6_addr.s6_addr );
|
||||
|
||||
if( IN6_IS_ADDR_V4MAPPED( &((struct sockaddr_in6 *)s)->sin6_addr ))
|
||||
a->type = NA_IP;
|
||||
else
|
||||
a->type6 = NA_IP6;
|
||||
|
||||
a->port = ((struct sockaddr_in6 *)s)->sin6_port;
|
||||
}
|
||||
}
|
||||
@@ -321,11 +324,6 @@ static qboolean NET_GetHostByName( const char *hostname, int family, struct sock
|
||||
struct addrinfo hints;
|
||||
qboolean ret = false;
|
||||
|
||||
#if XASH_NO_IPV6_RESOLVE
|
||||
if( family == AF_INET6 )
|
||||
return false;
|
||||
#endif
|
||||
|
||||
memset( &hints, 0, sizeof( hints ));
|
||||
hints.ai_family = family;
|
||||
|
||||
@@ -348,12 +346,6 @@ static qboolean NET_GetHostByName( const char *hostname, int family, struct sock
|
||||
return ret;
|
||||
#else
|
||||
struct hostent *h;
|
||||
|
||||
#if XASH_NO_IPV6_RESOLVE
|
||||
if( family == AF_INET6 )
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if(!( h = gethostbyname( hostname )))
|
||||
return false;
|
||||
|
||||
@@ -371,44 +363,27 @@ static qboolean NET_GetHostByName( const char *hostname, int family, struct sock
|
||||
#ifdef CAN_ASYNC_NS_RESOLVE
|
||||
static void NET_ResolveThread( void );
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#define mutex_create( x ) (( x ) = SDL_CreateMutex() )
|
||||
#define mutex_destroy( x ) SDL_DestroyMutex(( x ))
|
||||
#define mutex_lock( x ) SDL_LockMutex(( x ))
|
||||
#define mutex_unlock( x ) SDL_UnlockMutex(( x ))
|
||||
#define create_thread( thread, pfn ) (( thread ) = SDL_CreateThread(( pfn ), "DNS resolver thread", NULL ))
|
||||
#define detach_thread( x ) SDL_DetachThread(( x ))
|
||||
typedef SDL_mutex *mutex_t;
|
||||
typedef SDL_Thread *thread_t;
|
||||
static int NET_ThreadStart( void *ununsed )
|
||||
{
|
||||
NET_ResolveThread();
|
||||
return 0;
|
||||
}
|
||||
#elif !XASH_WIN32
|
||||
#if !XASH_WIN32
|
||||
#include <pthread.h>
|
||||
#define mutex_create( x ) pthread_mutex_init( &( x ), NULL )
|
||||
#define mutex_destroy( x ) pthread_mutex_destroy( &( x ))
|
||||
#define mutex_lock( x ) pthread_mutex_lock( &( x ))
|
||||
#define mutex_unlock( x ) pthread_mutex_unlock( &( x ))
|
||||
#define create_thread( thread, pfn ) !pthread_create( &( thread ), NULL, ( pfn ), NULL )
|
||||
#define detach_thread( x ) pthread_detach( x )
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
typedef pthread_t thread_t;
|
||||
#define mutex_lock pthread_mutex_lock
|
||||
#define mutex_unlock pthread_mutex_unlock
|
||||
#define exit_thread( x ) pthread_exit(x)
|
||||
#define create_thread( pfn ) !pthread_create( &nsthread.thread, NULL, (pfn), NULL )
|
||||
#define detach_thread( x ) pthread_detach(x)
|
||||
#define mutex_t pthread_mutex_t
|
||||
#define thread_t pthread_t
|
||||
static void *NET_ThreadStart( void *unused )
|
||||
{
|
||||
NET_ResolveThread();
|
||||
return NULL;
|
||||
}
|
||||
#else // WIN32
|
||||
#define mutex_create( x ) InitializeCriticalSection( &( x ))
|
||||
#define mutex_destroy( x ) DeleteCriticalSection( &( x ))
|
||||
#define mutex_lock( x ) EnterCriticalSection( &( x ))
|
||||
#define mutex_unlock( x ) LeaveCriticalSection( &( x ))
|
||||
#define create_thread( thread, pfn ) (( thread ) = CreateThread( NULL, 0, ( pfn ), NULL, 0, NULL ))
|
||||
#define detach_thread( x ) CloseHandle(( x ))
|
||||
typedef CRITICAL_SECTION mutex_t;
|
||||
typedef HANDLE thread_t;
|
||||
#define mutex_lock EnterCriticalSection
|
||||
#define mutex_unlock LeaveCriticalSection
|
||||
#define detach_thread( x ) CloseHandle(x)
|
||||
#define create_thread( pfn ) ( nsthread.thread = CreateThread( NULL, 0, pfn, NULL, 0, NULL ))
|
||||
#define mutex_t CRITICAL_SECTION
|
||||
#define thread_t HANDLE
|
||||
DWORD WINAPI NET_ThreadStart( LPVOID unused )
|
||||
{
|
||||
NET_ResolveThread();
|
||||
@@ -417,42 +392,38 @@ DWORD WINAPI NET_ThreadStart( LPVOID unused )
|
||||
}
|
||||
#endif // !_WIN32
|
||||
|
||||
#define RESOLVE_DBG( x ) do { if( net_resolve_debug.value ) Sys_PrintLog(( x )); } while( 0 )
|
||||
#ifdef DEBUG_RESOLVE
|
||||
#define RESOLVE_DBG(x) Sys_PrintLog(x)
|
||||
#else
|
||||
#define RESOLVE_DBG(x)
|
||||
#endif // DEBUG_RESOLVE
|
||||
|
||||
static struct nsthread_s
|
||||
{
|
||||
mutex_t mutexns;
|
||||
mutex_t mutexres;
|
||||
mutex_t mutexns;
|
||||
mutex_t mutexres;
|
||||
thread_t thread;
|
||||
int result;
|
||||
string hostname;
|
||||
int family;
|
||||
int result;
|
||||
string hostname;
|
||||
int family;
|
||||
struct sockaddr_storage addr;
|
||||
qboolean busy;
|
||||
} nsthread;
|
||||
} nsthread
|
||||
#if !XASH_WIN32
|
||||
= { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }
|
||||
#endif
|
||||
;
|
||||
|
||||
static void NET_InitializeCriticalSections( void )
|
||||
{
|
||||
net.threads_initialized = true;
|
||||
|
||||
mutex_create( nsthread.mutexns );
|
||||
mutex_create( nsthread.mutexres );
|
||||
#if XASH_WIN32
|
||||
InitializeCriticalSection( &nsthread.mutexns );
|
||||
InitializeCriticalSection( &nsthread.mutexres );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void NET_DeleteCriticalSections( void )
|
||||
{
|
||||
if( net.threads_initialized )
|
||||
{
|
||||
mutex_destroy( nsthread.mutexns );
|
||||
mutex_destroy( nsthread.mutexres );
|
||||
|
||||
net.threads_initialized = false;
|
||||
}
|
||||
|
||||
memset( &nsthread, 0, sizeof( nsthread ));
|
||||
}
|
||||
|
||||
static void NET_ResolveThread( void )
|
||||
void NET_ResolveThread( void )
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
qboolean res;
|
||||
@@ -469,12 +440,12 @@ static void NET_ResolveThread( void )
|
||||
RESOLVE_DBG( "[resolve thread] success\n" );
|
||||
else
|
||||
RESOLVE_DBG( "[resolve thread] failed\n" );
|
||||
mutex_lock( nsthread.mutexres );
|
||||
mutex_lock( &nsthread.mutexres );
|
||||
nsthread.addr = addr;
|
||||
nsthread.busy = false;
|
||||
nsthread.result = res ? NET_EAI_OK : NET_EAI_NONAME;
|
||||
RESOLVE_DBG( "[resolve thread] returning result\n" );
|
||||
mutex_unlock( nsthread.mutexres );
|
||||
mutex_unlock( &nsthread.mutexres );
|
||||
RESOLVE_DBG( "[resolve thread] exiting thread\n" );
|
||||
}
|
||||
#endif // CAN_ASYNC_NS_RESOLVE
|
||||
@@ -539,11 +510,11 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
|
||||
#ifdef CAN_ASYNC_NS_RESOLVE
|
||||
if( net.threads_initialized && nonblocking )
|
||||
{
|
||||
mutex_lock( nsthread.mutexres );
|
||||
mutex_lock( &nsthread.mutexres );
|
||||
|
||||
if( nsthread.busy )
|
||||
{
|
||||
mutex_unlock( nsthread.mutexres );
|
||||
mutex_unlock( &nsthread.mutexres );
|
||||
return NET_EAI_AGAIN;
|
||||
}
|
||||
|
||||
@@ -564,24 +535,28 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
|
||||
Q_strncpy( nsthread.hostname, copy, sizeof( nsthread.hostname ));
|
||||
nsthread.family = family;
|
||||
nsthread.busy = true;
|
||||
mutex_unlock( nsthread.mutexres );
|
||||
mutex_unlock( &nsthread.mutexres );
|
||||
|
||||
if( create_thread( nsthread.thread, NET_ThreadStart ))
|
||||
if( create_thread( NET_ThreadStart ))
|
||||
{
|
||||
asyncfailed = false;
|
||||
return NET_EAI_AGAIN;
|
||||
}
|
||||
|
||||
Con_Reportf( S_ERROR "%s: failed to create thread!\n", __func__ );
|
||||
nsthread.busy = false;
|
||||
else // failed to create thread
|
||||
{
|
||||
Con_Reportf( S_ERROR "%s: failed to create thread!\n", __func__ );
|
||||
nsthread.busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock( nsthread.mutexres );
|
||||
mutex_unlock( &nsthread.mutexres );
|
||||
}
|
||||
#endif // CAN_ASYNC_NS_RESOLVE
|
||||
|
||||
if( asyncfailed )
|
||||
{
|
||||
ret = NET_GetHostByName( copy, family, &temp );
|
||||
}
|
||||
|
||||
if( !ret )
|
||||
{
|
||||
@@ -595,9 +570,16 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
|
||||
sadr->ss_family = temp.ss_family;
|
||||
|
||||
if( temp.ss_family == AF_INET )
|
||||
((struct sockaddr_in *)sadr)->sin_addr = ((struct sockaddr_in*)&temp)->sin_addr;
|
||||
{
|
||||
((struct sockaddr_in *)sadr)->sin_addr =
|
||||
((struct sockaddr_in*)&temp)->sin_addr;
|
||||
}
|
||||
else if( temp.ss_family == AF_INET6 )
|
||||
((struct sockaddr_in6 *)sadr)->sin6_addr = ((struct sockaddr_in6*)&temp)->sin6_addr;
|
||||
{
|
||||
memcpy(&((struct sockaddr_in6 *)sadr)->sin6_addr,
|
||||
&((struct sockaddr_in6*)&temp)->sin6_addr,
|
||||
sizeof( struct in6_addr ));
|
||||
}
|
||||
}
|
||||
|
||||
return NET_EAI_OK;
|
||||
@@ -1060,20 +1042,19 @@ qboolean NET_StringToAdr( const char *string, netadr_t *adr )
|
||||
return NET_StringToAdrEx( string, adr, AF_UNSPEC );
|
||||
}
|
||||
|
||||
net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v6only )
|
||||
net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr )
|
||||
{
|
||||
struct sockaddr_storage s;
|
||||
net_gai_state_t res;
|
||||
|
||||
memset( adr, 0, sizeof( netadr_t ));
|
||||
|
||||
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
|
||||
{
|
||||
adr->type = NA_LOOPBACK;
|
||||
return NET_EAI_OK;
|
||||
}
|
||||
|
||||
res = NET_StringToSockaddr( string, &s, true, v6only ? AF_INET6 : AF_UNSPEC );
|
||||
res = NET_StringToSockaddr( string, &s, true, AF_UNSPEC );
|
||||
|
||||
if( res == NET_EAI_OK )
|
||||
NET_SockadrToNetadr( &s, adr );
|
||||
@@ -1358,49 +1339,30 @@ NET_GetLong
|
||||
receive long packet from network
|
||||
==================
|
||||
*/
|
||||
static qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsize, connprotocol_t proto )
|
||||
static qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsize )
|
||||
{
|
||||
int i, sequence_number, offset;
|
||||
SPLITPACKET *pHeader = (SPLITPACKET *)pData;
|
||||
int packet_number;
|
||||
int packet_count;
|
||||
short packet_id;
|
||||
size_t header_size = proto == PROTO_GOLDSRC ? sizeof( SPLITPACKETGS ) : sizeof( SPLITPACKET );
|
||||
int body_size = splitsize - header_size;
|
||||
int max_splits;
|
||||
int body_size = splitsize - sizeof( SPLITPACKET );
|
||||
|
||||
if( body_size < 0 )
|
||||
return false;
|
||||
|
||||
if( size < header_size )
|
||||
if( size < sizeof( SPLITPACKET ))
|
||||
{
|
||||
Con_Printf( S_ERROR "invalid split packet length %i\n", size );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
SPLITPACKETGS *pHeader = (SPLITPACKETGS *)pData;
|
||||
sequence_number = pHeader->sequence_number;
|
||||
packet_id = pHeader->packet_id;
|
||||
packet_count = ( packet_id & 0xFF );
|
||||
packet_number = ( packet_id >> 8 );
|
||||
|
||||
sequence_number = pHeader->sequence_number;
|
||||
packet_id = pHeader->packet_id;
|
||||
packet_count = ( packet_id & 0xF );
|
||||
packet_number = ( packet_id >> 4 );
|
||||
|
||||
max_splits = NET_MAX_GOLDSRC_FRAGMENTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
SPLITPACKET *pHeader = (SPLITPACKET *)pData;
|
||||
|
||||
sequence_number = pHeader->sequence_number;
|
||||
packet_id = pHeader->packet_id;
|
||||
packet_count = ( packet_id & 0xFF );
|
||||
packet_number = ( packet_id >> 8 );
|
||||
|
||||
max_splits = ARRAYSIZE( net.split_flags );
|
||||
}
|
||||
|
||||
if( packet_number >= max_splits || packet_count > max_splits )
|
||||
if( packet_number >= NET_MAX_FRAGMENTS || packet_count > NET_MAX_FRAGMENTS )
|
||||
{
|
||||
Con_Printf( S_ERROR "malformed packet number (%i/%i)\n", packet_number + 1, packet_count );
|
||||
return false;
|
||||
@@ -1413,14 +1375,14 @@ static qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsi
|
||||
net.split.total_size = 0;
|
||||
|
||||
// clear part's sequence
|
||||
for( i = 0; i < ARRAYSIZE( net.split_flags ); i++ )
|
||||
for( i = 0; i < NET_MAX_FRAGMENTS; i++ )
|
||||
net.split_flags[i] = -1;
|
||||
|
||||
if( net_showpackets.value == 4.0f )
|
||||
Con_Printf( "<-- Split packet restart %i count %i seq\n", net.split.split_count, sequence_number );
|
||||
}
|
||||
|
||||
size -= header_size;
|
||||
size -= sizeof( SPLITPACKET );
|
||||
|
||||
if( net.split_flags[packet_number] != sequence_number )
|
||||
{
|
||||
@@ -1439,7 +1401,7 @@ static qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsi
|
||||
}
|
||||
|
||||
offset = (packet_number * body_size);
|
||||
memcpy( net.split.buffer + offset, pData + header_size, size );
|
||||
memcpy( net.split.buffer + offset, pData + sizeof( SPLITPACKET ), size );
|
||||
|
||||
// have we received all of the pieces to the packet?
|
||||
if( net.split.split_count <= 0 )
|
||||
@@ -1502,15 +1464,13 @@ static qboolean NET_QueuePacket( netsrc_t sock, netadr_t *from, byte *data, size
|
||||
memcpy( data, buf, ret );
|
||||
*length = ret;
|
||||
#if !XASH_DEDICATED
|
||||
if( CL_LegacyMode( ))
|
||||
return NET_LagPacket( true, sock, from, length, data );
|
||||
|
||||
// check for split message
|
||||
if( sock == NS_CLIENT && *(int *)data == NET_HEADER_SPLITPACKET )
|
||||
{
|
||||
connprotocol_t proto = CL_Protocol();
|
||||
|
||||
if( proto == PROTO_LEGACY )
|
||||
return NET_LagPacket( true, sock, from, length, data );
|
||||
|
||||
// check for split message
|
||||
if( sock == NS_CLIENT && *(int *)data == NET_HEADER_SPLITPACKET )
|
||||
return NET_GetLong( data, ret, length, CL_GetSplitSize( ), proto );
|
||||
return NET_GetLong( data, ret, length, CL_GetSplitSize( ));
|
||||
}
|
||||
#endif
|
||||
// lag the packet, if needed
|
||||
@@ -1775,7 +1735,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
|
||||
if( COM_CheckStringEmpty( net_iface ) && Q_stricmp( net_iface, "localhost" ))
|
||||
NET_StringToSockaddr( net_iface, &addr, false, AF_INET6 );
|
||||
else ((struct sockaddr_in6 *)&addr)->sin6_addr = in6addr_any;
|
||||
else memcpy(((struct sockaddr_in6 *)&addr)->sin6_addr.s6_addr, &in6addr_any, sizeof( struct in6_addr ));
|
||||
|
||||
if( port == PORT_ANY ) ((struct sockaddr_in6 *)&addr)->sin6_port = 0;
|
||||
else ((struct sockaddr_in6 *)&addr)->sin6_port = htons((short)port);
|
||||
@@ -2108,7 +2068,7 @@ NET_ClearLagData
|
||||
clear fakelag list
|
||||
====================
|
||||
*/
|
||||
static void NET_ClearLagData( qboolean bClient, qboolean bServer )
|
||||
void NET_ClearLagData( qboolean bClient, qboolean bServer )
|
||||
{
|
||||
if( bClient ) NET_ClearLaggedList( &net.lagdata[NS_CLIENT] );
|
||||
if( bServer ) NET_ClearLaggedList( &net.lagdata[NS_SERVER] );
|
||||
@@ -2134,7 +2094,6 @@ void NET_Init( void )
|
||||
Cvar_RegisterVariable( &net_clientport );
|
||||
Cvar_RegisterVariable( &net_fakelag );
|
||||
Cvar_RegisterVariable( &net_fakeloss );
|
||||
Cvar_RegisterVariable( &net_resolve_debug );
|
||||
|
||||
Q_snprintf( cmd, sizeof( cmd ), "%i", PORT_SERVER );
|
||||
Cvar_FullSet( "hostport", cmd, FCVAR_READ_ONLY );
|
||||
@@ -2208,11 +2167,6 @@ void NET_Shutdown( void )
|
||||
NET_ClearLagData( true, true );
|
||||
|
||||
NET_Config( false, false );
|
||||
|
||||
#ifdef CAN_ASYNC_NS_RESOLVE
|
||||
NET_DeleteCriticalSections();
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
@@ -50,10 +50,8 @@ typedef enum
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
extern convar_t net_showpackets;
|
||||
extern convar_t net_clockwindow;
|
||||
extern convar_t net_send_debug;
|
||||
extern convar_t net_recv_debug;
|
||||
extern convar_t net_showpackets;
|
||||
extern convar_t net_clockwindow;
|
||||
|
||||
void NET_Init( void );
|
||||
void NET_Shutdown( void );
|
||||
@@ -68,7 +66,7 @@ qboolean NET_IsReservedAdr( netadr_t a );
|
||||
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b );
|
||||
qboolean NET_StringToAdr( const char *string, netadr_t *adr );
|
||||
qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen );
|
||||
net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v6only );
|
||||
net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr );
|
||||
int NET_CompareAdrSort( const void *_a, const void *_b );
|
||||
qboolean NET_CompareAdr( const netadr_t a, const netadr_t b );
|
||||
qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b );
|
||||
@@ -76,10 +74,12 @@ qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixle
|
||||
qboolean NET_GetPacket( netsrc_t sock, netadr_t *from, byte *data, size_t *length );
|
||||
void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to );
|
||||
void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t to, size_t splitsize );
|
||||
void NET_ClearLagData( qboolean bClient, qboolean bServer );
|
||||
void NET_IP6BytesToNetadr( netadr_t *adr, const uint8_t *ip6 );
|
||||
void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr );
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
qboolean CL_LegacyMode( void );
|
||||
int CL_GetSplitSize( void );
|
||||
#endif
|
||||
|
||||
|
||||
@@ -208,14 +208,6 @@ typedef enum fragsize_e
|
||||
FRAGSIZE_UNRELIABLE
|
||||
} fragsize_t;
|
||||
|
||||
typedef enum netchan_flags_e
|
||||
{
|
||||
NETCHAN_USE_LEGACY_SPLIT = BIT( 0 ),
|
||||
NETCHAN_USE_MUNGE = BIT( 1 ),
|
||||
NETCHAN_USE_BZIP2 = BIT( 2 ),
|
||||
NETCHAN_GOLDSRC = BIT( 3 ),
|
||||
} netchan_flags_t;
|
||||
|
||||
// Network Connection Channel
|
||||
typedef struct netchan_s
|
||||
{
|
||||
@@ -278,14 +270,10 @@ typedef struct netchan_s
|
||||
// added for net_speeds
|
||||
size_t total_sended;
|
||||
size_t total_received;
|
||||
qboolean split;
|
||||
unsigned int maxpacket;
|
||||
unsigned int splitid;
|
||||
netsplit_t netsplit;
|
||||
|
||||
qboolean split;
|
||||
qboolean use_munge;
|
||||
qboolean use_bz2;
|
||||
qboolean gs_netchan;
|
||||
netsplit_t netsplit;
|
||||
} netchan_t;
|
||||
|
||||
extern netadr_t net_from;
|
||||
@@ -299,7 +287,7 @@ extern int net_drop;
|
||||
|
||||
void Netchan_Init( void );
|
||||
void Netchan_Shutdown( void );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ), uint flags );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ) );
|
||||
void Netchan_CreateFileFragmentsFromBuffer( netchan_t *chan, const char *filename, byte *pbuf, int size );
|
||||
qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *length );
|
||||
qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg );
|
||||
|
||||
95
engine/common/pm_debug.c
Normal file
95
engine/common/pm_debug.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
pm_debug.c - player move debugging code
|
||||
Copyright (C) 2017 Uncle Mike
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "pm_local.h"
|
||||
#if !XASH_DEDICATED
|
||||
#include "client.h" // CL_Particle
|
||||
#endif
|
||||
|
||||
// expand debugging BBOX particle hulls by this many units.
|
||||
#define BOX_GAP 0.0f
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_ParticleLine
|
||||
|
||||
draw line from particles
|
||||
================
|
||||
*/
|
||||
void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
float len, curdist;
|
||||
vec3_t diff, pos;
|
||||
|
||||
// determine distance
|
||||
VectorSubtract( end, start, diff );
|
||||
len = VectorNormalizeLength( diff );
|
||||
curdist = 0;
|
||||
|
||||
while( curdist <= len )
|
||||
{
|
||||
VectorMA( start, curdist, diff, pos );
|
||||
CL_Particle( pos, pcolor, life, 0, zvel );
|
||||
curdist += 2.0f;
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawRectangle
|
||||
|
||||
================
|
||||
*/
|
||||
static void PM_DrawRectangle( const vec3_t tl, const vec3_t bl, const vec3_t tr, const vec3_t br, int pcolor, float life )
|
||||
{
|
||||
PM_ParticleLine( tl, bl, pcolor, life, 0 );
|
||||
PM_ParticleLine( bl, br, pcolor, life, 0 );
|
||||
PM_ParticleLine( br, tr, pcolor, life, 0 );
|
||||
PM_ParticleLine( tr, tl, pcolor, life, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PM_DrawBBox
|
||||
|
||||
================
|
||||
*/
|
||||
void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
vec3_t p[8], tmp;
|
||||
float gap = BOX_GAP;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
tmp[0] = (i & 1) ? mins[0] - gap : maxs[0] + gap;
|
||||
tmp[1] = (i & 2) ? mins[1] - gap : maxs[1] + gap ;
|
||||
tmp[2] = (i & 4) ? mins[2] - gap : maxs[2] + gap ;
|
||||
|
||||
VectorAdd( tmp, origin, tmp );
|
||||
VectorCopy( tmp, p[i] );
|
||||
}
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life );
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
}
|
||||
@@ -20,10 +20,17 @@ GNU General Public License for more details.
|
||||
|
||||
typedef int (*pfnIgnore)( physent_t *pe ); // custom trace filter
|
||||
|
||||
//
|
||||
// pm_debug.c
|
||||
//
|
||||
void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel );
|
||||
void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life );
|
||||
|
||||
//
|
||||
// pm_trace.c
|
||||
//
|
||||
void Pmove_Init( void );
|
||||
void PM_ClearPhysEnts( playermove_t *pmove );
|
||||
void PM_InitBoxHull( void );
|
||||
hull_t *PM_HullForBsp( physent_t *pe, playermove_t *pmove, float *offset );
|
||||
qboolean PM_RecursiveHullCheck( hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace );
|
||||
@@ -39,29 +46,7 @@ struct msurface_s *PM_TraceSurfacePmove( playermove_t *pmove, int ground, float
|
||||
const char *PM_TraceTexture( playermove_t *pmove, int ground, float *vstart, float *vend );
|
||||
int PM_PointContentsPmove( playermove_t *pmove, const float *p, int *truecontents );
|
||||
void PM_StuckTouch( playermove_t *pmove, int hitent, pmtrace_t *tr );
|
||||
|
||||
static inline void PM_ConvertTrace( trace_t *out, pmtrace_t *in, edict_t *ent )
|
||||
{
|
||||
out->allsolid = in->allsolid;
|
||||
out->startsolid = in->startsolid;
|
||||
out->inopen = in->inopen;
|
||||
out->inwater = in->inwater;
|
||||
out->fraction = in->fraction;
|
||||
out->plane.dist = in->plane.dist;
|
||||
out->hitgroup = in->hitgroup;
|
||||
out->ent = ent;
|
||||
|
||||
VectorCopy( in->endpos, out->endpos );
|
||||
VectorCopy( in->plane.normal, out->plane.normal );
|
||||
}
|
||||
|
||||
static inline void PM_ClearPhysEnts( playermove_t *pmove )
|
||||
{
|
||||
pmove->nummoveent = 0;
|
||||
pmove->numphysent = 0;
|
||||
pmove->numvisent = 0;
|
||||
pmove->numtouch = 0;
|
||||
}
|
||||
void PM_ConvertTrace( trace_t *out, pmtrace_t *in, edict_t *ent );
|
||||
|
||||
static inline void PM_InitTrace( trace_t *trace, const vec3_t end )
|
||||
{
|
||||
|
||||
@@ -55,6 +55,14 @@ void Pmove_Init( void )
|
||||
memcpy( host.player_maxs, pm_hullmaxs, sizeof( pm_hullmaxs ));
|
||||
}
|
||||
|
||||
void PM_ClearPhysEnts( playermove_t *pmove )
|
||||
{
|
||||
pmove->nummoveent = 0;
|
||||
pmove->numphysent = 0;
|
||||
pmove->numvisent = 0;
|
||||
pmove->numtouch = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
PM_InitBoxHull
|
||||
@@ -109,6 +117,21 @@ static hull_t *PM_HullForBox( const vec3_t mins, const vec3_t maxs )
|
||||
return &pm_boxhull;
|
||||
}
|
||||
|
||||
void PM_ConvertTrace( trace_t *out, pmtrace_t *in, edict_t *ent )
|
||||
{
|
||||
out->allsolid = in->allsolid;
|
||||
out->startsolid = in->startsolid;
|
||||
out->inopen = in->inopen;
|
||||
out->inwater = in->inwater;
|
||||
out->fraction = in->fraction;
|
||||
out->plane.dist = in->plane.dist;
|
||||
out->hitgroup = in->hitgroup;
|
||||
out->ent = ent;
|
||||
|
||||
VectorCopy( in->endpos, out->endpos );
|
||||
VectorCopy( in->plane.normal, out->plane.normal );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
PM_HullPointContents
|
||||
|
||||
@@ -73,7 +73,7 @@ GNU General Public License for more details.
|
||||
#define svc_director 51 // <variable sized>
|
||||
#define svc_voiceinit 52 // <see code>
|
||||
#define svc_voicedata 53 // [byte][short][...]
|
||||
// reserved
|
||||
#define svc_deltapacketbones 54 // [short][byte][...]
|
||||
// reserved
|
||||
#define svc_resourcelocation 56 // [string]
|
||||
#define svc_querycvarvalue 57 // [string]
|
||||
@@ -93,7 +93,7 @@ GNU General Public License for more details.
|
||||
#define clc_voicedata 8
|
||||
#define clc_requestcvarvalue 9
|
||||
#define clc_requestcvarvalue2 10
|
||||
#define clc_lastmsg 11 // end client messages (11 is GoldSrc message)
|
||||
#define clc_lastmsg 10 // end client messages
|
||||
|
||||
#define MAX_VISIBLE_PACKET_BITS 11 // 2048 visible entities per frame (hl1 has 256)
|
||||
#define MAX_VISIBLE_PACKET (1<<MAX_VISIBLE_PACKET_BITS)
|
||||
@@ -277,11 +277,11 @@ GNU General Public License for more details.
|
||||
#define SU_ARMOR (1<<13)
|
||||
#define SU_WEAPON (1<<14)
|
||||
|
||||
extern const char *const svc_strings[svc_lastmsg+1];
|
||||
extern const char *const svc_legacy_strings[svc_lastmsg+1];
|
||||
extern const char *const svc_quake_strings[svc_lastmsg+1];
|
||||
extern const char *const svc_goldsrc_strings[svc_lastmsg+1];
|
||||
extern const char *const clc_strings[clc_lastmsg+1];
|
||||
extern const char *svc_strings[svc_lastmsg+1];
|
||||
extern const char *svc_legacy_strings[svc_lastmsg+1];
|
||||
extern const char *svc_quake_strings[svc_lastmsg+1];
|
||||
extern const char *svc_goldsrc_strings[svc_lastmsg+1];
|
||||
extern const char *clc_strings[clc_lastmsg+1];
|
||||
|
||||
// FWGS extensions
|
||||
#define NET_EXT_SPLITSIZE (1U<<0) // set splitsize by cl_dlmax
|
||||
@@ -320,7 +320,8 @@ extern const char *const clc_strings[clc_lastmsg+1];
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0" // TODO: implement IP filter
|
||||
|
||||
// GoldSrc protocol definitions
|
||||
#define PROTOCOL_GOLDSRC_VERSION 48
|
||||
#define PROTOCOL_GOLDSRC_VERSION_REAL 48
|
||||
#define PROTOCOL_GOLDSRC_VERSION (PROTOCOL_GOLDSRC_VERSION_REAL | (BIT( 7 ))) // should be 48, only to differentiate it from PROTOCOL_LEGACY_VERSION
|
||||
|
||||
#define svc_goldsrc_version svc_changing
|
||||
#define svc_goldsrc_serverinfo svc_serverdata
|
||||
@@ -341,17 +342,13 @@ extern const char *const clc_strings[clc_lastmsg+1];
|
||||
#define clc_goldsrc_hltv clc_requestcvarvalue // 9
|
||||
#define clc_goldsrc_requestcvarvalue clc_requestcvarvalue2 // 10
|
||||
#define clc_goldsrc_requestcvarvalue2 11
|
||||
#define clc_goldsrc_lastmsg 11
|
||||
#define clc_goldsrc_lastmsg 12
|
||||
|
||||
#define S2C_REJECT_BADPASSWORD '8'
|
||||
#define S2C_REJECT '9'
|
||||
#define S2C_CHALLENGE "A00000000"
|
||||
#define S2C_CONNECTION "B"
|
||||
#define A2C_PRINT 'l'
|
||||
|
||||
#define MAX_GOLDSRC_BACKUP_CMDS 8
|
||||
#define MAX_GOLDSRC_TOTAL_CMDS 16
|
||||
#define MAX_GOLDSRC_MODEL_BITS 10
|
||||
#define MAX_GOLDSRC_RESOURCE_BITS 12
|
||||
#define MAX_GOLDSRC_ENTITY_BITS 11
|
||||
// #define MAX_GOLDSRC_EDICTS BIT( MAX_ENTITY_BITS )
|
||||
|
||||
@@ -30,7 +30,7 @@ static void Sound_Reset( void )
|
||||
sound.size = 0;
|
||||
}
|
||||
|
||||
static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void )
|
||||
static wavdata_t *SoundPack( void )
|
||||
{
|
||||
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ enum soundlst_type_e
|
||||
SoundList_List
|
||||
};
|
||||
|
||||
static const char *const soundlst_groups[SoundList_Groups] =
|
||||
static const char *soundlst_groups[SoundList_Groups] =
|
||||
{
|
||||
"BouncePlayerShell",
|
||||
"BounceWeaponShell",
|
||||
@@ -46,7 +46,7 @@ typedef struct soundlst_s
|
||||
int max; // the string count if type is group
|
||||
} soundlst_t;
|
||||
|
||||
static soundlst_t soundlst[SoundList_Groups];
|
||||
soundlst_t soundlst[SoundList_Groups];
|
||||
|
||||
static void SoundList_Print_f( void );
|
||||
static void SoundList_Free( soundlst_t *lst )
|
||||
|
||||
@@ -230,20 +230,13 @@ static void Sys_PrintLogfile( const int fd, const char *logtime, const char *msg
|
||||
|
||||
if( p == NULL )
|
||||
{
|
||||
if( write( fd, msg, Q_strlen( msg )) < 0 )
|
||||
{
|
||||
// don't call engine Msg, might cause recursion
|
||||
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
|
||||
}
|
||||
write( fd, msg, Q_strlen( msg ));
|
||||
break;
|
||||
}
|
||||
else if( IsColorString( p ))
|
||||
{
|
||||
if( p != msg )
|
||||
{
|
||||
if( write( fd, msg, p - msg ) < 0 )
|
||||
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
|
||||
}
|
||||
write( fd, msg, p - msg );
|
||||
msg = p + 2;
|
||||
|
||||
if( colorize )
|
||||
@@ -251,8 +244,7 @@ static void Sys_PrintLogfile( const int fd, const char *logtime, const char *msg
|
||||
}
|
||||
else
|
||||
{
|
||||
if( write( fd, msg, p - msg + 1 ) < 0 )
|
||||
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
|
||||
write( fd, msg, p - msg + 1 );
|
||||
msg = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ void Test_RunIPFilter( void );
|
||||
void Test_RunGamma( void );
|
||||
void Test_RunDelta( void );
|
||||
void Test_RunBuffer( void );
|
||||
void Test_RunMunge( void );
|
||||
|
||||
#define TEST_LIST_0 \
|
||||
Test_RunLibCommon(); \
|
||||
@@ -50,8 +49,7 @@ void Test_RunMunge( void );
|
||||
Test_RunCvar(); \
|
||||
Test_RunIPFilter(); \
|
||||
Test_RunBuffer(); \
|
||||
Test_RunDelta(); \
|
||||
Test_RunMunge();
|
||||
Test_RunDelta();
|
||||
|
||||
#define TEST_LIST_0_CLIENT \
|
||||
Test_RunCon(); \
|
||||
|
||||
@@ -20,6 +20,47 @@ GNU General Public License for more details.
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "studio.h"
|
||||
|
||||
/*
|
||||
==================
|
||||
World_MoveBounds
|
||||
==================
|
||||
*/
|
||||
void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( end[i] > start[i] )
|
||||
{
|
||||
boxmins[i] = start[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = end[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
boxmins[i] = end[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = start[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch )
|
||||
{
|
||||
if( trace->allsolid || trace->startsolid || trace->fraction < cliptrace->fraction )
|
||||
{
|
||||
trace->ent = touch;
|
||||
|
||||
if( cliptrace->startsolid )
|
||||
{
|
||||
*cliptrace = *trace;
|
||||
cliptrace->startsolid = true;
|
||||
}
|
||||
else *cliptrace = *trace;
|
||||
}
|
||||
|
||||
return *cliptrace;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
World_TransformAABB
|
||||
@@ -66,3 +107,31 @@ void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
RankForContents
|
||||
|
||||
Used for determine contents priority
|
||||
==================
|
||||
*/
|
||||
int RankForContents( int contents )
|
||||
{
|
||||
switch( contents )
|
||||
{
|
||||
case CONTENTS_EMPTY: return 0;
|
||||
case CONTENTS_WATER: return 1;
|
||||
case CONTENTS_TRANSLUCENT: return 2;
|
||||
case CONTENTS_CURRENT_0: return 3;
|
||||
case CONTENTS_CURRENT_90: return 4;
|
||||
case CONTENTS_CURRENT_180: return 5;
|
||||
case CONTENTS_CURRENT_270: return 6;
|
||||
case CONTENTS_CURRENT_UP: return 7;
|
||||
case CONTENTS_CURRENT_DOWN: return 8;
|
||||
case CONTENTS_SLIME: return 9;
|
||||
case CONTENTS_LAVA: return 10;
|
||||
case CONTENTS_SKY: return 11;
|
||||
case CONTENTS_SOLID: return 12;
|
||||
default: return 13; // any user contents has more priority than default
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,71 +36,10 @@ ENTITY AREA CHECKING
|
||||
#include "lightstyle.h"
|
||||
|
||||
// trace common
|
||||
static inline void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( end[i] > start[i] )
|
||||
{
|
||||
boxmins[i] = start[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = end[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
boxmins[i] = end[i] + mins[i] - 1.0f;
|
||||
boxmaxs[i] = start[i] + maxs[i] + 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch )
|
||||
{
|
||||
if( trace->allsolid || trace->startsolid || trace->fraction < cliptrace->fraction )
|
||||
{
|
||||
trace->ent = touch;
|
||||
|
||||
if( cliptrace->startsolid )
|
||||
{
|
||||
*cliptrace = *trace;
|
||||
cliptrace->startsolid = true;
|
||||
}
|
||||
else *cliptrace = *trace;
|
||||
}
|
||||
|
||||
return *cliptrace;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
RankForContents
|
||||
|
||||
Used for determine contents priority
|
||||
==================
|
||||
*/
|
||||
static inline int RankForContents( int contents )
|
||||
{
|
||||
switch( contents )
|
||||
{
|
||||
case CONTENTS_EMPTY: return 0;
|
||||
case CONTENTS_WATER: return 1;
|
||||
case CONTENTS_TRANSLUCENT: return 2;
|
||||
case CONTENTS_CURRENT_0: return 3;
|
||||
case CONTENTS_CURRENT_90: return 4;
|
||||
case CONTENTS_CURRENT_180: return 5;
|
||||
case CONTENTS_CURRENT_270: return 6;
|
||||
case CONTENTS_CURRENT_UP: return 7;
|
||||
case CONTENTS_CURRENT_DOWN: return 8;
|
||||
case CONTENTS_SLIME: return 9;
|
||||
case CONTENTS_LAVA: return 10;
|
||||
case CONTENTS_SKY: return 11;
|
||||
case CONTENTS_SOLID: return 12;
|
||||
default: return 13; // any user contents has more priority than default
|
||||
}
|
||||
}
|
||||
|
||||
void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs );
|
||||
void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs );
|
||||
trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch );
|
||||
int RankForContents( int contents );
|
||||
|
||||
#define check_angles( x ) ( (int)x == 90 || (int)x == 180 || (int)x == 270 || (int)x == -90 || (int)x == -180 || (int)x == -270 )
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ typedef enum
|
||||
force_exactfile, // File on client must exactly match server's file
|
||||
force_model_samebounds, // For model files only, the geometry must fit in the same bbox
|
||||
force_model_specifybounds, // For model files only, the geometry must fit in the specified bbox
|
||||
force_model_specifybounds_if_avail,
|
||||
} FORCE_TYPE;
|
||||
|
||||
// Returned by TraceLine
|
||||
|
||||
@@ -51,7 +51,6 @@ void IOS_LaunchDialog( void );
|
||||
|
||||
#if XASH_POSIX
|
||||
void Posix_Daemonize( void );
|
||||
void Posix_SetupSigtermHandling( void );
|
||||
#endif
|
||||
|
||||
#if XASH_SDL
|
||||
@@ -157,13 +156,6 @@ static inline qboolean Sys_DebuggerPresent( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void Platform_SetupSigtermHandling( void )
|
||||
{
|
||||
#if XASH_POSIX
|
||||
Posix_SetupSigtermHandling( );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ GNU General Public License for more details.
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include "platform/platform.h"
|
||||
#include "menu_int.h"
|
||||
|
||||
@@ -146,21 +145,6 @@ void Posix_Daemonize( void )
|
||||
|
||||
}
|
||||
|
||||
static void Posix_SigtermCallback( int signal )
|
||||
{
|
||||
Sys_Quit();
|
||||
}
|
||||
|
||||
void Posix_SetupSigtermHandling( void )
|
||||
{
|
||||
#if !XASH_PSVITA
|
||||
struct sigaction act = { 0 };
|
||||
act.sa_handler = Posix_SigtermCallback;
|
||||
act.sa_flags = 0;
|
||||
sigaction( SIGTERM, &act, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_TIMER == TIMER_POSIX
|
||||
double Platform_DoubleTime( void )
|
||||
{
|
||||
|
||||
@@ -18,10 +18,8 @@ GNU General Public License for more details.
|
||||
#define NET_PSVITA_H
|
||||
|
||||
#include <vitasdk.h>
|
||||
#include "platform/posix/net.h"
|
||||
|
||||
/* we're missing IPv6 support; define some trash */
|
||||
#define XASH_NO_IPV6_RESOLVE 1
|
||||
|
||||
#ifndef IN6_IS_ADDR_V4MAPPED
|
||||
#define IN6_IS_ADDR_V4MAPPED( p ) ( 0 )
|
||||
|
||||
@@ -80,10 +80,11 @@ GNU General Public License for more details.
|
||||
#define MODEL_CLIENT BIT( 30 ) // client sprite
|
||||
|
||||
// goes into world.flags
|
||||
#define FWORLD_SKYSPHERE BIT( 0 )
|
||||
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
|
||||
#define FWORLD_WATERALPHA BIT( 2 )
|
||||
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
|
||||
#define FWORLD_SKYSPHERE BIT( 0 )
|
||||
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
|
||||
#define FWORLD_WATERALPHA BIT( 2 )
|
||||
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
|
||||
#define FWORLD_HAS_LITWATER BIT( 4 )
|
||||
|
||||
// special rendermode for screenfade modulate
|
||||
// (probably will be expanded at some point)
|
||||
@@ -389,13 +390,10 @@ typedef struct ref_api_s
|
||||
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
|
||||
|
||||
// memory
|
||||
poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline )
|
||||
WARN_UNUSED_RESULT;
|
||||
poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline );
|
||||
void (*_Mem_FreePool)( poolhandle_t *poolptr, const char *filename, int fileline );
|
||||
void *(*_Mem_Alloc)( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
ALLOC_CHECK( 2 ) WARN_UNUSED_RESULT;
|
||||
void *(*_Mem_Realloc)( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
|
||||
void *(*_Mem_Alloc)( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 2 );
|
||||
void *(*_Mem_Realloc)( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 3 );
|
||||
void (*_Mem_Free)( void *data, const char *filename, int fileline );
|
||||
|
||||
// library management
|
||||
|
||||
@@ -19,7 +19,7 @@ GNU General Public License for more details.
|
||||
#include "net_encode.h"
|
||||
#include "net_api.h"
|
||||
|
||||
const char *const clc_strings[clc_lastmsg+1] =
|
||||
const char *clc_strings[clc_lastmsg+1] =
|
||||
{
|
||||
"clc_bad",
|
||||
"clc_nop",
|
||||
@@ -27,12 +27,11 @@ const char *const clc_strings[clc_lastmsg+1] =
|
||||
"clc_stringcmd",
|
||||
"clc_delta",
|
||||
"clc_resourcelist",
|
||||
"clc_legacy_userinfo",
|
||||
"clc_unused6",
|
||||
"clc_fileconsistency",
|
||||
"clc_voicedata",
|
||||
"clc_cvarvalue/clc_goldsrc_hltv",
|
||||
"clc_cvarvalue2/clc_goldsrc_requestcvarvalue",
|
||||
"clc_goldsrc_requestcvarvalue2",
|
||||
"clc_cvarvalue",
|
||||
"clc_cvarvalue2",
|
||||
};
|
||||
|
||||
typedef struct ucmd_s
|
||||
@@ -445,7 +444,7 @@ static void SV_ConnectClient( netadr_t from )
|
||||
newcl->listeners = -1;
|
||||
|
||||
// initailize netchan
|
||||
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize, 0 );
|
||||
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize );
|
||||
MSG_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf
|
||||
|
||||
Q_strncpy( newcl->hashedcdkey, Info_ValueForKey( protinfo, "uuid" ), 32 );
|
||||
@@ -1343,8 +1342,9 @@ otherwise see code SV_UpdateMovevars()
|
||||
*/
|
||||
void SV_FullUpdateMovevars( sv_client_t *cl, sizebuf_t *msg )
|
||||
{
|
||||
const movevars_t nullmovevars = { 0 };
|
||||
movevars_t nullmovevars;
|
||||
|
||||
memset( &nullmovevars, 0, sizeof( nullmovevars ));
|
||||
MSG_WriteDeltaMovevars( msg, &nullmovevars, &svgame.movevars );
|
||||
}
|
||||
|
||||
@@ -3036,7 +3036,7 @@ static qboolean SV_EntGetVars_f( sv_client_t *cl )
|
||||
return true;
|
||||
}
|
||||
|
||||
static const ucmd_t ucmds[] =
|
||||
ucmd_t ucmds[] =
|
||||
{
|
||||
{ "new", SV_New_f },
|
||||
{ "god", SV_Godmode_f },
|
||||
@@ -3056,7 +3056,7 @@ static const ucmd_t ucmds[] =
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const ucmd_t enttoolscmds[] =
|
||||
ucmd_t enttoolscmds[] =
|
||||
{
|
||||
{ "ent_list", SV_EntList_f },
|
||||
{ "ent_info", SV_EntInfo_f },
|
||||
@@ -3073,7 +3073,7 @@ SV_ExecuteUserCommand
|
||||
*/
|
||||
static void SV_ExecuteClientCommand( sv_client_t *cl, const char *s )
|
||||
{
|
||||
const ucmd_t *u;
|
||||
ucmd_t *u;
|
||||
|
||||
Cmd_TokenizeString( s );
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
|
||||
extern convar_t con_gamemaps;
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_ClientPrintf
|
||||
|
||||
@@ -25,8 +25,8 @@ typedef struct
|
||||
byte sended[MAX_EDICTS_BYTES];
|
||||
} sv_ents_t;
|
||||
|
||||
static int c_fullsend; // just a debug counter
|
||||
static int c_notsend;
|
||||
int c_fullsend; // just a debug counter
|
||||
int c_notsend;
|
||||
|
||||
/*
|
||||
=======================
|
||||
|
||||
@@ -24,6 +24,8 @@ GNU General Public License for more details.
|
||||
#include "render_api.h" // modelstate_t
|
||||
#include "ref_common.h" // decals
|
||||
|
||||
#define ENTVARS_COUNT ARRAYSIZE( gEntvarsDescription )
|
||||
|
||||
// GameAPI functions declarations
|
||||
static int GAME_EXPORT pfnModelIndex( const char *m );
|
||||
|
||||
@@ -81,7 +83,7 @@ EntvarsDescription
|
||||
entavrs table for FindEntityByString
|
||||
=============
|
||||
*/
|
||||
static const TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
static TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
{
|
||||
DEFINE_ENTITY_FIELD( classname, FIELD_STRING ),
|
||||
DEFINE_ENTITY_FIELD( globalname, FIELD_STRING ),
|
||||
@@ -98,6 +100,20 @@ static const TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ),
|
||||
};
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_GetEntvarsDescription
|
||||
|
||||
entavrs table for FindEntityByString
|
||||
=============
|
||||
*/
|
||||
static TYPEDESCRIPTION *SV_GetEntvarsDescirption( int number )
|
||||
{
|
||||
if( number < 0 || number >= ENTVARS_COUNT )
|
||||
return NULL;
|
||||
return &gEntvarsDescription[number];
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_SysError
|
||||
@@ -627,16 +643,12 @@ Write ambient sounds into demo
|
||||
*/
|
||||
void SV_RestartAmbientSounds( void )
|
||||
{
|
||||
// TODO: we don't know sounds state on remote server
|
||||
// as it's used only for demos, maybe this could be implemented on client side?
|
||||
#if !XASH_DEDICATED
|
||||
soundlist_t soundInfo[256];
|
||||
string curtrack, looptrack;
|
||||
int i, nSounds;
|
||||
int position;
|
||||
|
||||
if( !SV_Active( ) || Host_IsDedicated( ))
|
||||
return;
|
||||
if( !SV_Active( )) return;
|
||||
|
||||
nSounds = S_GetCurrentStaticSounds( soundInfo, 256 );
|
||||
|
||||
@@ -651,12 +663,13 @@ void SV_RestartAmbientSounds( void )
|
||||
SV_StartSound( SV_PEntityOfEntIndex( si->entnum, true ), CHAN_STATIC, si->name, si->volume, si->attenuation, 0, si->pitch );
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED // TODO: ???
|
||||
// restart soundtrack
|
||||
if( S_StreamGetCurrentState( curtrack, sizeof( curtrack ), looptrack, sizeof( looptrack ), &position ))
|
||||
{
|
||||
SV_StartMusic( curtrack, looptrack, position );
|
||||
}
|
||||
#endif // !XASH_DEDICATED
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -668,25 +681,31 @@ Write all the decals into demo
|
||||
*/
|
||||
void SV_RestartDecals( void )
|
||||
{
|
||||
// TODO: similar to SV_RestartAmbientSounds, this is only used for demo recording
|
||||
// and better be reimplemented on client side
|
||||
#if !XASH_DEDICATED
|
||||
decallist_t *list;
|
||||
int decalIndex;
|
||||
int modelIndex;
|
||||
sizebuf_t *msg;
|
||||
int i, numdecals;
|
||||
|
||||
if( !SV_Active( ) || Host_IsDedicated( ))
|
||||
return;
|
||||
if( !SV_Active( )) return;
|
||||
|
||||
// g-cont. add space for studiodecals if present
|
||||
list = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
|
||||
|
||||
numdecals = ref.dllFuncs.R_CreateDecalList( list );
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated() )
|
||||
{
|
||||
numdecals = ref.dllFuncs.R_CreateDecalList( list );
|
||||
|
||||
// remove decals from map
|
||||
ref.dllFuncs.R_ClearAllDecals();
|
||||
// remove decals from map
|
||||
ref.dllFuncs.R_ClearAllDecals();
|
||||
}
|
||||
else
|
||||
#endif // XASH_DEDICATED
|
||||
{
|
||||
// we probably running a dedicated server
|
||||
numdecals = 0;
|
||||
}
|
||||
|
||||
// write decals into reliable datagram
|
||||
msg = SV_GetReliableDatagram();
|
||||
@@ -709,7 +728,6 @@ void SV_RestartDecals( void )
|
||||
}
|
||||
|
||||
Z_Free( list );
|
||||
#endif // !XASH_DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1490,8 +1508,8 @@ SV_FindEntityByString
|
||||
*/
|
||||
static edict_t *GAME_EXPORT SV_FindEntityByString( edict_t *pStartEdict, const char *pszField, const char *pszValue )
|
||||
{
|
||||
int i = 0, e = 0;
|
||||
const TYPEDESCRIPTION *desc = NULL;
|
||||
int index = 0, e = 0;
|
||||
TYPEDESCRIPTION *desc = NULL;
|
||||
edict_t *ed;
|
||||
const char *t;
|
||||
|
||||
@@ -1500,13 +1518,10 @@ static edict_t *GAME_EXPORT SV_FindEntityByString( edict_t *pStartEdict, const c
|
||||
|
||||
if( pStartEdict ) e = NUM_FOR_EDICT( pStartEdict );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( gEntvarsDescription ); i++ )
|
||||
while(( desc = SV_GetEntvarsDescirption( index++ )) != NULL )
|
||||
{
|
||||
if( !Q_strcmp( pszField, gEntvarsDescription[i].fieldName ))
|
||||
{
|
||||
desc = &gEntvarsDescription[i];
|
||||
if( !Q_strcmp( pszField, desc->fieldName ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( desc == NULL )
|
||||
@@ -5100,8 +5115,6 @@ void SV_SpawnEntities( const char *mapname )
|
||||
|
||||
void SV_UnloadProgs( void )
|
||||
{
|
||||
pending_cvar_t *pending_cvars_list;
|
||||
|
||||
if( !svgame.hInstance )
|
||||
return;
|
||||
|
||||
@@ -5111,8 +5124,6 @@ void SV_UnloadProgs( void )
|
||||
/// SV_UnloadProgs will be disabled
|
||||
//Mod_ClearUserData ();
|
||||
|
||||
pending_cvars_list = Cvar_PrepareToUnlink( FCVAR_EXTDLL );
|
||||
|
||||
if( svgame.dllFuncs2.pfnGameShutdown != NULL )
|
||||
svgame.dllFuncs2.pfnGameShutdown ();
|
||||
|
||||
@@ -5130,7 +5141,7 @@ void SV_UnloadProgs( void )
|
||||
|
||||
// must unlink all game cvars,
|
||||
// before pointers on them will be lost...
|
||||
Cvar_UnlinkPendingCvars( pending_cvars_list );
|
||||
Cvar_Unlink( FCVAR_EXTDLL );
|
||||
Cmd_Unlink( CMD_SERVERDLL );
|
||||
|
||||
SV_FreeStringPool();
|
||||
|
||||
@@ -363,7 +363,6 @@ loads external resource list
|
||||
static void SV_CreateGenericResources( void )
|
||||
{
|
||||
string filename;
|
||||
int i;
|
||||
|
||||
Q_strncpy( filename, sv.model_precache[1], sizeof( filename ));
|
||||
COM_ReplaceExtension( filename, ".res", sizeof( filename ));
|
||||
@@ -371,16 +370,6 @@ static void SV_CreateGenericResources( void )
|
||||
|
||||
SV_ReadResourceList( filename );
|
||||
SV_ReadResourceList( "reslist.txt" );
|
||||
|
||||
for( i = 0; i < world.wadlist.count; i++ )
|
||||
{
|
||||
if( world.wadlist.wadusage[i] > 0 )
|
||||
{
|
||||
string wadname;
|
||||
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", world.wadlist.wadnames[i] );
|
||||
SV_GenericIndex( wadname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1028,8 +1017,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba
|
||||
if( !SV_InitGame( ))
|
||||
return false;
|
||||
|
||||
Delta_Init(); // re-initialize delta
|
||||
|
||||
// unlock sv_cheats in local game
|
||||
ClearBits( sv_cheats.flags, FCVAR_READ_ONLY );
|
||||
|
||||
|
||||
@@ -92,9 +92,9 @@ static CVAR_DEFINE_AUTO( sv_waterfriction, "1", FCVAR_SERVER|FCVAR_MOVEVARS, "ho
|
||||
static CVAR_DEFINE_AUTO( sv_bounce, "1", FCVAR_SERVER|FCVAR_MOVEVARS, "bounce factor for entities with MOVETYPE_BOUNCE" );
|
||||
static CVAR_DEFINE_AUTO( sv_stepsize, "18", FCVAR_SERVER|FCVAR_MOVEVARS, "how high you and NPS's can step up" );
|
||||
CVAR_DEFINE_AUTO( sv_maxvelocity, "2000", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "max velocity for all things in the world" );
|
||||
static CVAR_DEFINE_AUTO( sv_zmax, "4096", FCVAR_MOVEVARS|FCVAR_SPONLY, "maximum viewable distance" );
|
||||
static CVAR_DEFINE_AUTO( sv_zmax, "4096", FCVAR_SERVER|FCVAR_MOVEVARS|FCVAR_SPONLY, "maximum viewable distance" );
|
||||
CVAR_DEFINE_AUTO( sv_wateramp, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "world waveheight factor" );
|
||||
static CVAR_DEFINE( sv_footsteps, "mp_footsteps", "1", FCVAR_SERVER|FCVAR_MOVEVARS, "play foot steps for players" );
|
||||
static CVAR_DEFINE( sv_footsteps, "mp_footsteps", "1", FCVAR_SERVER|FCVAR_MOVEVARS, "world gravity value" );
|
||||
CVAR_DEFINE_AUTO( sv_skyname, "desert", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "skybox name (can be dynamically changed in-game)" );
|
||||
static CVAR_DEFINE_AUTO( sv_rollangle, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED|FCVAR_ARCHIVE, "how much to tilt the view when strafing" );
|
||||
static CVAR_DEFINE_AUTO( sv_rollspeed, "200", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "how much strafing is necessary to tilt the view" );
|
||||
@@ -189,9 +189,6 @@ void SV_UpdateMovevars( qboolean initialize )
|
||||
if( !initialize && !host.movevars_changed )
|
||||
return;
|
||||
|
||||
// NOTE: this breaks Natural Selection mod on ns_machina map that uses model as sky
|
||||
// it sets the value to 4000000 that even exceeds the coord limit
|
||||
#if 0
|
||||
// check range
|
||||
if( sv_zmax.value < 256.0f ) Cvar_SetValue( "sv_zmax", 256.0f );
|
||||
|
||||
@@ -206,7 +203,6 @@ void SV_UpdateMovevars( qboolean initialize )
|
||||
if( sv_zmax.value > 32767.0f )
|
||||
Cvar_SetValue( "sv_zmax", 32767.0f );
|
||||
}
|
||||
#endif
|
||||
|
||||
svgame.movevars.gravity = sv_gravity.value;
|
||||
svgame.movevars.stopspeed = sv_stopspeed.value;
|
||||
|
||||
@@ -82,7 +82,7 @@ typedef struct
|
||||
float time;
|
||||
} SAVE_LIGHTSTYLE;
|
||||
|
||||
static void (__cdecl *pfnSaveGameComment)( char *buffer, int max_length ) = NULL;
|
||||
void (__cdecl *pfnSaveGameComment)( char *buffer, int max_length ) = NULL;
|
||||
|
||||
static TYPEDESCRIPTION gGameHeader[] =
|
||||
{
|
||||
@@ -218,7 +218,7 @@ static TYPEDESCRIPTION gTempEntvars[] =
|
||||
DEFINE_ENTITY_GLOBAL_FIELD( globalname, FIELD_STRING ),
|
||||
};
|
||||
|
||||
static const struct
|
||||
struct
|
||||
{
|
||||
const char *mapname;
|
||||
const char *titlename;
|
||||
@@ -1170,36 +1170,41 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
|
||||
char name[MAX_QPATH];
|
||||
int i, id, version;
|
||||
char *pTokenData;
|
||||
decallist_t *decalList = NULL;
|
||||
SAVE_CLIENT header = { 0 };
|
||||
decallist_t *decalList;
|
||||
SAVE_CLIENT header;
|
||||
file_t *pFile;
|
||||
|
||||
// clearing the saving buffer to reuse
|
||||
SaveClear( pSaveData );
|
||||
|
||||
header.entityCount = sv.num_static_entities;
|
||||
memset( &header, 0, sizeof( header ));
|
||||
|
||||
// g-cont. add space for studiodecals if present
|
||||
decalList = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
|
||||
|
||||
// initialize client header
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ))
|
||||
if( !Host_IsDedicated() )
|
||||
{
|
||||
// g-cont. add space for studiodecals if present
|
||||
decalList = (decallist_t *)Mem_Calloc( host.mempool, sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
|
||||
|
||||
header.decalCount = ref.dllFuncs.R_CreateDecalList( decalList );
|
||||
|
||||
if( !changelevel ) // sounds won't going across transition
|
||||
{
|
||||
header.soundCount = S_GetCurrentDynamicSounds( soundInfo, MAX_CHANNELS );
|
||||
|
||||
// music not reqiured to save position: it's just continue playing on a next level
|
||||
S_StreamGetCurrentState(
|
||||
header.introTrack, sizeof( header.introTrack ),
|
||||
header.mainTrack, sizeof( header.mainTrack ),
|
||||
&header.trackPosition );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // XASH_DEDICATED
|
||||
{
|
||||
// we probably running a dedicated server
|
||||
header.decalCount = 0;
|
||||
}
|
||||
header.entityCount = sv.num_static_entities;
|
||||
|
||||
if( !changelevel )
|
||||
{
|
||||
// sounds won't going across transition
|
||||
header.soundCount = S_GetCurrentDynamicSounds( soundInfo, MAX_CHANNELS );
|
||||
#if !XASH_DEDICATED
|
||||
// music not reqiured to save position: it's just continue playing on a next level
|
||||
S_StreamGetCurrentState( header.introTrack, sizeof( header.introTrack ), header.mainTrack, sizeof( header.mainTrack ), &header.trackPosition );
|
||||
#endif
|
||||
}
|
||||
|
||||
// save viewentity to allow camera works after save\restore
|
||||
if( SV_IsValidEdict( cl->pViewEntity ) && cl->pViewEntity != cl->edict )
|
||||
@@ -1212,7 +1217,7 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
|
||||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "ClientHeader", &header, gSaveClient, ARRAYSIZE( gSaveClient ));
|
||||
|
||||
// store decals
|
||||
for( i = 0; decalList != NULL && i < header.decalCount; i++ )
|
||||
for( i = 0; i < header.decalCount; i++ )
|
||||
{
|
||||
// NOTE: apply landmark offset only for brush entities without origin brushes
|
||||
if( pSaveData->fUseLandmark && FBitSet( decalList[i].flags, FDECAL_USE_LANDMARK ))
|
||||
@@ -1220,9 +1225,7 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
|
||||
|
||||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "DECALLIST", &decalList[i], gDecalEntry, ARRAYSIZE( gDecalEntry ));
|
||||
}
|
||||
|
||||
if( decalList )
|
||||
Mem_Free( decalList );
|
||||
Z_Free( decalList );
|
||||
|
||||
// write client entities
|
||||
for( i = 0; i < header.entityCount; i++ )
|
||||
@@ -2185,19 +2188,6 @@ qboolean SV_SaveGame( const char *pName )
|
||||
return SaveGameSlot( savename, comment );
|
||||
}
|
||||
|
||||
static int SV_CompareFileTime( int ft1, int ft2 )
|
||||
{
|
||||
if( ft1 < ft2 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if( ft1 > ft2 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_GetLatestSave
|
||||
@@ -2223,7 +2213,7 @@ const char *SV_GetLatestSave( void )
|
||||
if( ft > 0 )
|
||||
{
|
||||
// should we use the matched?
|
||||
if( !found || SV_CompareFileTime( newest, ft ) < 0 )
|
||||
if( !found || Host_CompareFileTime( newest, ft ) < 0 )
|
||||
{
|
||||
Q_strncpy( savename, t->filenames[i], sizeof( savename ));
|
||||
newest = ft;
|
||||
|
||||
@@ -80,24 +80,14 @@ def configure(conf):
|
||||
conf.env.HAVE_SDL2 = True
|
||||
else:
|
||||
conf.load('sdl2')
|
||||
if conf.options.SDL3:
|
||||
if not conf.env.HAVE_SDL3:
|
||||
conf.fatal('SDL3 not available! If you want to build dedicated server, specify --dedicated')
|
||||
conf.define('XASH_SDL', 3)
|
||||
else:
|
||||
if not conf.env.HAVE_SDL2:
|
||||
conf.fatal('SDL2 not available! If you want to build dedicated server, specify --dedicated')
|
||||
conf.define('XASH_SDL', 2)
|
||||
if not conf.env.HAVE_SDL2:
|
||||
conf.fatal('SDL2 not available! If you want to build dedicated server, specify --dedicated')
|
||||
conf.define('XASH_SDL', 2)
|
||||
|
||||
if conf.env.DEST_OS == 'haiku':
|
||||
conf.env.LIB_HAIKU = ['network']
|
||||
conf.env.LIBPATH_HAIKU = ['/boot/system/lib']
|
||||
|
||||
if conf.env.DEST_OS == 'wasi':
|
||||
conf.options.NO_ASYNC_RESOLVE = True
|
||||
conf.env.append_unique('CFLAGS', '-mllvm')
|
||||
conf.env.append_unique('CFLAGS', '-wasm-enable-sjlj')
|
||||
|
||||
if conf.options.STATIC:
|
||||
conf.env.STATIC = True
|
||||
conf.define('XASH_NO_LIBDL',1)
|
||||
@@ -182,8 +172,8 @@ def build(bld):
|
||||
source += bld.path.ant_glob(['platform/misc/lib_static.c'])
|
||||
is_cxx_link = True
|
||||
|
||||
if bld.env.HAVE_SDL2 or bld.env.HAVE_SDL3:
|
||||
libs.append('SDL3' if bld.env.HAVE_SDL3 else 'SDL2')
|
||||
if bld.env.HAVE_SDL2:
|
||||
libs.append('SDL2')
|
||||
source += bld.path.ant_glob(['platform/sdl/*.c'])
|
||||
|
||||
if bld.env.MAGX:
|
||||
@@ -232,8 +222,7 @@ def build(bld):
|
||||
'client/*.c',
|
||||
'client/vgui/*.c',
|
||||
'client/avi/*.c'])
|
||||
is_cxx_link = True
|
||||
libs += ['opus', 'bzip2', 'MultiEmulator']
|
||||
libs += ['opus']
|
||||
|
||||
includes = ['server', 'client', 'client/vgui' ]
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user