some improvements i think
This commit is contained in:
@@ -7,6 +7,23 @@
|
|||||||
#include "tier0/rand.h"
|
#include "tier0/rand.h"
|
||||||
|
|
||||||
IHTTPClientManager *g_pHttpClientMgr = NULL;
|
IHTTPClientManager *g_pHttpClientMgr = NULL;
|
||||||
|
static int base64_decode(const char *b64, unsigned char *pOut) {
|
||||||
|
int len = strlen(b64);
|
||||||
|
if (pOut == NULL)
|
||||||
|
return (len*3)/4;
|
||||||
|
int out_len = EVP_DecodeBlock(pOut,
|
||||||
|
(const unsigned char *)b64,
|
||||||
|
len);
|
||||||
|
if (out_len < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (len > 0 && b64[len - 1] == '=') {
|
||||||
|
out_len--;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out_len;
|
||||||
|
}
|
||||||
|
|
||||||
// autogenerated
|
// autogenerated
|
||||||
#define APPLE_LOCAL_USER "e2e70285da39596ef06153b9c4e1e5dc8d2f983bc5cd63f5b1e292207060d931"
|
#define APPLE_LOCAL_USER "e2e70285da39596ef06153b9c4e1e5dc8d2f983bc5cd63f5b1e292207060d931"
|
||||||
@@ -43,6 +60,7 @@ public:
|
|||||||
virtual EAppleAuthStatus SubmitLoginData( const char *szEmail, const char *szPassword ) override;
|
virtual EAppleAuthStatus SubmitLoginData( const char *szEmail, const char *szPassword ) override;
|
||||||
virtual EAppleAuthStatus Submit2FA( const char *szCode ) override;
|
virtual EAppleAuthStatus Submit2FA( const char *szCode ) override;
|
||||||
virtual CUtlString EncryptPassword( const char *szPassword, CUtlString szSalt, uint32_t uIters, EPasswordType eType );
|
virtual CUtlString EncryptPassword( const char *szPassword, CUtlString szSalt, uint32_t uIters, EPasswordType eType );
|
||||||
|
void ComputeM1( unsigned char M1[SHA256_DIGEST_LENGTH], const BIGNUM *N, const BIGNUM *g, const char *username, const char *password, const unsigned char *salt, size_t salt_len, const BIGNUM *A, const BIGNUM *B, const BIGNUM *a );
|
||||||
|
|
||||||
CUtlString FetchADIPB();
|
CUtlString FetchADIPB();
|
||||||
void FetchHeaders( CUtlString szAdiPb );
|
void FetchHeaders( CUtlString szAdiPb );
|
||||||
@@ -261,23 +279,20 @@ EAppleAuthStatus CAppleAuth::SubmitLoginData( const char *szEmail, const char *s
|
|||||||
BIGNUM* pA = BN_new();
|
BIGNUM* pA = BN_new();
|
||||||
BN_CTX *pbnCtx = BN_CTX_new();
|
BN_CTX *pbnCtx = BN_CTX_new();
|
||||||
|
|
||||||
/*
|
|
||||||
CUtlBuffer<unsigned char> bN;
|
|
||||||
CUtlBuffer<unsigned char> bG;
|
|
||||||
*/
|
|
||||||
SHA256_CTX pSha;
|
SHA256_CTX pSha;
|
||||||
unsigned char szHash[SHA256_DIGEST_LENGTH];
|
unsigned char pK[SHA256_DIGEST_LENGTH];
|
||||||
BN_hex2bn(&pN, N2048);
|
BN_hex2bn(&pN, N2048);
|
||||||
BN_hex2bn(&pG, G2048);
|
BN_hex2bn(&pG, G2048);
|
||||||
/*
|
CUtlBuffer<unsigned char> bN;
|
||||||
|
CUtlBuffer<unsigned char> bG;
|
||||||
bN = CUtlBuffer<unsigned char>(BN_num_bytes(pN));
|
bN = CUtlBuffer<unsigned char>(BN_num_bytes(pN));
|
||||||
bG = CUtlBuffer<unsigned char>(BN_num_bytes(pG));
|
bG = CUtlBuffer<unsigned char>(BN_num_bytes(pG));
|
||||||
BN_bn2bin(pN, bN.GetMemory());
|
BN_bn2bin(pN, bN.GetMemory());
|
||||||
SHA256_Init(&pSha);
|
SHA256_Init(&pSha);
|
||||||
SHA256_Update(&pSha, bN.GetMemory(), bN.GetSize());
|
SHA256_Update(&pSha, bN.GetMemory(), bN.GetSize());
|
||||||
SHA256_Update(&pSha, bG.GetMemory(), bG.GetSize());
|
SHA256_Update(&pSha, bG.GetMemory(), bG.GetSize());
|
||||||
SHA256_Final(szHash, &pSha);
|
SHA256_Final(pK, &pSha);
|
||||||
*/
|
|
||||||
BN_rand(pa, 256, 0, 0);
|
BN_rand(pa, 256, 0, 0);
|
||||||
BN_set_flags(pa, BN_FLG_CONSTTIME);
|
BN_set_flags(pa, BN_FLG_CONSTTIME);
|
||||||
BN_mod_exp(pA, pG, pa, pN, pbnCtx);
|
BN_mod_exp(pA, pG, pa, pN, pbnCtx);
|
||||||
@@ -368,39 +383,230 @@ EAppleAuthStatus CAppleAuth::SubmitLoginData( const char *szEmail, const char *s
|
|||||||
m_pGrandSlamClient->Post("/grandslam/GsService2", &header, plist.GetLenght(), plist);
|
m_pGrandSlamClient->Post("/grandslam/GsService2", &header, plist.GetLenght(), plist);
|
||||||
HTTPResponse_t stResponse = m_pGrandSlamClient->GetResponse();
|
HTTPResponse_t stResponse = m_pGrandSlamClient->GetResponse();
|
||||||
V_printf("%i %i\n", stResponse.m_uCode, stResponse.m_bIsComplete);
|
V_printf("%i %i\n", stResponse.m_uCode, stResponse.m_bIsComplete);
|
||||||
if (stResponse.m_uCode == 200)
|
if (stResponse.m_uCode != 200)
|
||||||
|
return APPLE_AUTH_FAILURE;
|
||||||
|
V_printf("%s\n",stResponse.m_message.GetMemory());
|
||||||
|
IJSONObject *pObject = PropertyListManager()->ReadString(stResponse.m_message);
|
||||||
|
IJSONObject *pResponse = pObject->GetValue("Response")->GetObject();
|
||||||
|
CUtlString szEncryptedPassword = EncryptPassword(szPassword, pResponse->GetValue("s")->GetStringValue(), pResponse->GetValue("i")->GetNumberValue(), PASSWORD_TYPE_S2K);
|
||||||
|
const char *szSalt = pResponse->GetValue("s")->GetStringValue();
|
||||||
|
const char *szB = pResponse->GetValue("B")->GetStringValue();
|
||||||
|
unsigned char salt[32];
|
||||||
|
int iSaltLen = base64_decode(szSalt, salt);
|
||||||
|
|
||||||
|
int iBLen = base64_decode(szB, NULL);
|
||||||
|
CUtlBuffer<unsigned char> BBuffer = CUtlBuffer<unsigned char>(iBLen);
|
||||||
|
iBLen = base64_decode(szB, BBuffer.GetMemory());
|
||||||
|
BIGNUM *pB = BN_bin2bn(BBuffer.GetMemory(), BBuffer.GetSize(), NULL);
|
||||||
|
unsigned char M1[SHA256_DIGEST_LENGTH];
|
||||||
|
ComputeM1(M1, pN, pG, szEmail, szPassword, salt, iSaltLen, pA, pB, pa);
|
||||||
|
|
||||||
|
CUtlString szM1 = {};
|
||||||
|
for ( int i = 0; i < SHA256_DIGEST_LENGTH; i++ )
|
||||||
{
|
{
|
||||||
V_printf("%s\n",stResponse.m_message.GetMemory());
|
szM1.AppendTail(CUtlString("%02x", M1[i]));
|
||||||
IJSONObject *pObject = PropertyListManager()->ReadString(stResponse.m_message);
|
|
||||||
IJSONObject *pResponse = pObject->GetValue("Response")->GetObject();
|
|
||||||
EncryptPassword(szPassword, pResponse->GetValue("s")->GetStringValue(), pResponse->GetValue("i")->GetNumberValue(), PASSWORD_TYPE_S2K);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plist = CUtlString(
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
|
||||||
|
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||||
|
"<plist version=\"1.0\">\n"
|
||||||
|
"<dict>\n"
|
||||||
|
"\t<key>Header</key>\n"
|
||||||
|
"\t<dict>\n"
|
||||||
|
"\t<key>Version</key>\n"
|
||||||
|
"\t<string>1.0.1</string>\n"
|
||||||
|
"\t</dict>\n"
|
||||||
|
|
||||||
|
"\t<key>Request</key>\n"
|
||||||
|
"\t<dict>\n"
|
||||||
|
|
||||||
|
"\t<key>M1</key>\n"
|
||||||
|
"\t<data>%s</data>\n"
|
||||||
|
|
||||||
|
"\t<key>c</key>\n"
|
||||||
|
"\t<string>%s</string>\n"
|
||||||
|
|
||||||
|
"\t<key>ps</key>\n"
|
||||||
|
"\t<array><string>s2k</string><string>s2k_fo</string></array>\n"
|
||||||
|
|
||||||
|
"\t<key>u</key>\n"
|
||||||
|
"\t<string>%s</string>\n"
|
||||||
|
|
||||||
|
"\t<key>o</key>\n"
|
||||||
|
"\t<string>complete</string>\n"
|
||||||
|
|
||||||
|
"\t<key>cpd</key>\n"
|
||||||
|
"\t<dict>\n"
|
||||||
|
|
||||||
|
"\t<key>X-Apple-I-Client-Time</key>\n"
|
||||||
|
"\t<string>2026-1-9T12:00:00Z</string>\n"
|
||||||
|
"\t<key>X-Apple-I-MD</key>\n"
|
||||||
|
"\t<string>%s</string>\n"
|
||||||
|
"\t<key>X-Apple-I-MD-LU</key>\n"
|
||||||
|
"\t<string>" APPLE_LOCAL_USER "</string>\n"
|
||||||
|
"\t<key>X-Apple-I-MD-M</key>\n"
|
||||||
|
"\t<string>%s</string>\n"
|
||||||
|
"\t<key>X-Apple-I-MD-RINFO</key>\n"
|
||||||
|
"\t<string>%s</string>\n"
|
||||||
|
"\t<key>X-Mme-Client-Info</key>\n"
|
||||||
|
"\t<string><MacBookPro13,2> <macOS;13.1;22C65> <com.apple.AuthKit/1 (com.apple.dt.Xcode/3594.4.19)></string>\n"
|
||||||
|
"\t<key>X-Apple-I-SRL-NO</key>\n"
|
||||||
|
"\t<string>0</string>\n"
|
||||||
|
|
||||||
|
|
||||||
|
"\t<key>bootstrap</key>\n"
|
||||||
|
"\t<trur/>\n"
|
||||||
|
|
||||||
|
"\t<key>icscrec</key>\n"
|
||||||
|
"\t<true/>\n"
|
||||||
|
|
||||||
|
|
||||||
|
"\t<key>pbe</key>\n"
|
||||||
|
"\t<false/>\n"
|
||||||
|
|
||||||
|
"\t<key>prkgen</key>\n"
|
||||||
|
"\t<true/>\n"
|
||||||
|
|
||||||
|
"\t<key>svct</key>\n"
|
||||||
|
"\t<string>iCloud</string>\n"
|
||||||
|
|
||||||
|
"\t<key>loc</key>\n"
|
||||||
|
"\t<string>en_US</string>\n"
|
||||||
|
|
||||||
|
"\t</dict>\n"
|
||||||
|
|
||||||
|
"\t</dict>\n"
|
||||||
|
"</dict>\n"
|
||||||
|
"</plist>\n", szM1.GetString(), pResponse->GetValue("c")->GetStringValue(), szEmail, m_szAppleIMD.GetString(), m_szAppleIMDM.GetString(), m_szAppleIMDRINFO.GetString());
|
||||||
|
V_printf("%s\n", plist.GetString());
|
||||||
|
m_pGrandSlamClient->Post("/grandslam/GsService2", &header, plist.GetLenght(), plist);
|
||||||
|
stResponse = m_pGrandSlamClient->GetResponse();
|
||||||
|
V_printf("%i %i\n", stResponse.m_uCode, stResponse.m_bIsComplete);
|
||||||
|
if (stResponse.m_uCode != 200)
|
||||||
|
return APPLE_AUTH_FAILURE;
|
||||||
|
V_printf("%s\n", stResponse.m_message.GetMemory());
|
||||||
|
|
||||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||||
|
|
||||||
|
|
||||||
OPENSSL_free(pszA);
|
OPENSSL_free(pszA);
|
||||||
return APPLE_AUTH_SUCCESS;
|
return APPLE_AUTH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hash_bn_pad(unsigned char out[SHA256_DIGEST_LENGTH], const BIGNUM *bn)
|
||||||
|
{
|
||||||
|
unsigned char buf[256];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
int len = BN_num_bytes(bn);
|
||||||
|
BN_bn2bin(bn, buf + (256 - len));
|
||||||
|
|
||||||
|
SHA256(buf, 256, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAppleAuth::ComputeM1(
|
||||||
|
unsigned char M1[SHA256_DIGEST_LENGTH],
|
||||||
|
const BIGNUM *N,
|
||||||
|
const BIGNUM *g,
|
||||||
|
const char *username,
|
||||||
|
const char *password,
|
||||||
|
const unsigned char *salt, size_t salt_len,
|
||||||
|
const BIGNUM *A,
|
||||||
|
const BIGNUM *B,
|
||||||
|
const BIGNUM *a
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
unsigned char HN[SHA256_DIGEST_LENGTH], Hg[SHA256_DIGEST_LENGTH], HNxorg[SHA256_DIGEST_LENGTH];
|
||||||
|
unsigned char HI[SHA256_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
/* H(N) xor H(g) */
|
||||||
|
hash_bn_pad(HN, N);
|
||||||
|
hash_bn_pad(Hg, g);
|
||||||
|
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||||
|
HNxorg[i] = HN[i] ^ Hg[i];
|
||||||
|
|
||||||
|
/* H(I) */
|
||||||
|
SHA256((const unsigned char *)username, strlen(username), HI);
|
||||||
|
|
||||||
|
/* x = H(s || H(I ":" P)) */
|
||||||
|
unsigned char inner_hash[SHA256_DIGEST_LENGTH];
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx, (const unsigned char *)username, strlen(username));
|
||||||
|
SHA256_Update(&ctx, (const unsigned char *)":", 1);
|
||||||
|
SHA256_Update(&ctx, (const unsigned char *)password, strlen(password));
|
||||||
|
SHA256_Final(inner_hash, &ctx);
|
||||||
|
|
||||||
|
unsigned char x_hash[SHA256_DIGEST_LENGTH];
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx, salt, salt_len);
|
||||||
|
SHA256_Update(&ctx, inner_hash, SHA256_DIGEST_LENGTH);
|
||||||
|
SHA256_Final(x_hash, &ctx);
|
||||||
|
|
||||||
|
BIGNUM *x = BN_bin2bn(x_hash, SHA256_DIGEST_LENGTH, NULL);
|
||||||
|
|
||||||
|
/* k = H(N || g) */
|
||||||
|
unsigned char k_hash[SHA256_DIGEST_LENGTH];
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
unsigned char bufN[256], bufg[256];
|
||||||
|
memset(bufN, 0, 256); BN_bn2bin(N, bufN + (256 - BN_num_bytes(N)));
|
||||||
|
memset(bufg, 0, 256); BN_bn2bin(g, bufg + (256 - BN_num_bytes(g)));
|
||||||
|
SHA256_Update(&ctx, bufN, 256);
|
||||||
|
SHA256_Update(&ctx, bufg, 256);
|
||||||
|
SHA256_Final(k_hash, &ctx);
|
||||||
|
BIGNUM *k = BN_bin2bn(k_hash, SHA256_DIGEST_LENGTH, NULL);
|
||||||
|
|
||||||
|
/* u = H(A || B) */
|
||||||
|
unsigned char bufA[256], bufB[256], u_hash[SHA256_DIGEST_LENGTH];
|
||||||
|
memset(bufA, 0, 256); BN_bn2bin(A, bufA + (256 - BN_num_bytes(A)));
|
||||||
|
memset(bufB, 0, 256); BN_bn2bin(B, bufB + (256 - BN_num_bytes(B)));
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx, bufA, 256);
|
||||||
|
SHA256_Update(&ctx, bufB, 256);
|
||||||
|
SHA256_Final(u_hash, &ctx);
|
||||||
|
BIGNUM *u = BN_bin2bn(u_hash, SHA256_DIGEST_LENGTH, NULL);
|
||||||
|
|
||||||
|
/* S = (B - k * g^x)^(a + u * x) mod N */
|
||||||
|
BN_CTX *bn_ctx = BN_CTX_new();
|
||||||
|
BIGNUM *gx = BN_new(), *kgx = BN_new(), *B_sub = BN_new();
|
||||||
|
BIGNUM *ux = BN_new(), *exp = BN_new(), *S = BN_new();
|
||||||
|
|
||||||
|
BN_mod_exp(gx, g, x, N, bn_ctx); /* g^x mod N */
|
||||||
|
BN_mod_mul(kgx, k, gx, N, bn_ctx); /* k * g^x mod N */
|
||||||
|
BN_mod_sub(B_sub, B, kgx, N, bn_ctx); /* B - k*g^x mod N */
|
||||||
|
BN_mul(ux, u, x, bn_ctx); /* u*x */
|
||||||
|
BN_add(exp, a, ux); /* a + u*x */
|
||||||
|
BN_mod_exp(S, B_sub, exp, N, bn_ctx); /* S */
|
||||||
|
|
||||||
|
/* K = H(S) */
|
||||||
|
unsigned char S_bytes[256];
|
||||||
|
memset(S_bytes, 0, 256);
|
||||||
|
BN_bn2bin(S, S_bytes + (256 - BN_num_bytes(S)));
|
||||||
|
unsigned char K[SHA256_DIGEST_LENGTH];
|
||||||
|
SHA256(S_bytes, 256, K);
|
||||||
|
|
||||||
|
/* Compute M1 */
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx, HNxorg, SHA256_DIGEST_LENGTH);
|
||||||
|
SHA256_Update(&ctx, HI, SHA256_DIGEST_LENGTH);
|
||||||
|
SHA256_Update(&ctx, salt, salt_len);
|
||||||
|
SHA256_Update(&ctx, bufA, 256);
|
||||||
|
SHA256_Update(&ctx, bufB, 256);
|
||||||
|
SHA256_Update(&ctx, K, SHA256_DIGEST_LENGTH);
|
||||||
|
SHA256_Final(M1, &ctx);
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
BN_free(x); BN_free(k); BN_free(u);
|
||||||
|
BN_free(gx); BN_free(kgx); BN_free(B_sub); BN_free(ux); BN_free(exp); BN_free(S);
|
||||||
|
BN_CTX_free(bn_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
EAppleAuthStatus CAppleAuth::Submit2FA( const char *szCode )
|
EAppleAuthStatus CAppleAuth::Submit2FA( const char *szCode )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int base64_decode(const char *b64, unsigned char *out) {
|
|
||||||
int len = strlen(b64);
|
|
||||||
int out_len = EVP_DecodeBlock(out,
|
|
||||||
(const unsigned char *)b64,
|
|
||||||
len);
|
|
||||||
if (out_len < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while (len > 0 && b64[len - 1] == '=') {
|
|
||||||
out_len--;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out_len;
|
|
||||||
}
|
|
||||||
CUtlString CAppleAuth::EncryptPassword( const char *szPassword, CUtlString szSalt, uint32_t uIters, EPasswordType eType )
|
CUtlString CAppleAuth::EncryptPassword( const char *szPassword, CUtlString szSalt, uint32_t uIters, EPasswordType eType )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
0
brv/build.cpp
Normal file
0
brv/build.cpp
Normal file
0
brv/cbrv.h
Normal file
0
brv/cbrv.h
Normal file
0
brv/modern.cpp
Normal file
0
brv/modern.cpp
Normal file
@@ -1,7 +1,7 @@
|
|||||||
# We want to build just enough to use other stuff
|
# We want to build just enough to use other stuff
|
||||||
TIER0_FILES := ../tier0/lib.cpp ../tier0/mem.cpp ../tier0/platform.cpp ../tier0/commandline.cpp ../tier0/rand.cpp
|
TIER0_FILES := ../tier0/lib.cpp ../tier0/mem.cpp ../tier0/platform.cpp ../tier0/commandline.cpp ../tier0/rand.cpp
|
||||||
TIER1_FILES := ../tier1/utlbuffer.cpp ../tier1/interface.cpp ../tier1/utlstring.cpp ../tier1/utlvector.cpp ../tier1/utlmap.cpp
|
TIER1_FILES := ../tier1/utlbuffer.cpp ../tier1/interface.cpp ../tier1/utlstring.cpp ../tier1/utlvector.cpp ../tier1/utlmap.cpp
|
||||||
TIER2_FILES := ../tier2/filesystem.cpp ../tier2/fileformats/ini.cpp
|
TIER2_FILES := ../tier2/filesystem.cpp ../tier2/fileformats/ini.cpp ../tier2/tokenizer.cpp ../tier2/fileformats/json.cpp
|
||||||
FILESYSTEM_FILES := ../stdfilesystems/filesystem_libc.cpp
|
FILESYSTEM_FILES := ../stdfilesystems/filesystem_libc.cpp
|
||||||
TIER1_OBJS := $(TIER1_FILES:.cpp=.o)
|
TIER1_OBJS := $(TIER1_FILES:.cpp=.o)
|
||||||
TIER2_OBJS := $(TIER2_FILES:.cpp=.o)
|
TIER2_OBJS := $(TIER2_FILES:.cpp=.o)
|
||||||
@@ -57,8 +57,8 @@ build/libfilesystem_std.so: $(FILESYSTEM_FILES) build/libtier1.a build/libtier0.
|
|||||||
build/libfpcbuild.a: buildfile/interfaces.o builddir
|
build/libfpcbuild.a: buildfile/interfaces.o builddir
|
||||||
ar rcs build/libfpcbuild.a buildfile/interfaces.o
|
ar rcs build/libfpcbuild.a buildfile/interfaces.o
|
||||||
|
|
||||||
build/libfpc.so: $(FPC_FILES) builddir build/libfpcbuild.a build/libtier1.a
|
build/libfpc.so: $(FPC_FILES) builddir build/libfpcbuild.a build/libtier1.a build/libtier2.a
|
||||||
$(CC) $(CCFLAGS) $(FPC_FILES) library/libfpc.cpp -fPIC -shared -o build/libfpc.so build/libtier1.a
|
$(CC) $(CCFLAGS) $(FPC_FILES) library/libfpc.cpp -fPIC -shared -o build/libfpc.so build/libtier1.a build/libtier2.a
|
||||||
|
|
||||||
builddir:
|
builddir:
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "tier1/interface.h"
|
#include "tier1/interface.h"
|
||||||
#include "tier1/utlstring.h"
|
#include "tier1/utlstring.h"
|
||||||
#include "tier1/utlvector.h"
|
#include "tier1/utlvector.h"
|
||||||
|
#include "tier2/fileformats/json.h"
|
||||||
#include "libgen.h"
|
#include "libgen.h"
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
|
||||||
@@ -245,23 +246,33 @@ skipcompile:
|
|||||||
|
|
||||||
void CClangCompiler::GenerateLinterData()
|
void CClangCompiler::GenerateLinterData()
|
||||||
{
|
{
|
||||||
|
CUtlVector<IJSONValue*> jsonValues = {};
|
||||||
FILE* f = V_fopen("compile_commands.json", "wb");
|
FILE* f = V_fopen("compile_commands.json", "wb");
|
||||||
V_fprintf(f, "[\n");
|
for ( auto &f: g_clangFiles )
|
||||||
uint32_t i = 0;
|
|
||||||
for (auto &file: g_clangFiles)
|
|
||||||
{
|
{
|
||||||
V_fprintf(f, "\t{\n");
|
IJSONObject *pFileObject = JSONManager()->CreateObject();
|
||||||
V_fprintf(f, "\t\t\"arguments\": [\n");
|
IJSONValue *pFileValue = JSONManager()->CreateValue();
|
||||||
for (auto &arg: file.m_szArguments)
|
IJSONArray *pArgumentFiles = JSONManager()->CreateArray();
|
||||||
V_fprintf(f, "\t\t\t\"%s\",\n",arg.GetString());
|
IJSONValue *pArgumentsValue = JSONManager()->CreateValue();
|
||||||
|
CUtlVector<IJSONValue*> values;
|
||||||
V_fseek(f, -2, SEEK_CUR);
|
|
||||||
V_fprintf(f, "\n\t\t],\n");
|
for (auto &arg: f.m_szArguments)
|
||||||
V_fprintf(f, "\t\t\"file\": \"%s\",\n", file.m_szName.GetString());
|
{
|
||||||
V_fprintf(f, "\t\t\"directory\": \"%s\"\n", filesystem2->BuildDirectory());
|
IJSONValue *pFileValue = JSONManager()->CreateValue();
|
||||||
V_fprintf(f, "\t},\n");
|
pFileValue->SetStringValue(arg.GetString());
|
||||||
|
values.AppendTail(pFileValue);
|
||||||
|
}
|
||||||
|
pArgumentFiles->SetArray(values.GetSize(), values.GetData());
|
||||||
|
pArgumentsValue->SetArrayValue(pArgumentFiles);
|
||||||
|
pFileObject->SetValue("arguments", pArgumentsValue);
|
||||||
|
pFileValue->SetObjectValue(pFileObject);
|
||||||
|
jsonValues.AppendTail(pFileValue);
|
||||||
};
|
};
|
||||||
V_fseek(f, -2, SEEK_CUR);
|
IJSONArray *pArray = JSONManager()->CreateArray();
|
||||||
V_fprintf(f, "\n]\n");
|
pArray->SetArray(jsonValues.GetSize(), jsonValues.GetData());
|
||||||
|
IJSONValue *pRoot = JSONManager()->CreateValue();
|
||||||
|
pRoot->SetArrayValue(pArray);
|
||||||
|
CUtlString szCommands = JSONManager()->WriteString(pRoot);
|
||||||
|
V_printf("JSON\n%s\n",szCommands.GetString());
|
||||||
V_fclose(f);
|
V_fclose(f);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "tier0/commandline.h"
|
#include "tier0/commandline.h"
|
||||||
#include "tier1/interface.h"
|
#include "tier1/interface.h"
|
||||||
#include "tier1/utlvector.h"
|
#include "tier1/utlvector.h"
|
||||||
|
#include "tier1/utlstring.h"
|
||||||
#include "tier2/ifilesystem.h"
|
#include "tier2/ifilesystem.h"
|
||||||
#include "tier2/fileformats/ini.h"
|
#include "tier2/fileformats/ini.h"
|
||||||
#include "public/c.h"
|
#include "public/c.h"
|
||||||
|
|||||||
0
fpc/sysroots/ios.cpp
Normal file
0
fpc/sysroots/ios.cpp
Normal file
0
fpc/sysroots/macos.cpp
Normal file
0
fpc/sysroots/macos.cpp
Normal file
0
fpc/sysroots/wdk.cpp
Normal file
0
fpc/sysroots/wdk.cpp
Normal file
10
fpc/sysroots/xcode.cpp
Normal file
10
fpc/sysroots/xcode.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "c.h"
|
||||||
|
#include "ld.h"
|
||||||
|
#include "helper.h"
|
||||||
|
#include "sysroots.h"
|
||||||
|
|
||||||
|
DECLARE_SYSROOT_INSTALL_STAGE(xcode_install)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define TIER2_JSON_H
|
#define TIER2_JSON_H
|
||||||
|
|
||||||
#include "tier0/platform.h"
|
#include "tier0/platform.h"
|
||||||
|
#include "tier1/utlstring.h"
|
||||||
|
|
||||||
class IJSONObject;
|
class IJSONObject;
|
||||||
class IJSONArray;
|
class IJSONArray;
|
||||||
@@ -27,9 +28,9 @@ abstract_class IJSONArray
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual uint32_t GetCount() = 0;
|
virtual uint32_t GetCount() = 0;
|
||||||
virtual IJSONObject *GetParameter( uint32_t i ) = 0;
|
virtual IJSONValue *GetParameter( uint32_t i ) = 0;
|
||||||
|
|
||||||
virtual void SetArray( uint32_t uCount, IJSONValue *pValue ) = 0;
|
virtual void SetArray( uint32_t uCount, IJSONValue **ppValues ) = 0;
|
||||||
|
|
||||||
virtual void CopyTo( IJSONArray *pObject ) = 0;
|
virtual void CopyTo( IJSONArray *pObject ) = 0;
|
||||||
virtual void Free() = 0;
|
virtual void Free() = 0;
|
||||||
@@ -77,7 +78,8 @@ public:
|
|||||||
virtual IJSONValue *CreateValue( ) = 0;
|
virtual IJSONValue *CreateValue( ) = 0;
|
||||||
virtual void FreeValue( IJSONValue *pValue ) = 0;
|
virtual void FreeValue( IJSONValue *pValue ) = 0;
|
||||||
|
|
||||||
virtual IJSONObject *ReadString( const char *szString ) = 0;
|
virtual IJSONValue *ReadString( const char *szString ) = 0;
|
||||||
|
virtual CUtlString WriteString( IJSONValue *pValue ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
IJSONManager *JSONManager();
|
IJSONManager *JSONManager();
|
||||||
|
|||||||
@@ -5,28 +5,32 @@ abstract_class CJSONArray: public IJSONArray
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual uint32_t GetCount() override;
|
virtual uint32_t GetCount() override;
|
||||||
virtual IJSONObject *GetParameter( uint32_t i ) override;
|
virtual IJSONValue *GetParameter( uint32_t i ) override;
|
||||||
|
|
||||||
virtual void SetArray( uint32_t uCount, IJSONValue *pValue ) override;
|
virtual void SetArray( uint32_t uCount, IJSONValue **ppValues ) override;
|
||||||
|
|
||||||
virtual void CopyTo( IJSONArray *pObject ) override;
|
virtual void CopyTo( IJSONArray *pObject ) override;
|
||||||
virtual void Free() override;
|
virtual void Free() override;
|
||||||
|
|
||||||
|
CUtlVector<IJSONValue*> m_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t CJSONArray::GetCount()
|
uint32_t CJSONArray::GetCount()
|
||||||
{
|
{
|
||||||
|
return m_values.GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
IJSONObject *CJSONArray::GetParameter( uint32_t i )
|
IJSONValue *CJSONArray::GetParameter( uint32_t i )
|
||||||
{
|
{
|
||||||
|
return m_values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CJSONArray::SetArray( uint32_t uCount, IJSONValue *pValue )
|
void CJSONArray::SetArray( uint32_t uCount, IJSONValue **ppValues )
|
||||||
{
|
{
|
||||||
|
m_values.Resize(uCount);
|
||||||
|
for ( uint32_t u = 0; u < uCount; u++)
|
||||||
|
m_values[u] = ppValues[u];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJSONArray::CopyTo( IJSONArray *pObject )
|
void CJSONArray::CopyTo( IJSONArray *pObject )
|
||||||
@@ -36,7 +40,9 @@ void CJSONArray::CopyTo( IJSONArray *pObject )
|
|||||||
|
|
||||||
void CJSONArray::Free()
|
void CJSONArray::Free()
|
||||||
{
|
{
|
||||||
|
for ( auto &value: m_values)
|
||||||
|
JSONManager()->FreeValue(value);
|
||||||
|
m_values = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract_class CJSONValue: public IJSONValue
|
abstract_class CJSONValue: public IJSONValue
|
||||||
@@ -118,30 +124,34 @@ void CJSONValue::MakeNULL()
|
|||||||
void CJSONValue::SetStringValue( const char *szString )
|
void CJSONValue::SetStringValue( const char *szString )
|
||||||
{
|
{
|
||||||
MakeNULL();
|
MakeNULL();
|
||||||
|
m_eType = JSON_PARAMETER_STRING;
|
||||||
m_szString = szString;
|
m_szString = szString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJSONValue::SetNumberValue( float fValue )
|
void CJSONValue::SetNumberValue( float fValue )
|
||||||
{
|
{
|
||||||
MakeNULL();
|
MakeNULL();
|
||||||
|
m_eType = JSON_PARAMETER_NUMBER;
|
||||||
m_fValue = fValue;
|
m_fValue = fValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJSONValue::SetBooleanValue( bool bValue )
|
void CJSONValue::SetBooleanValue( bool bValue )
|
||||||
{
|
{
|
||||||
MakeNULL();
|
MakeNULL();
|
||||||
|
m_eType = JSON_PARAMETER_BOOLEAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJSONValue::SetArrayValue( IJSONArray *pValue )
|
void CJSONValue::SetArrayValue( IJSONArray *pValue )
|
||||||
{
|
{
|
||||||
MakeNULL();
|
MakeNULL();
|
||||||
|
m_eType = JSON_PARAMETER_ARRAY;
|
||||||
|
m_pArray = pValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJSONValue::SetObjectValue( IJSONObject *pValue )
|
void CJSONValue::SetObjectValue( IJSONObject *pValue )
|
||||||
{
|
{
|
||||||
MakeNULL();
|
MakeNULL();
|
||||||
|
m_eType = JSON_PARAMETER_OBJECT;
|
||||||
m_pObject = pValue;
|
m_pObject = pValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,13 +244,17 @@ public:
|
|||||||
virtual IJSONValue *CreateValue( ) override;
|
virtual IJSONValue *CreateValue( ) override;
|
||||||
virtual void FreeValue( IJSONValue *pValue ) override;
|
virtual void FreeValue( IJSONValue *pValue ) override;
|
||||||
|
|
||||||
|
virtual IJSONValue *ReadString( const char *szString ) override;
|
||||||
|
virtual CUtlString WriteString( IJSONValue *pValue ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CUtlString RealWriteString( IJSONValue *pValue, uint32_t uOffest );
|
||||||
|
|
||||||
static bool ExpectedToken( Token_t &token, const char *szValue );
|
static bool ExpectedToken( Token_t &token, const char *szValue );
|
||||||
static CUtlString GetQuotedToken( Token_t &token );
|
static CUtlString GetQuotedToken( Token_t &token );
|
||||||
IJSONObject *ParseObject( Token_t *&pToken, const Token_t *pEnding );
|
IJSONObject *ParseObject( Token_t *&pToken, const Token_t *pEnding );
|
||||||
IJSONArray *ParseArray( Token_t *&pToken, const Token_t *pEnding );
|
IJSONArray *ParseArray( Token_t *&pToken, const Token_t *pEnding );
|
||||||
IJSONValue *ParseValue( Token_t *&pToken, const Token_t *pEnding );
|
IJSONValue *ParseValue( Token_t *&pToken, const Token_t *pEnding );
|
||||||
virtual IJSONObject *ReadString( const char *szString ) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IJSONObject *CJSONManager::CreateObject( )
|
IJSONObject *CJSONManager::CreateObject( )
|
||||||
@@ -256,12 +270,13 @@ void CJSONManager::FreeObject( IJSONObject *pObject )
|
|||||||
|
|
||||||
IJSONArray *CJSONManager::CreateArray( )
|
IJSONArray *CJSONManager::CreateArray( )
|
||||||
{
|
{
|
||||||
|
return new CJSONArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJSONManager::FreeArray( IJSONArray *pArray )
|
void CJSONManager::FreeArray( IJSONArray *pArray )
|
||||||
{
|
{
|
||||||
|
pArray->Free();
|
||||||
|
delete (CJSONObject*)pArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
IJSONValue *CJSONManager::CreateValue( )
|
IJSONValue *CJSONManager::CreateValue( )
|
||||||
@@ -343,7 +358,7 @@ not_comma:
|
|||||||
V_printf("%i: comma (,) or } was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
|
V_printf("%i: comma (,) or } was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
|
||||||
return NULL;
|
return NULL;
|
||||||
not_colon:
|
not_colon:
|
||||||
V_printf("%i: colon (:)was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
|
V_printf("%i: colon (:) was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
not_quoted:
|
not_quoted:
|
||||||
@@ -357,22 +372,66 @@ eof:
|
|||||||
|
|
||||||
IJSONArray *CJSONManager::ParseArray( Token_t *&pToken, const Token_t *pEnding )
|
IJSONArray *CJSONManager::ParseArray( Token_t *&pToken, const Token_t *pEnding )
|
||||||
{
|
{
|
||||||
|
IJSONArray *pObject;
|
||||||
|
CUtlString szParamName;
|
||||||
|
IJSONValue *pValue;
|
||||||
|
CUtlVector<IJSONValue*> values;
|
||||||
|
|
||||||
|
if ( !ExpectedToken(*(pToken), "[") )
|
||||||
|
return NULL;
|
||||||
|
NEXT_TOKEN();
|
||||||
|
pObject = CreateArray();
|
||||||
|
|
||||||
|
// object might be empty
|
||||||
|
if ( ExpectedToken(*pToken, "]") )
|
||||||
|
{
|
||||||
|
NEXT_TOKEN();
|
||||||
|
return pObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
pValue = ParseValue(pToken, pEnding);
|
||||||
|
values.AppendTail(pValue);
|
||||||
|
|
||||||
|
if ( !ExpectedToken(*pToken, ",") )
|
||||||
|
{
|
||||||
|
if ( !ExpectedToken(*pToken, "]") )
|
||||||
|
{
|
||||||
|
goto not_comma;
|
||||||
|
}
|
||||||
|
|
||||||
|
pObject->SetArray(values.GetSize(), values.GetData());
|
||||||
|
return pObject;
|
||||||
|
}
|
||||||
|
NEXT_TOKEN();
|
||||||
|
}
|
||||||
|
return pObject;
|
||||||
|
not_comma:
|
||||||
|
V_printf("%i: comma (,) or } was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
V_printf("EOF\n");
|
V_printf("EOF\n");
|
||||||
return NULL;
|
pObject->SetArray(values.GetSize(), values.GetData());
|
||||||
|
return pObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
IJSONValue *CJSONManager::ParseValue( Token_t *&pToken, const Token_t *pEnding )
|
IJSONValue *CJSONManager::ParseValue( Token_t *&pToken, const Token_t *pEnding )
|
||||||
{
|
{
|
||||||
IJSONObject *pObject = ParseObject(pToken, pEnding);
|
IJSONObject *pObject = ParseObject(pToken, pEnding);
|
||||||
IJSONArray *pArray = NULL;
|
IJSONArray *pArray = ParseArray(pToken, pEnding);
|
||||||
IJSONValue *pValue = CreateValue();
|
IJSONValue *pValue = CreateValue();
|
||||||
if (pObject)
|
if (pObject)
|
||||||
{
|
{
|
||||||
pValue->SetObjectValue(pObject);
|
pValue->SetObjectValue(pObject);
|
||||||
return pValue;
|
return pValue;
|
||||||
}
|
}
|
||||||
|
if (pArray)
|
||||||
|
{
|
||||||
|
pValue->SetArrayValue(pArray);
|
||||||
|
return pValue;
|
||||||
|
}
|
||||||
if ( GetQuotedToken(*pToken) != NULL )
|
if ( GetQuotedToken(*pToken) != NULL )
|
||||||
{
|
{
|
||||||
pValue->SetStringValue(pToken->m_szValue);
|
pValue->SetStringValue(pToken->m_szValue);
|
||||||
@@ -386,19 +445,81 @@ eof:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IJSONObject *CJSONManager::ReadString( const char *psz )
|
IJSONValue *CJSONManager::ReadString( const char *psz )
|
||||||
{
|
{
|
||||||
CUtlVector<Token_t> tokens;
|
CUtlVector<Token_t> tokens;
|
||||||
CUtlVector<char> stack;
|
CUtlVector<char> stack;
|
||||||
IJSONObject *pGlobalObject = NULL;
|
IJSONValue *pGlobalObject = NULL;
|
||||||
|
|
||||||
tokens = Tokenize(psz);
|
tokens = Tokenize(psz);
|
||||||
Token_t *pCurrentToken = tokens.GetData();
|
Token_t *pCurrentToken = tokens.GetData();
|
||||||
pGlobalObject = ParseObject(pCurrentToken, tokens.end().m_pCurrent);
|
pGlobalObject = ParseValue(pCurrentToken, tokens.end().m_pCurrent);
|
||||||
|
|
||||||
return pGlobalObject;
|
return pGlobalObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CUtlString CJSONManager::WriteString( IJSONValue *pValue )
|
||||||
|
{
|
||||||
|
return RealWriteString(pValue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUtlString CJSONManager::RealWriteString( IJSONValue *pValue, uint32_t uOffset )
|
||||||
|
{
|
||||||
|
IJSONArray *pArray;
|
||||||
|
CJSONObject *pObject;
|
||||||
|
CUtlString szString = "";
|
||||||
|
if (pValue)
|
||||||
|
switch (pValue->GetType())
|
||||||
|
{
|
||||||
|
case JSON_PARAMETER_NULL:
|
||||||
|
return CUtlString("null", pValue->GetNumberValue());
|
||||||
|
case JSON_PARAMETER_BOOLEAN:
|
||||||
|
if (pValue->GetBooleanValue())
|
||||||
|
return "true";
|
||||||
|
return "false";
|
||||||
|
case JSON_PARAMETER_NUMBER:
|
||||||
|
return CUtlString("\"%f\"", pValue->GetNumberValue());
|
||||||
|
case JSON_PARAMETER_STRING:
|
||||||
|
return CUtlString("\"%s\"", pValue->GetStringValue());
|
||||||
|
case JSON_PARAMETER_ARRAY:
|
||||||
|
pArray = pValue->GetArray();
|
||||||
|
szString.AppendTail("[\n");
|
||||||
|
for ( uint32_t i = 0; i < pArray->GetCount(); i++ )
|
||||||
|
{
|
||||||
|
for ( uint32_t j = 0; j <= uOffset; j++)
|
||||||
|
szString.AppendTail("\t");
|
||||||
|
szString.AppendTail(RealWriteString( pArray->GetParameter(i), uOffset+1 ));
|
||||||
|
if ( i != pArray->GetCount() - 1 )
|
||||||
|
szString.AppendTail(",");
|
||||||
|
szString.AppendTail("\n");
|
||||||
|
}
|
||||||
|
for ( uint32_t j = 0; j < uOffset; j++)
|
||||||
|
szString.AppendTail("\t");
|
||||||
|
szString.AppendTail("]");
|
||||||
|
return szString;
|
||||||
|
case JSON_PARAMETER_OBJECT:
|
||||||
|
pObject = (CJSONObject*)pValue->GetObject();
|
||||||
|
szString.AppendTail("{\n");
|
||||||
|
for ( uint32_t i = 0; i < pObject->m_params.GetSize(); i++ )
|
||||||
|
{
|
||||||
|
for ( uint32_t j = 0; j <= uOffset; j++)
|
||||||
|
szString.AppendTail("\t");
|
||||||
|
|
||||||
|
szString.AppendTail(pObject->m_params[i].m_szName);
|
||||||
|
szString.AppendTail(": ");
|
||||||
|
|
||||||
|
szString.AppendTail(RealWriteString( pObject->m_params[i].m_pValue, uOffset+1 ));
|
||||||
|
if ( i != pObject->m_params.GetSize() - 1 )
|
||||||
|
szString.AppendTail(",");
|
||||||
|
szString.AppendTail("\n");
|
||||||
|
}
|
||||||
|
for ( uint32_t j = 0; j < uOffset; j++)
|
||||||
|
szString.AppendTail("\t");
|
||||||
|
szString.AppendTail("}");
|
||||||
|
return szString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IJSONManager *JSONManager()
|
IJSONManager *JSONManager()
|
||||||
{
|
{
|
||||||
static CJSONManager mgr;
|
static CJSONManager mgr;
|
||||||
|
|||||||
Reference in New Issue
Block a user