diff options
-rw-r--r-- | .editorconfig | 11 | ||||
-rw-r--r-- | .git-blame-ignore-revs | 3 | ||||
-rw-r--r-- | .github/pull_request_template.md | 18 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 4 | ||||
-rw-r--r-- | NorthstarDLL/NorthstarDLL.vcxproj (renamed from NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj) | 1341 | ||||
-rw-r--r-- | NorthstarDLL/NorthstarDLL.vcxproj.filters (renamed from NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters) | 3576 | ||||
-rw-r--r-- | NorthstarDLL/audio.cpp (renamed from NorthstarDedicatedTest/audio.cpp) | 92 | ||||
-rw-r--r-- | NorthstarDLL/audio.h (renamed from NorthstarDedicatedTest/audio.h) | 4 | ||||
-rw-r--r-- | NorthstarDLL/audio_asm.asm (renamed from NorthstarDedicatedTest/audio_asm.asm) | 2 | ||||
-rw-r--r-- | NorthstarDLL/bansystem.cpp | 222 | ||||
-rw-r--r-- | NorthstarDLL/bansystem.h (renamed from NorthstarDedicatedTest/bansystem.h) | 5 | ||||
-rw-r--r-- | NorthstarDLL/bitbuf.h (renamed from NorthstarDedicatedTest/bitbuf.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/bits.cpp (renamed from NorthstarDedicatedTest/bits.cpp) | 0 | ||||
-rw-r--r-- | NorthstarDLL/bits.h (renamed from NorthstarDedicatedTest/bits.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/buildainfile.cpp (renamed from NorthstarDedicatedTest/buildainfile.cpp) | 74 | ||||
-rw-r--r-- | NorthstarDLL/chatcommand.cpp (renamed from NorthstarDedicatedTest/chatcommand.cpp) | 8 | ||||
-rw-r--r-- | NorthstarDLL/clientauthhooks.cpp (renamed from NorthstarDedicatedTest/clientauthhooks.cpp) | 29 | ||||
-rw-r--r-- | NorthstarDLL/clientchathooks.cpp | 83 | ||||
-rw-r--r-- | NorthstarDLL/clientruihooks.cpp | 24 | ||||
-rw-r--r-- | NorthstarDLL/clientvideooverrides.cpp | 42 | ||||
-rw-r--r-- | NorthstarDLL/color.h (renamed from NorthstarDedicatedTest/color.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/concommand.cpp (renamed from NorthstarDedicatedTest/concommand.cpp) | 53 | ||||
-rw-r--r-- | NorthstarDLL/concommand.h (renamed from NorthstarDedicatedTest/concommand.h) | 23 | ||||
-rw-r--r-- | NorthstarDLL/convar.cpp (renamed from NorthstarDedicatedTest/convar.cpp) | 36 | ||||
-rw-r--r-- | NorthstarDLL/convar.h (renamed from NorthstarDedicatedTest/convar.h) | 51 | ||||
-rw-r--r-- | NorthstarDLL/crashhandler.cpp (renamed from NorthstarDedicatedTest/logging.cpp) | 289 | ||||
-rw-r--r-- | NorthstarDLL/crashhandler.h | 4 | ||||
-rw-r--r-- | NorthstarDLL/cvar.cpp (renamed from NorthstarDedicatedTest/cvar.cpp) | 8 | ||||
-rw-r--r-- | NorthstarDLL/cvar.h (renamed from NorthstarDedicatedTest/cvar.h) | 8 | ||||
-rw-r--r-- | NorthstarDLL/debugoverlay.cpp (renamed from NorthstarDedicatedTest/debugoverlay.cpp) | 64 | ||||
-rw-r--r-- | NorthstarDLL/dedicated.cpp | 293 | ||||
-rw-r--r-- | NorthstarDLL/dedicated.h | 3 | ||||
-rw-r--r-- | NorthstarDLL/dedicatedmaterialsystem.cpp | 41 | ||||
-rw-r--r-- | NorthstarDLL/demofixes.cpp | 26 | ||||
-rw-r--r-- | NorthstarDLL/dllmain.cpp | 168 | ||||
-rw-r--r-- | NorthstarDLL/exploitfixes.cpp | 449 | ||||
-rw-r--r-- | NorthstarDLL/exploitfixes_lzss.cpp | 79 | ||||
-rw-r--r-- | NorthstarDLL/exploitfixes_utf8parser.cpp | 200 | ||||
-rw-r--r-- | NorthstarDLL/filesystem.cpp | 186 | ||||
-rw-r--r-- | NorthstarDLL/filesystem.h (renamed from NorthstarDedicatedTest/filesystem.h) | 14 | ||||
-rw-r--r-- | NorthstarDLL/hooks.cpp | 398 | ||||
-rw-r--r-- | NorthstarDLL/hooks.h | 311 | ||||
-rw-r--r-- | NorthstarDLL/host.cpp | 73 | ||||
-rw-r--r-- | NorthstarDLL/hoststate.cpp | 116 | ||||
-rw-r--r-- | NorthstarDLL/hoststate.h | 45 | ||||
-rw-r--r-- | NorthstarDLL/include/MinHook.h (renamed from NorthstarDedicatedTest/include/MinHook.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/MinHook.x64.lib (renamed from NorthstarDedicatedTest/include/MinHook.x64.lib) | bin | 32400 -> 32401 bytes | |||
-rw-r--r-- | NorthstarDLL/include/crypto/__DECC_INCLUDE_EPILOGUE.H (renamed from NorthstarDedicatedTest/include/crypto/__DECC_INCLUDE_EPILOGUE.H) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/__DECC_INCLUDE_PROLOGUE.H (renamed from NorthstarDedicatedTest/include/crypto/__DECC_INCLUDE_PROLOGUE.H) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/aes_platform.h (renamed from NorthstarDedicatedTest/include/crypto/aes_platform.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/aria.h (renamed from NorthstarDedicatedTest/include/crypto/aria.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/asn1.h (renamed from NorthstarDedicatedTest/include/crypto/asn1.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/asn1_dsa.h (renamed from NorthstarDedicatedTest/include/crypto/asn1_dsa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/asn1err.h (renamed from NorthstarDedicatedTest/include/crypto/asn1err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/async.h (renamed from NorthstarDedicatedTest/include/crypto/async.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/asyncerr.h (renamed from NorthstarDedicatedTest/include/crypto/asyncerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bioerr.h (renamed from NorthstarDedicatedTest/include/crypto/bioerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bn.h (renamed from NorthstarDedicatedTest/include/crypto/bn.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bn_conf.h (renamed from NorthstarDedicatedTest/include/crypto/bn_conf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bn_conf.h.in (renamed from NorthstarDedicatedTest/include/crypto/bn_conf.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bn_dh.h (renamed from NorthstarDedicatedTest/include/crypto/bn_dh.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bn_srp.h (renamed from NorthstarDedicatedTest/include/crypto/bn_srp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/bnerr.h (renamed from NorthstarDedicatedTest/include/crypto/bnerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/buffererr.h (renamed from NorthstarDedicatedTest/include/crypto/buffererr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/chacha.h (renamed from NorthstarDedicatedTest/include/crypto/chacha.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/cmll_platform.h (renamed from NorthstarDedicatedTest/include/crypto/cmll_platform.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/cmperr.h (renamed from NorthstarDedicatedTest/include/crypto/cmperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/cmserr.h (renamed from NorthstarDedicatedTest/include/crypto/cmserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/comperr.h (renamed from NorthstarDedicatedTest/include/crypto/comperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/conferr.h (renamed from NorthstarDedicatedTest/include/crypto/conferr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/crmferr.h (renamed from NorthstarDedicatedTest/include/crypto/crmferr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/cryptlib.h (renamed from NorthstarDedicatedTest/include/crypto/cryptlib.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/cryptoerr.h (renamed from NorthstarDedicatedTest/include/crypto/cryptoerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/cterr.h (renamed from NorthstarDedicatedTest/include/crypto/cterr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ctype.h (renamed from NorthstarDedicatedTest/include/crypto/ctype.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/decoder.h (renamed from NorthstarDedicatedTest/include/crypto/decoder.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/decodererr.h (renamed from NorthstarDedicatedTest/include/crypto/decodererr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/des_platform.h (renamed from NorthstarDedicatedTest/include/crypto/des_platform.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/dh.h (renamed from NorthstarDedicatedTest/include/crypto/dh.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/dherr.h (renamed from NorthstarDedicatedTest/include/crypto/dherr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/dsa.h (renamed from NorthstarDedicatedTest/include/crypto/dsa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/dsaerr.h (renamed from NorthstarDedicatedTest/include/crypto/dsaerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/dso_conf.h (renamed from NorthstarDedicatedTest/include/crypto/dso_conf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/dso_conf.h.in (renamed from NorthstarDedicatedTest/include/crypto/dso_conf.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ec.h (renamed from NorthstarDedicatedTest/include/crypto/ec.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ecerr.h (renamed from NorthstarDedicatedTest/include/crypto/ecerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ecx.h (renamed from NorthstarDedicatedTest/include/crypto/ecx.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/encoder.h (renamed from NorthstarDedicatedTest/include/crypto/encoder.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/encodererr.h (renamed from NorthstarDedicatedTest/include/crypto/encodererr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/engine.h (renamed from NorthstarDedicatedTest/include/crypto/engine.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/engineerr.h (renamed from NorthstarDedicatedTest/include/crypto/engineerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/err.h (renamed from NorthstarDedicatedTest/include/crypto/err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ess.h (renamed from NorthstarDedicatedTest/include/crypto/ess.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/esserr.h (renamed from NorthstarDedicatedTest/include/crypto/esserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/evp.h (renamed from NorthstarDedicatedTest/include/crypto/evp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/evperr.h (renamed from NorthstarDedicatedTest/include/crypto/evperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/httperr.h (renamed from NorthstarDedicatedTest/include/crypto/httperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/lhash.h (renamed from NorthstarDedicatedTest/include/crypto/lhash.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/md32_common.h (renamed from NorthstarDedicatedTest/include/crypto/md32_common.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/modes.h (renamed from NorthstarDedicatedTest/include/crypto/modes.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/objects.h (renamed from NorthstarDedicatedTest/include/crypto/objects.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/objectserr.h (renamed from NorthstarDedicatedTest/include/crypto/objectserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ocsperr.h (renamed from NorthstarDedicatedTest/include/crypto/ocsperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/pem.h (renamed from NorthstarDedicatedTest/include/crypto/pem.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/pemerr.h (renamed from NorthstarDedicatedTest/include/crypto/pemerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/pkcs12err.h (renamed from NorthstarDedicatedTest/include/crypto/pkcs12err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/pkcs7.h (renamed from NorthstarDedicatedTest/include/crypto/pkcs7.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/pkcs7err.h (renamed from NorthstarDedicatedTest/include/crypto/pkcs7err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/poly1305.h (renamed from NorthstarDedicatedTest/include/crypto/poly1305.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/ppc_arch.h (renamed from NorthstarDedicatedTest/include/crypto/ppc_arch.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/punycode.h (renamed from NorthstarDedicatedTest/include/crypto/punycode.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/rand.h (renamed from NorthstarDedicatedTest/include/crypto/rand.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/rand_pool.h (renamed from NorthstarDedicatedTest/include/crypto/rand_pool.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/randerr.h (renamed from NorthstarDedicatedTest/include/crypto/randerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/rsa.h (renamed from NorthstarDedicatedTest/include/crypto/rsa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/rsaerr.h (renamed from NorthstarDedicatedTest/include/crypto/rsaerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/security_bits.h (renamed from NorthstarDedicatedTest/include/crypto/security_bits.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/sha.h (renamed from NorthstarDedicatedTest/include/crypto/sha.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/siphash.h (renamed from NorthstarDedicatedTest/include/crypto/siphash.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/siv.h (renamed from NorthstarDedicatedTest/include/crypto/siv.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/sm2.h (renamed from NorthstarDedicatedTest/include/crypto/sm2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/sm2err.h (renamed from NorthstarDedicatedTest/include/crypto/sm2err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/sm4.h (renamed from NorthstarDedicatedTest/include/crypto/sm4.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/sparc_arch.h (renamed from NorthstarDedicatedTest/include/crypto/sparc_arch.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/sparse_array.h (renamed from NorthstarDedicatedTest/include/crypto/sparse_array.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/store.h (renamed from NorthstarDedicatedTest/include/crypto/store.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/storeerr.h (renamed from NorthstarDedicatedTest/include/crypto/storeerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/tserr.h (renamed from NorthstarDedicatedTest/include/crypto/tserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/types.h (renamed from NorthstarDedicatedTest/include/crypto/types.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/uierr.h (renamed from NorthstarDedicatedTest/include/crypto/uierr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/x509.h (renamed from NorthstarDedicatedTest/include/crypto/x509.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/x509err.h (renamed from NorthstarDedicatedTest/include/crypto/x509err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/crypto/x509v3err.h (renamed from NorthstarDedicatedTest/include/crypto/x509v3err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/httplib.h (renamed from NorthstarDedicatedTest/include/httplib.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/__DECC_INCLUDE_EPILOGUE.H (renamed from NorthstarDedicatedTest/include/internal/__DECC_INCLUDE_EPILOGUE.H) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/__DECC_INCLUDE_PROLOGUE.H (renamed from NorthstarDedicatedTest/include/internal/__DECC_INCLUDE_PROLOGUE.H) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/asn1.h (renamed from NorthstarDedicatedTest/include/internal/asn1.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/bio.h (renamed from NorthstarDedicatedTest/include/internal/bio.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/comp.h (renamed from NorthstarDedicatedTest/include/internal/comp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/conf.h (renamed from NorthstarDedicatedTest/include/internal/conf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/constant_time.h (renamed from NorthstarDedicatedTest/include/internal/constant_time.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/core.h (renamed from NorthstarDedicatedTest/include/internal/core.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/cryptlib.h (renamed from NorthstarDedicatedTest/include/internal/cryptlib.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/dane.h (renamed from NorthstarDedicatedTest/include/internal/dane.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/deprecated.h (renamed from NorthstarDedicatedTest/include/internal/deprecated.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/der.h (renamed from NorthstarDedicatedTest/include/internal/der.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/dso.h (renamed from NorthstarDedicatedTest/include/internal/dso.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/dsoerr.h (renamed from NorthstarDedicatedTest/include/internal/dsoerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/endian.h (renamed from NorthstarDedicatedTest/include/internal/endian.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/err.h (renamed from NorthstarDedicatedTest/include/internal/err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/ffc.h (renamed from NorthstarDedicatedTest/include/internal/ffc.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/ktls.h (renamed from NorthstarDedicatedTest/include/internal/ktls.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/namemap.h (renamed from NorthstarDedicatedTest/include/internal/namemap.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/nelem.h (renamed from NorthstarDedicatedTest/include/internal/nelem.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/numbers.h (renamed from NorthstarDedicatedTest/include/internal/numbers.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/o_dir.h (renamed from NorthstarDedicatedTest/include/internal/o_dir.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/packet.h (renamed from NorthstarDedicatedTest/include/internal/packet.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/param_build_set.h (renamed from NorthstarDedicatedTest/include/internal/param_build_set.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/passphrase.h (renamed from NorthstarDedicatedTest/include/internal/passphrase.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/property.h (renamed from NorthstarDedicatedTest/include/internal/property.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/propertyerr.h (renamed from NorthstarDedicatedTest/include/internal/propertyerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/provider.h (renamed from NorthstarDedicatedTest/include/internal/provider.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/refcount.h (renamed from NorthstarDedicatedTest/include/internal/refcount.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/sha3.h (renamed from NorthstarDedicatedTest/include/internal/sha3.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/sizes.h (renamed from NorthstarDedicatedTest/include/internal/sizes.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/sm3.h (renamed from NorthstarDedicatedTest/include/internal/sm3.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/sockets.h (renamed from NorthstarDedicatedTest/include/internal/sockets.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/sslconf.h (renamed from NorthstarDedicatedTest/include/internal/sslconf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/symhacks.h (renamed from NorthstarDedicatedTest/include/internal/symhacks.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/thread_once.h (renamed from NorthstarDedicatedTest/include/internal/thread_once.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/tlsgroups.h (renamed from NorthstarDedicatedTest/include/internal/tlsgroups.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/tsan_assist.h (renamed from NorthstarDedicatedTest/include/internal/tsan_assist.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/internal/unicode.h (renamed from NorthstarDedicatedTest/include/internal/unicode.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcrypto_static.lib (renamed from NorthstarDedicatedTest/include/libcrypto_static.lib) | bin | 35832382 -> 35832383 bytes | |||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/curl.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/curl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/curlver.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/curlver.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/easy.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/easy.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/mprintf.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/mprintf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/multi.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/multi.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/options.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/options.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/stdcheaders.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/stdcheaders.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/system.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/system.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/typecheck-gcc.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/typecheck-gcc.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/include/curl/urlapi.h (renamed from NorthstarDedicatedTest/include/libcurl/include/curl/urlapi.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/libcurl/lib/libcurl_a.lib (renamed from NorthstarDedicatedTest/include/libcurl/lib/libcurl_a.lib) | bin | 2140640 -> 2140641 bytes | |||
-rw-r--r-- | NorthstarDLL/include/libssl_static.lib (renamed from NorthstarDedicatedTest/include/libssl_static.lib) | bin | 4851208 -> 4851209 bytes | |||
-rw-r--r-- | NorthstarDLL/include/openssl/__DECC_INCLUDE_EPILOGUE.H (renamed from NorthstarDedicatedTest/include/openssl/__DECC_INCLUDE_EPILOGUE.H) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/__DECC_INCLUDE_PROLOGUE.H (renamed from NorthstarDedicatedTest/include/openssl/__DECC_INCLUDE_PROLOGUE.H) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/aes.h (renamed from NorthstarDedicatedTest/include/openssl/aes.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asn1.h (renamed from NorthstarDedicatedTest/include/openssl/asn1.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asn1.h.in (renamed from NorthstarDedicatedTest/include/openssl/asn1.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asn1_mac.h (renamed from NorthstarDedicatedTest/include/openssl/asn1_mac.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asn1err.h (renamed from NorthstarDedicatedTest/include/openssl/asn1err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asn1t.h (renamed from NorthstarDedicatedTest/include/openssl/asn1t.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asn1t.h.in (renamed from NorthstarDedicatedTest/include/openssl/asn1t.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/async.h (renamed from NorthstarDedicatedTest/include/openssl/async.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/asyncerr.h (renamed from NorthstarDedicatedTest/include/openssl/asyncerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/bio.h (renamed from NorthstarDedicatedTest/include/openssl/bio.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/bio.h.in (renamed from NorthstarDedicatedTest/include/openssl/bio.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/bioerr.h (renamed from NorthstarDedicatedTest/include/openssl/bioerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/blowfish.h (renamed from NorthstarDedicatedTest/include/openssl/blowfish.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/bn.h (renamed from NorthstarDedicatedTest/include/openssl/bn.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/bnerr.h (renamed from NorthstarDedicatedTest/include/openssl/bnerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/buffer.h (renamed from NorthstarDedicatedTest/include/openssl/buffer.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/buffererr.h (renamed from NorthstarDedicatedTest/include/openssl/buffererr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/camellia.h (renamed from NorthstarDedicatedTest/include/openssl/camellia.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cast.h (renamed from NorthstarDedicatedTest/include/openssl/cast.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cmac.h (renamed from NorthstarDedicatedTest/include/openssl/cmac.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cmp.h (renamed from NorthstarDedicatedTest/include/openssl/cmp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cmp.h.in (renamed from NorthstarDedicatedTest/include/openssl/cmp.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cmp_util.h (renamed from NorthstarDedicatedTest/include/openssl/cmp_util.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cmperr.h (renamed from NorthstarDedicatedTest/include/openssl/cmperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cms.h (renamed from NorthstarDedicatedTest/include/openssl/cms.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cms.h.in (renamed from NorthstarDedicatedTest/include/openssl/cms.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cmserr.h (renamed from NorthstarDedicatedTest/include/openssl/cmserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/comp.h (renamed from NorthstarDedicatedTest/include/openssl/comp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/comperr.h (renamed from NorthstarDedicatedTest/include/openssl/comperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/conf.h (renamed from NorthstarDedicatedTest/include/openssl/conf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/conf.h.in (renamed from NorthstarDedicatedTest/include/openssl/conf.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/conf_api.h (renamed from NorthstarDedicatedTest/include/openssl/conf_api.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/conferr.h (renamed from NorthstarDedicatedTest/include/openssl/conferr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/configuration.h (renamed from NorthstarDedicatedTest/include/openssl/configuration.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/configuration.h.in (renamed from NorthstarDedicatedTest/include/openssl/configuration.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/conftypes.h (renamed from NorthstarDedicatedTest/include/openssl/conftypes.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/core.h (renamed from NorthstarDedicatedTest/include/openssl/core.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/core_dispatch.h (renamed from NorthstarDedicatedTest/include/openssl/core_dispatch.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/core_names.h (renamed from NorthstarDedicatedTest/include/openssl/core_names.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/core_object.h (renamed from NorthstarDedicatedTest/include/openssl/core_object.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/crmf.h (renamed from NorthstarDedicatedTest/include/openssl/crmf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/crmf.h.in (renamed from NorthstarDedicatedTest/include/openssl/crmf.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/crmferr.h (renamed from NorthstarDedicatedTest/include/openssl/crmferr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/crypto.h (renamed from NorthstarDedicatedTest/include/openssl/crypto.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/crypto.h.in (renamed from NorthstarDedicatedTest/include/openssl/crypto.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cryptoerr.h (renamed from NorthstarDedicatedTest/include/openssl/cryptoerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cryptoerr_legacy.h (renamed from NorthstarDedicatedTest/include/openssl/cryptoerr_legacy.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ct.h (renamed from NorthstarDedicatedTest/include/openssl/ct.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ct.h.in (renamed from NorthstarDedicatedTest/include/openssl/ct.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/cterr.h (renamed from NorthstarDedicatedTest/include/openssl/cterr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/decoder.h (renamed from NorthstarDedicatedTest/include/openssl/decoder.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/decodererr.h (renamed from NorthstarDedicatedTest/include/openssl/decodererr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/des.h (renamed from NorthstarDedicatedTest/include/openssl/des.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/dh.h (renamed from NorthstarDedicatedTest/include/openssl/dh.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/dherr.h (renamed from NorthstarDedicatedTest/include/openssl/dherr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/dsa.h (renamed from NorthstarDedicatedTest/include/openssl/dsa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/dsaerr.h (renamed from NorthstarDedicatedTest/include/openssl/dsaerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/dtls1.h (renamed from NorthstarDedicatedTest/include/openssl/dtls1.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/e_os2.h (renamed from NorthstarDedicatedTest/include/openssl/e_os2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ebcdic.h (renamed from NorthstarDedicatedTest/include/openssl/ebcdic.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ec.h (renamed from NorthstarDedicatedTest/include/openssl/ec.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ecdh.h (renamed from NorthstarDedicatedTest/include/openssl/ecdh.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ecdsa.h (renamed from NorthstarDedicatedTest/include/openssl/ecdsa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ecerr.h (renamed from NorthstarDedicatedTest/include/openssl/ecerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/encoder.h (renamed from NorthstarDedicatedTest/include/openssl/encoder.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/encodererr.h (renamed from NorthstarDedicatedTest/include/openssl/encodererr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/engine.h (renamed from NorthstarDedicatedTest/include/openssl/engine.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/engineerr.h (renamed from NorthstarDedicatedTest/include/openssl/engineerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/err.h (renamed from NorthstarDedicatedTest/include/openssl/err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/err.h.in (renamed from NorthstarDedicatedTest/include/openssl/err.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ess.h (renamed from NorthstarDedicatedTest/include/openssl/ess.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ess.h.in (renamed from NorthstarDedicatedTest/include/openssl/ess.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/esserr.h (renamed from NorthstarDedicatedTest/include/openssl/esserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/evp.h (renamed from NorthstarDedicatedTest/include/openssl/evp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/evperr.h (renamed from NorthstarDedicatedTest/include/openssl/evperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/fips_names.h (renamed from NorthstarDedicatedTest/include/openssl/fips_names.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/fipskey.h (renamed from NorthstarDedicatedTest/include/openssl/fipskey.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/fipskey.h.in (renamed from NorthstarDedicatedTest/include/openssl/fipskey.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/hmac.h (renamed from NorthstarDedicatedTest/include/openssl/hmac.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/http.h (renamed from NorthstarDedicatedTest/include/openssl/http.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/httperr.h (renamed from NorthstarDedicatedTest/include/openssl/httperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/idea.h (renamed from NorthstarDedicatedTest/include/openssl/idea.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/kdf.h (renamed from NorthstarDedicatedTest/include/openssl/kdf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/kdferr.h (renamed from NorthstarDedicatedTest/include/openssl/kdferr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/lhash.h (renamed from NorthstarDedicatedTest/include/openssl/lhash.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/lhash.h.in (renamed from NorthstarDedicatedTest/include/openssl/lhash.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/macros.h (renamed from NorthstarDedicatedTest/include/openssl/macros.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/md2.h (renamed from NorthstarDedicatedTest/include/openssl/md2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/md4.h (renamed from NorthstarDedicatedTest/include/openssl/md4.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/md5.h (renamed from NorthstarDedicatedTest/include/openssl/md5.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/mdc2.h (renamed from NorthstarDedicatedTest/include/openssl/mdc2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/modes.h (renamed from NorthstarDedicatedTest/include/openssl/modes.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/obj_mac.h (renamed from NorthstarDedicatedTest/include/openssl/obj_mac.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/objects.h (renamed from NorthstarDedicatedTest/include/openssl/objects.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/objectserr.h (renamed from NorthstarDedicatedTest/include/openssl/objectserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ocsp.h (renamed from NorthstarDedicatedTest/include/openssl/ocsp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ocsp.h.in (renamed from NorthstarDedicatedTest/include/openssl/ocsp.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ocsperr.h (renamed from NorthstarDedicatedTest/include/openssl/ocsperr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/opensslconf.h (renamed from NorthstarDedicatedTest/include/openssl/opensslconf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/opensslv.h (renamed from NorthstarDedicatedTest/include/openssl/opensslv.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/opensslv.h.in (renamed from NorthstarDedicatedTest/include/openssl/opensslv.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ossl_typ.h (renamed from NorthstarDedicatedTest/include/openssl/ossl_typ.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/param_build.h (renamed from NorthstarDedicatedTest/include/openssl/param_build.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/params.h (renamed from NorthstarDedicatedTest/include/openssl/params.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pem.h (renamed from NorthstarDedicatedTest/include/openssl/pem.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pem2.h (renamed from NorthstarDedicatedTest/include/openssl/pem2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pemerr.h (renamed from NorthstarDedicatedTest/include/openssl/pemerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pkcs12.h (renamed from NorthstarDedicatedTest/include/openssl/pkcs12.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pkcs12.h.in (renamed from NorthstarDedicatedTest/include/openssl/pkcs12.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pkcs12err.h (renamed from NorthstarDedicatedTest/include/openssl/pkcs12err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pkcs7.h (renamed from NorthstarDedicatedTest/include/openssl/pkcs7.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pkcs7.h.in (renamed from NorthstarDedicatedTest/include/openssl/pkcs7.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/pkcs7err.h (renamed from NorthstarDedicatedTest/include/openssl/pkcs7err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/prov_ssl.h (renamed from NorthstarDedicatedTest/include/openssl/prov_ssl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/proverr.h (renamed from NorthstarDedicatedTest/include/openssl/proverr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/provider.h (renamed from NorthstarDedicatedTest/include/openssl/provider.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/rand.h (renamed from NorthstarDedicatedTest/include/openssl/rand.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/randerr.h (renamed from NorthstarDedicatedTest/include/openssl/randerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/rc2.h (renamed from NorthstarDedicatedTest/include/openssl/rc2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/rc4.h (renamed from NorthstarDedicatedTest/include/openssl/rc4.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/rc5.h (renamed from NorthstarDedicatedTest/include/openssl/rc5.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ripemd.h (renamed from NorthstarDedicatedTest/include/openssl/ripemd.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/rsa.h (renamed from NorthstarDedicatedTest/include/openssl/rsa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/rsaerr.h (renamed from NorthstarDedicatedTest/include/openssl/rsaerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/safestack.h (renamed from NorthstarDedicatedTest/include/openssl/safestack.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/safestack.h.in (renamed from NorthstarDedicatedTest/include/openssl/safestack.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/seed.h (renamed from NorthstarDedicatedTest/include/openssl/seed.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/self_test.h (renamed from NorthstarDedicatedTest/include/openssl/self_test.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/sha.h (renamed from NorthstarDedicatedTest/include/openssl/sha.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/srp.h (renamed from NorthstarDedicatedTest/include/openssl/srp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/srp.h.in (renamed from NorthstarDedicatedTest/include/openssl/srp.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/srtp.h (renamed from NorthstarDedicatedTest/include/openssl/srtp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ssl.h (renamed from NorthstarDedicatedTest/include/openssl/ssl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ssl.h.in (renamed from NorthstarDedicatedTest/include/openssl/ssl.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ssl2.h (renamed from NorthstarDedicatedTest/include/openssl/ssl2.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ssl3.h (renamed from NorthstarDedicatedTest/include/openssl/ssl3.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/sslerr.h (renamed from NorthstarDedicatedTest/include/openssl/sslerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/sslerr_legacy.h (renamed from NorthstarDedicatedTest/include/openssl/sslerr_legacy.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/stack.h (renamed from NorthstarDedicatedTest/include/openssl/stack.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/store.h (renamed from NorthstarDedicatedTest/include/openssl/store.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/storeerr.h (renamed from NorthstarDedicatedTest/include/openssl/storeerr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/symhacks.h (renamed from NorthstarDedicatedTest/include/openssl/symhacks.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/tls1.h (renamed from NorthstarDedicatedTest/include/openssl/tls1.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/trace.h (renamed from NorthstarDedicatedTest/include/openssl/trace.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ts.h (renamed from NorthstarDedicatedTest/include/openssl/ts.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/tserr.h (renamed from NorthstarDedicatedTest/include/openssl/tserr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/txt_db.h (renamed from NorthstarDedicatedTest/include/openssl/txt_db.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/types.h (renamed from NorthstarDedicatedTest/include/openssl/types.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ui.h (renamed from NorthstarDedicatedTest/include/openssl/ui.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/ui.h.in (renamed from NorthstarDedicatedTest/include/openssl/ui.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/uierr.h (renamed from NorthstarDedicatedTest/include/openssl/uierr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/whrlpool.h (renamed from NorthstarDedicatedTest/include/openssl/whrlpool.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509.h (renamed from NorthstarDedicatedTest/include/openssl/x509.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509.h.in (renamed from NorthstarDedicatedTest/include/openssl/x509.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509_vfy.h (renamed from NorthstarDedicatedTest/include/openssl/x509_vfy.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509_vfy.h.in (renamed from NorthstarDedicatedTest/include/openssl/x509_vfy.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509err.h (renamed from NorthstarDedicatedTest/include/openssl/x509err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509v3.h (renamed from NorthstarDedicatedTest/include/openssl/x509v3.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509v3.h.in (renamed from NorthstarDedicatedTest/include/openssl/x509v3.h.in) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/openssl/x509v3err.h (renamed from NorthstarDedicatedTest/include/openssl/x509v3err.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/allocators.h (renamed from NorthstarDedicatedTest/include/rapidjson/allocators.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/document.h (renamed from NorthstarDedicatedTest/include/rapidjson/document.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/encodedstream.h (renamed from NorthstarDedicatedTest/include/rapidjson/encodedstream.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/encodings.h (renamed from NorthstarDedicatedTest/include/rapidjson/encodings.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/error/en.h (renamed from NorthstarDedicatedTest/include/rapidjson/error/en.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/error/error.h (renamed from NorthstarDedicatedTest/include/rapidjson/error/error.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/filereadstream.h (renamed from NorthstarDedicatedTest/include/rapidjson/filereadstream.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/filewritestream.h (renamed from NorthstarDedicatedTest/include/rapidjson/filewritestream.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/fwd.h (renamed from NorthstarDedicatedTest/include/rapidjson/fwd.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/biginteger.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/biginteger.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/diyfp.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/diyfp.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/dtoa.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/dtoa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/ieee754.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/ieee754.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/itoa.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/itoa.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/meta.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/meta.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/pow10.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/pow10.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/regex.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/regex.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/stack.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/stack.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/strfunc.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/strfunc.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/strtod.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/strtod.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/internal/swap.h (renamed from NorthstarDedicatedTest/include/rapidjson/internal/swap.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/istreamwrapper.h (renamed from NorthstarDedicatedTest/include/rapidjson/istreamwrapper.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/memorybuffer.h (renamed from NorthstarDedicatedTest/include/rapidjson/memorybuffer.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/memorystream.h (renamed from NorthstarDedicatedTest/include/rapidjson/memorystream.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/msinttypes/inttypes.h (renamed from NorthstarDedicatedTest/include/rapidjson/msinttypes/inttypes.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/msinttypes/stdint.h (renamed from NorthstarDedicatedTest/include/rapidjson/msinttypes/stdint.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/ostreamwrapper.h (renamed from NorthstarDedicatedTest/include/rapidjson/ostreamwrapper.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/pointer.h (renamed from NorthstarDedicatedTest/include/rapidjson/pointer.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/prettywriter.h (renamed from NorthstarDedicatedTest/include/rapidjson/prettywriter.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/rapidjson.h (renamed from NorthstarDedicatedTest/include/rapidjson/rapidjson.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/reader.h (renamed from NorthstarDedicatedTest/include/rapidjson/reader.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/schema.h (renamed from NorthstarDedicatedTest/include/rapidjson/schema.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/stream.h (renamed from NorthstarDedicatedTest/include/rapidjson/stream.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/stringbuffer.h (renamed from NorthstarDedicatedTest/include/rapidjson/stringbuffer.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/rapidjson/writer.h (renamed from NorthstarDedicatedTest/include/rapidjson/writer.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/async.h (renamed from NorthstarDedicatedTest/include/spdlog/async.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/async_logger-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/async_logger-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/async_logger.h (renamed from NorthstarDedicatedTest/include/spdlog/async_logger.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/cfg/argv.h (renamed from NorthstarDedicatedTest/include/spdlog/cfg/argv.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/cfg/env.h (renamed from NorthstarDedicatedTest/include/spdlog/cfg/env.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/cfg/helpers-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/cfg/helpers-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/cfg/helpers.h (renamed from NorthstarDedicatedTest/include/spdlog/cfg/helpers.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/common-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/common-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/common.h (renamed from NorthstarDedicatedTest/include/spdlog/common.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/backtracer-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/backtracer-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/backtracer.h (renamed from NorthstarDedicatedTest/include/spdlog/details/backtracer.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/circular_q.h (renamed from NorthstarDedicatedTest/include/spdlog/details/circular_q.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/console_globals.h (renamed from NorthstarDedicatedTest/include/spdlog/details/console_globals.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/file_helper-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/file_helper-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/file_helper.h (renamed from NorthstarDedicatedTest/include/spdlog/details/file_helper.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/fmt_helper.h (renamed from NorthstarDedicatedTest/include/spdlog/details/fmt_helper.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/log_msg-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/log_msg-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/log_msg.h (renamed from NorthstarDedicatedTest/include/spdlog/details/log_msg.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/log_msg_buffer-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/log_msg_buffer-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/log_msg_buffer.h (renamed from NorthstarDedicatedTest/include/spdlog/details/log_msg_buffer.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/mpmc_blocking_q.h (renamed from NorthstarDedicatedTest/include/spdlog/details/mpmc_blocking_q.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/null_mutex.h (renamed from NorthstarDedicatedTest/include/spdlog/details/null_mutex.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/os-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/os-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/os.h (renamed from NorthstarDedicatedTest/include/spdlog/details/os.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/periodic_worker-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/periodic_worker-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/periodic_worker.h (renamed from NorthstarDedicatedTest/include/spdlog/details/periodic_worker.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/registry-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/registry-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/registry.h (renamed from NorthstarDedicatedTest/include/spdlog/details/registry.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/synchronous_factory.h (renamed from NorthstarDedicatedTest/include/spdlog/details/synchronous_factory.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/tcp_client-windows.h (renamed from NorthstarDedicatedTest/include/spdlog/details/tcp_client-windows.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/tcp_client.h (renamed from NorthstarDedicatedTest/include/spdlog/details/tcp_client.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/thread_pool-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/details/thread_pool-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/thread_pool.h (renamed from NorthstarDedicatedTest/include/spdlog/details/thread_pool.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/details/windows_include.h (renamed from NorthstarDedicatedTest/include/spdlog/details/windows_include.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bin_to_hex.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bin_to_hex.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/LICENSE.rst (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/LICENSE.rst) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/chrono.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/chrono.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/color.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/color.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/compile.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/compile.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/core.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/core.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/format-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/format-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/format.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/format.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/locale.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/locale.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/os.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/os.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/ostream.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/ostream.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/posix.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/posix.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/printf.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/printf.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/bundled/ranges.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/bundled/ranges.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/chrono.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/chrono.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/fmt.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/fmt.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fmt/ostr.h (renamed from NorthstarDedicatedTest/include/spdlog/fmt/ostr.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/formatter.h (renamed from NorthstarDedicatedTest/include/spdlog/formatter.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/fwd.h (renamed from NorthstarDedicatedTest/include/spdlog/fwd.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/logger-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/logger-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/logger.h (renamed from NorthstarDedicatedTest/include/spdlog/logger.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/pattern_formatter-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/pattern_formatter-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/pattern_formatter.h (renamed from NorthstarDedicatedTest/include/spdlog/pattern_formatter.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/android_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/android_sink.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/ansicolor_sink-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/ansicolor_sink-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/ansicolor_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/ansicolor_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/base_sink-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/base_sink-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/base_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/base_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/basic_file_sink-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/basic_file_sink-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/basic_file_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/basic_file_sink.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/daily_file_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/daily_file_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/dist_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/dist_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/dup_filter_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/dup_filter_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/hourly_file_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/hourly_file_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/msvc_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/msvc_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/null_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/null_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/ostream_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/ostream_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/ringbuffer_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/ringbuffer_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/rotating_file_sink-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/rotating_file_sink-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/rotating_file_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/rotating_file_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/sink-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/sink-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/stdout_color_sinks-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/stdout_color_sinks-inl.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/stdout_color_sinks.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/stdout_color_sinks.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/stdout_sinks-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/stdout_sinks-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/stdout_sinks.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/stdout_sinks.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/syslog_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/syslog_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/systemd_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/systemd_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/tcp_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/tcp_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/win_eventlog_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/win_eventlog_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/wincolor_sink-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/wincolor_sink-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/sinks/wincolor_sink.h (renamed from NorthstarDedicatedTest/include/spdlog/sinks/wincolor_sink.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/spdlog-inl.h (renamed from NorthstarDedicatedTest/include/spdlog/spdlog-inl.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/spdlog.h (renamed from NorthstarDedicatedTest/include/spdlog/spdlog.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/stopwatch.h (renamed from NorthstarDedicatedTest/include/spdlog/stopwatch.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/tweakme.h (renamed from NorthstarDedicatedTest/include/spdlog/tweakme.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/include/spdlog/version.h (renamed from NorthstarDedicatedTest/include/spdlog/version.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/keyvalues.cpp (renamed from NorthstarDedicatedTest/keyvalues.cpp) | 83 | ||||
-rw-r--r-- | NorthstarDLL/languagehooks.cpp (renamed from NorthstarDedicatedTest/languagehooks.cpp) | 29 | ||||
-rw-r--r-- | NorthstarDLL/latencyflex.cpp | 44 | ||||
-rw-r--r-- | NorthstarDLL/limits.cpp | 299 | ||||
-rw-r--r-- | NorthstarDLL/limits.h | 51 | ||||
-rw-r--r-- | NorthstarDLL/localchatwriter.cpp (renamed from NorthstarDedicatedTest/localchatwriter.cpp) | 87 | ||||
-rw-r--r-- | NorthstarDLL/localchatwriter.h (renamed from NorthstarDedicatedTest/localchatwriter.h) | 21 | ||||
-rw-r--r-- | NorthstarDLL/logging.cpp | 259 | ||||
-rw-r--r-- | NorthstarDLL/logging.h | 4 | ||||
-rw-r--r-- | NorthstarDLL/main.h (renamed from NorthstarDedicatedTest/main.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/masterserver.cpp | 1076 | ||||
-rw-r--r-- | NorthstarDLL/masterserver.h | 126 | ||||
-rw-r--r-- | NorthstarDLL/maxplayers.cpp | 645 | ||||
-rw-r--r-- | NorthstarDLL/maxplayers.h | 7 | ||||
-rw-r--r-- | NorthstarDLL/memalloc.cpp (renamed from NorthstarDedicatedTest/memalloc.cpp) | 24 | ||||
-rw-r--r-- | NorthstarDLL/memalloc.h (renamed from NorthstarDedicatedTest/memalloc.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/memory.cpp | 348 | ||||
-rw-r--r-- | NorthstarDLL/memory.h | 90 | ||||
-rw-r--r-- | NorthstarDLL/misccommands.cpp | 65 | ||||
-rw-r--r-- | NorthstarDLL/misccommands.h | 2 | ||||
-rw-r--r-- | NorthstarDLL/miscserverfixes.cpp | 7 | ||||
-rw-r--r-- | NorthstarDLL/miscserverscript.cpp | 65 | ||||
-rw-r--r-- | NorthstarDLL/modlocalisation.cpp | 35 | ||||
-rw-r--r-- | NorthstarDLL/modmanager.cpp (renamed from NorthstarDedicatedTest/modmanager.cpp) | 267 | ||||
-rw-r--r-- | NorthstarDLL/modmanager.h (renamed from NorthstarDedicatedTest/modmanager.h) | 46 | ||||
-rw-r--r-- | NorthstarDLL/ns_version.h (renamed from NorthstarDedicatedTest/ns_version.h) | 0 | ||||
-rw-r--r-- | NorthstarDLL/nsprefix.cpp (renamed from NorthstarDedicatedTest/configurables.cpp) | 6 | ||||
-rw-r--r-- | NorthstarDLL/nsprefix.h (renamed from NorthstarDedicatedTest/configurables.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/pch.cpp (renamed from NorthstarDedicatedTest/pch.cpp) | 0 | ||||
-rw-r--r-- | NorthstarDLL/pch.h (renamed from NorthstarDedicatedTest/pch.h) | 15 | ||||
-rw-r--r-- | NorthstarDLL/pdef.cpp (renamed from NorthstarDedicatedTest/pdef.cpp) | 20 | ||||
-rw-r--r-- | NorthstarDLL/pdef.h (renamed from NorthstarDedicatedTest/pdef.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/playlist.cpp | 130 | ||||
-rw-r--r-- | NorthstarDLL/playlist.h | 10 | ||||
-rw-r--r-- | NorthstarDLL/plugin_abi.h (renamed from NorthstarDedicatedTest/plugin_abi.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/plugins.cpp (renamed from NorthstarDedicatedTest/plugins.cpp) | 96 | ||||
-rw-r--r-- | NorthstarDLL/plugins.h (renamed from NorthstarDedicatedTest/plugins.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/printcommand.h | 6 | ||||
-rw-r--r-- | NorthstarDLL/printcommands.cpp | 174 | ||||
-rw-r--r-- | NorthstarDLL/printmaps.cpp | 168 | ||||
-rw-r--r-- | NorthstarDLL/printmaps.h | 2 | ||||
-rw-r--r-- | NorthstarDLL/r2client.cpp | 20 | ||||
-rw-r--r-- | NorthstarDLL/r2client.h | 11 | ||||
-rw-r--r-- | NorthstarDLL/r2engine.cpp | 36 | ||||
-rw-r--r-- | NorthstarDLL/r2engine.h | 199 | ||||
-rw-r--r-- | NorthstarDLL/r2server.cpp | 17 | ||||
-rw-r--r-- | NorthstarDLL/r2server.h | 19 | ||||
-rw-r--r-- | NorthstarDLL/rpakfilesystem.cpp | 299 | ||||
-rw-r--r-- | NorthstarDLL/rpakfilesystem.h | 39 | ||||
-rw-r--r-- | NorthstarDLL/runframe.cpp | 20 | ||||
-rw-r--r-- | NorthstarDLL/scriptbrowserhooks.cpp | 25 | ||||
-rw-r--r-- | NorthstarDLL/scriptdatatables.cpp | 940 | ||||
-rw-r--r-- | NorthstarDLL/scriptjson.cpp | 282 | ||||
-rw-r--r-- | NorthstarDLL/scriptmainmenupromos.cpp | 136 | ||||
-rw-r--r-- | NorthstarDLL/scriptmodmenu.cpp | 203 | ||||
-rw-r--r-- | NorthstarDLL/scriptserverbrowser.cpp | 458 | ||||
-rw-r--r-- | NorthstarDLL/scriptservertoclientstringcommand.cpp | 25 | ||||
-rw-r--r-- | NorthstarDLL/scriptsrson.cpp (renamed from NorthstarDedicatedTest/scriptsrson.cpp) | 23 | ||||
-rw-r--r-- | NorthstarDLL/scriptsrson.h (renamed from NorthstarDedicatedTest/scriptsrson.h) | 2 | ||||
-rw-r--r-- | NorthstarDLL/scriptutility.cpp | 23 | ||||
-rw-r--r-- | NorthstarDLL/serverauthentication.cpp | 401 | ||||
-rw-r--r-- | NorthstarDLL/serverauthentication.h | 57 | ||||
-rw-r--r-- | NorthstarDLL/serverchathooks.cpp | 183 | ||||
-rw-r--r-- | NorthstarDLL/serverchathooks.h (renamed from NorthstarDedicatedTest/serverchathooks.h) | 4 | ||||
-rw-r--r-- | NorthstarDLL/serverpresence.cpp | 233 | ||||
-rw-r--r-- | NorthstarDLL/serverpresence.h | 91 | ||||
-rw-r--r-- | NorthstarDLL/sourceconsole.cpp | 73 | ||||
-rw-r--r-- | NorthstarDLL/sourceconsole.h (renamed from NorthstarDedicatedTest/sourceconsole.h) | 17 | ||||
-rw-r--r-- | NorthstarDLL/sourceinterface.cpp | 49 | ||||
-rw-r--r-- | NorthstarDLL/sourceinterface.h (renamed from NorthstarDedicatedTest/sourceinterface.h) | 3 | ||||
-rw-r--r-- | NorthstarDLL/squirrel.cpp | 592 | ||||
-rw-r--r-- | NorthstarDLL/squirrel.h | 318 | ||||
-rw-r--r-- | NorthstarDLL/squirreldatatypes.h | 484 | ||||
-rw-r--r-- | NorthstarDLL/tier0.cpp | 37 | ||||
-rw-r--r-- | NorthstarDLL/tier0.h | 68 | ||||
-rw-r--r-- | NorthstarDLL/vector.h | 52 | ||||
-rw-r--r-- | NorthstarDLL/version.cpp (renamed from NorthstarDedicatedTest/version.cpp) | 0 | ||||
-rw-r--r-- | NorthstarDLL/version.h (renamed from NorthstarDedicatedTest/version.h) | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes.cpp | 419 | ||||
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes.h | 9 | ||||
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes_UTF8Parser.h | 175 | ||||
-rw-r--r-- | NorthstarDedicatedTest/NSMem.h | 211 | ||||
-rw-r--r-- | NorthstarDedicatedTest/bansystem.cpp | 106 | ||||
-rw-r--r-- | NorthstarDedicatedTest/buildainfile.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/chatcommand.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientauthhooks.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientchathooks.cpp | 95 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientchathooks.h | 5 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientruihooks.cpp | 24 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientruihooks.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientvideooverrides.cpp | 39 | ||||
-rw-r--r-- | NorthstarDedicatedTest/clientvideooverrides.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/context.cpp | 14 | ||||
-rw-r--r-- | NorthstarDedicatedTest/context.h | 11 | ||||
-rw-r--r-- | NorthstarDedicatedTest/debugoverlay.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicated.cpp | 329 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicated.h | 7 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicatedmaterialsystem.cpp | 123 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicatedmaterialsystem.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 297 | ||||
-rw-r--r-- | NorthstarDedicatedTest/emit_blocker.cpp | 26 | ||||
-rw-r--r-- | NorthstarDedicatedTest/emit_blocker.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/filesystem.cpp | 197 | ||||
-rw-r--r-- | NorthstarDedicatedTest/gameutils.cpp | 119 | ||||
-rw-r--r-- | NorthstarDedicatedTest/gameutils.h | 249 | ||||
-rw-r--r-- | NorthstarDedicatedTest/hooks.cpp | 255 | ||||
-rw-r--r-- | NorthstarDedicatedTest/hooks.h | 11 | ||||
-rw-r--r-- | NorthstarDedicatedTest/hookutils.cpp | 44 | ||||
-rw-r--r-- | NorthstarDedicatedTest/hookutils.h | 22 | ||||
-rw-r--r-- | NorthstarDedicatedTest/keyvalues.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/languagehooks.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/latencyflex.cpp | 44 | ||||
-rw-r--r-- | NorthstarDedicatedTest/latencyflex.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/logging.h | 7 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.cpp | 1366 | ||||
-rw-r--r-- | NorthstarDedicatedTest/masterserver.h | 133 | ||||
-rw-r--r-- | NorthstarDedicatedTest/maxplayers.cpp | 682 | ||||
-rw-r--r-- | NorthstarDedicatedTest/maxplayers.h | 4 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscclientfixes.cpp | 49 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscclientfixes.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/misccommands.cpp | 60 | ||||
-rw-r--r-- | NorthstarDedicatedTest/misccommands.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.cpp | 28 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.h | 1 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverscript.cpp | 66 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverscript.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modlocalisation.cpp | 37 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modlocalisation.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/playlist.cpp | 106 | ||||
-rw-r--r-- | NorthstarDedicatedTest/playlist.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/rpakfilesystem.cpp | 246 | ||||
-rw-r--r-- | NorthstarDedicatedTest/rpakfilesystem.h | 16 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptbrowserhooks.cpp | 27 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptbrowserhooks.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptmainmenupromos.cpp | 136 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptmainmenupromos.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptmodmenu.cpp | 203 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptmodmenu.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptserverbrowser.cpp | 441 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptserverbrowser.h | 4 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp | 24 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptservertoclientstringcommand.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.cpp | 743 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.h | 112 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverchathooks.cpp | 209 | ||||
-rw-r--r-- | NorthstarDedicatedTest/sigscanning.cpp | 41 | ||||
-rw-r--r-- | NorthstarDedicatedTest/sigscanning.h | 7 | ||||
-rw-r--r-- | NorthstarDedicatedTest/sourceconsole.cpp | 80 | ||||
-rw-r--r-- | NorthstarDedicatedTest/sourceinterface.cpp | 82 | ||||
-rw-r--r-- | NorthstarDedicatedTest/squirrel.cpp | 450 | ||||
-rw-r--r-- | NorthstarDedicatedTest/squirrel.h | 294 | ||||
-rw-r--r-- | NorthstarLauncher/NorthstarLauncher.vcxproj (renamed from LauncherInjector/LauncherInjector.vcxproj) | 10 | ||||
-rw-r--r-- | NorthstarLauncher/NorthstarLauncher.vcxproj.filters (renamed from LauncherInjector/LauncherInjector.vcxproj.filters) | 4 | ||||
-rw-r--r-- | NorthstarLauncher/main.cpp (renamed from LauncherInjector/main.cpp) | 94 | ||||
-rw-r--r-- | NorthstarLauncher/ns_icon.ico (renamed from LauncherInjector/ns_icon.ico) | bin | 1441814 -> 1441814 bytes | |||
-rw-r--r-- | NorthstarLauncher/resource1.h (renamed from LauncherInjector/resource1.h) | 0 | ||||
-rw-r--r-- | NorthstarLauncher/resources.rc (renamed from LauncherInjector/resources.rc) | 2 | ||||
-rw-r--r-- | R2Northstar.sln | 6 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | loader_launcher_proxy/Memory.cpp | 82 | ||||
-rw-r--r-- | loader_launcher_proxy/Memory.h | 24 | ||||
-rw-r--r-- | loader_launcher_proxy/dllmain.cpp | 229 | ||||
-rw-r--r-- | loader_launcher_proxy/framework.h | 4 | ||||
-rw-r--r-- | loader_launcher_proxy/loader_launcher_proxy.vcxproj | 4 | ||||
-rw-r--r-- | loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters | 4 | ||||
-rw-r--r-- | loader_launcher_proxy/pch.h | 2 | ||||
-rw-r--r-- | loader_wsock32_proxy/dllmain.cpp | 64 | ||||
-rw-r--r-- | loader_wsock32_proxy/hookutils.cpp | 54 | ||||
-rw-r--r-- | loader_wsock32_proxy/include/MinHook.h | 186 | ||||
-rw-r--r-- | loader_wsock32_proxy/include/MinHook.x64.lib | bin | 0 -> 32401 bytes | |||
-rw-r--r-- | loader_wsock32_proxy/loader.cpp | 32 | ||||
-rw-r--r-- | loader_wsock32_proxy/loader_wsock32_proxy.vcxproj | 10 | ||||
-rw-r--r-- | loader_wsock32_proxy/loader_wsock32_proxy.vcxproj.filters | 13 | ||||
-rw-r--r-- | loader_wsock32_proxy/pch.h | 4 |
648 files changed, 15425 insertions, 12192 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..bc423183 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# For more info on `.editorconfig` file see https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Newline ending every file +[*] +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = tab diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6838b387..10640d70 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -2,3 +2,6 @@ # Format commit 75bf194b2fca06de805a7bc025c6dd8379250fa5 + +# Folder rename +f9bc3c9d1834cb8bd5f872b749b057c33e8b0102 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..727a3060 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,18 @@ +<!-- +WHEN OPENING A PULL REQUEST KEEP IN MIND: +-> If the changes you made can be summarised in a screenshot, add one (e.g. you changed the layout of an in-game menu) +-> If the changes you made can be summarised in a screenrecording, add one (e.g. proof that you fixed a certain bug) + +-> For fixes, description on how to reproduce the bug are appreciated and help your PR get merged faster +-> For features, description on how to use the feature is appreciated and will help your PR get merged faster + +-> Please use a sensible title for your pull request + +-> Please describe the changes you made. The easier it is to understand what you changed, the higher the chances of your PR being merged (in a timely manner). + +-> If you made multiple independent changes, please make a new PR for each one. This prevents your PR being blocked from merging by one of the changes you made. + +Note that commit messages in PRs will generally be squashed to keep commit history clean. +--> + +Replace this line with a description of your change (and screenshots/screenrecordings if applicable). diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index affe0a37..d49a62f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,8 +34,8 @@ jobs: - uses: actions/checkout@v2 - uses: DoozyX/clang-format-lint-action@v0.13 with: - source: 'NorthstarDedicatedTest LauncherInjector' - exclude: 'NorthstarDedicatedTest/include loader_launcher_proxy loader_wsock32_proxy' + source: 'NorthstarDLL NorthstarLauncher' + exclude: 'NorthstarDLL/include loader_launcher_proxy loader_wsock32_proxy' extensions: 'h,cpp' clangFormatVersion: 13 style: file diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDLL/NorthstarDLL.vcxproj index cddbd3a7..b6f3ea37 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj +++ b/NorthstarDLL/NorthstarDLL.vcxproj @@ -1,669 +1,674 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>16.0</VCProjectVersion> - <Keyword>Win32Proj</Keyword> - <ProjectGuid>{cfad2623-064f-453c-8196-79ee10292e32}</ProjectGuid> - <RootNamespace>NorthstarDedicatedTest</RootNamespace> - <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> - <ProjectName>Northstar</ProjectName> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v143</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v143</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" /> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <WarningLevel>Level3</WarningLevel> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>_DEBUG;NORTHSTARDEDICATEDTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <PrecompiledHeader>Use</PrecompiledHeader> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> - <LanguageStandard>stdcpp17</LanguageStandard> - <AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableUAC>false</EnableUAC> - <AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcurl\lib\libcurl_a.lib;dbghelp.lib;Wldap32.lib;Normaliz.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies> - <ForceSymbolReferences> - </ForceSymbolReferences> - <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - </Link> - <PreBuildEvent> - <Command> - </Command> - </PreBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <WarningLevel>Level3</WarningLevel> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>NDEBUG;NORTHSTARDEDICATEDTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <PrecompiledHeader>Use</PrecompiledHeader> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> - <LanguageStandard>stdcpp17</LanguageStandard> - <AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableUAC>false</EnableUAC> - <AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcurl\lib\libcurl_a.lib;dbghelp.lib;Wldap32.lib;Normaliz.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies> - <ForceSymbolReferences> - </ForceSymbolReferences> - <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - </Link> - <PreBuildEvent> - <Command> - </Command> - </PreBuildEvent> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="audio.h" /> - <ClInclude Include="bansystem.h" /> - <ClInclude Include="bitbuf.h" /> - <ClInclude Include="bits.h" /> - <ClInclude Include="buildainfile.h" /> - <ClInclude Include="chatcommand.h" /> - <ClInclude Include="clientchathooks.h" /> - <ClInclude Include="debugoverlay.h" /> - <ClInclude Include="clientruihooks.h" /> - <ClInclude Include="clientvideooverrides.h" /> - <ClInclude Include="emit_blocker.h" /> - <ClInclude Include="localchatwriter.h" /> - <ClInclude Include="ns_version.h" /> - <ClInclude Include="plugins.h" /> - <ClInclude Include="plugin_abi.h" /> - <ClInclude Include="serverchathooks.h" /> - <ClInclude Include="clientauthhooks.h" /> - <ClInclude Include="color.h" /> - <ClInclude Include="concommand.h" /> - <ClInclude Include="configurables.h" /> - <ClInclude Include="context.h" /> - <ClInclude Include="convar.h" /> - <ClInclude Include="cvar.h" /> - <ClInclude Include="dedicated.h" /> - <ClInclude Include="dedicatedmaterialsystem.h" /> - <ClInclude Include="filesystem.h" /> - <ClInclude Include="gameutils.h" /> - <ClInclude Include="hooks.h" /> - <ClInclude Include="hookutils.h" /> - <ClInclude Include="include\crypto\aes_platform.h" /> - <ClInclude Include="include\crypto\aria.h" /> - <ClInclude Include="include\crypto\asn1.h" /> - <ClInclude Include="include\crypto\asn1err.h" /> - <ClInclude Include="include\crypto\asn1_dsa.h" /> - <ClInclude Include="include\crypto\async.h" /> - <ClInclude Include="include\crypto\asyncerr.h" /> - <ClInclude Include="include\crypto\bioerr.h" /> - <ClInclude Include="include\crypto\bn.h" /> - <ClInclude Include="include\crypto\bnerr.h" /> - <ClInclude Include="include\crypto\bn_conf.h" /> - <ClInclude Include="include\crypto\bn_dh.h" /> - <ClInclude Include="include\crypto\bn_srp.h" /> - <ClInclude Include="include\crypto\buffererr.h" /> - <ClInclude Include="include\crypto\chacha.h" /> - <ClInclude Include="include\crypto\cmll_platform.h" /> - <ClInclude Include="include\crypto\cmperr.h" /> - <ClInclude Include="include\crypto\cmserr.h" /> - <ClInclude Include="include\crypto\comperr.h" /> - <ClInclude Include="include\crypto\conferr.h" /> - <ClInclude Include="include\crypto\crmferr.h" /> - <ClInclude Include="include\crypto\cryptlib.h" /> - <ClInclude Include="include\crypto\cryptoerr.h" /> - <ClInclude Include="include\crypto\cterr.h" /> - <ClInclude Include="include\crypto\ctype.h" /> - <ClInclude Include="include\crypto\decoder.h" /> - <ClInclude Include="include\crypto\decodererr.h" /> - <ClInclude Include="include\crypto\des_platform.h" /> - <ClInclude Include="include\crypto\dh.h" /> - <ClInclude Include="include\crypto\dherr.h" /> - <ClInclude Include="include\crypto\dsa.h" /> - <ClInclude Include="include\crypto\dsaerr.h" /> - <ClInclude Include="include\crypto\dso_conf.h" /> - <ClInclude Include="include\crypto\ec.h" /> - <ClInclude Include="include\crypto\ecerr.h" /> - <ClInclude Include="include\crypto\ecx.h" /> - <ClInclude Include="include\crypto\encoder.h" /> - <ClInclude Include="include\crypto\encodererr.h" /> - <ClInclude Include="include\crypto\engine.h" /> - <ClInclude Include="include\crypto\engineerr.h" /> - <ClInclude Include="include\crypto\err.h" /> - <ClInclude Include="include\crypto\ess.h" /> - <ClInclude Include="include\crypto\esserr.h" /> - <ClInclude Include="include\crypto\evp.h" /> - <ClInclude Include="include\crypto\evperr.h" /> - <ClInclude Include="include\crypto\httperr.h" /> - <ClInclude Include="include\crypto\lhash.h" /> - <ClInclude Include="include\crypto\md32_common.h" /> - <ClInclude Include="include\crypto\modes.h" /> - <ClInclude Include="include\crypto\objects.h" /> - <ClInclude Include="include\crypto\objectserr.h" /> - <ClInclude Include="include\crypto\ocsperr.h" /> - <ClInclude Include="include\crypto\pem.h" /> - <ClInclude Include="include\crypto\pemerr.h" /> - <ClInclude Include="include\crypto\pkcs12err.h" /> - <ClInclude Include="include\crypto\pkcs7.h" /> - <ClInclude Include="include\crypto\pkcs7err.h" /> - <ClInclude Include="include\crypto\poly1305.h" /> - <ClInclude Include="include\crypto\ppc_arch.h" /> - <ClInclude Include="include\crypto\punycode.h" /> - <ClInclude Include="include\crypto\rand.h" /> - <ClInclude Include="include\crypto\randerr.h" /> - <ClInclude Include="include\crypto\rand_pool.h" /> - <ClInclude Include="include\crypto\rsa.h" /> - <ClInclude Include="include\crypto\rsaerr.h" /> - <ClInclude Include="include\crypto\security_bits.h" /> - <ClInclude Include="include\crypto\sha.h" /> - <ClInclude Include="include\crypto\siphash.h" /> - <ClInclude Include="include\crypto\siv.h" /> - <ClInclude Include="include\crypto\sm2.h" /> - <ClInclude Include="include\crypto\sm2err.h" /> - <ClInclude Include="include\crypto\sm4.h" /> - <ClInclude Include="include\crypto\sparc_arch.h" /> - <ClInclude Include="include\crypto\sparse_array.h" /> - <ClInclude Include="include\crypto\store.h" /> - <ClInclude Include="include\crypto\storeerr.h" /> - <ClInclude Include="include\crypto\tserr.h" /> - <ClInclude Include="include\crypto\types.h" /> - <ClInclude Include="include\crypto\uierr.h" /> - <ClInclude Include="include\crypto\x509.h" /> - <ClInclude Include="include\crypto\x509err.h" /> - <ClInclude Include="include\crypto\x509v3err.h" /> - <ClInclude Include="include\crypto\__DECC_INCLUDE_EPILOGUE.H" /> - <ClInclude Include="include\crypto\__DECC_INCLUDE_PROLOGUE.H" /> - <ClInclude Include="include\httplib.h" /> - <ClInclude Include="include\internal\asn1.h" /> - <ClInclude Include="include\internal\bio.h" /> - <ClInclude Include="include\internal\comp.h" /> - <ClInclude Include="include\internal\conf.h" /> - <ClInclude Include="include\internal\constant_time.h" /> - <ClInclude Include="include\internal\core.h" /> - <ClInclude Include="include\internal\cryptlib.h" /> - <ClInclude Include="include\internal\dane.h" /> - <ClInclude Include="include\internal\deprecated.h" /> - <ClInclude Include="include\internal\der.h" /> - <ClInclude Include="include\internal\dso.h" /> - <ClInclude Include="include\internal\dsoerr.h" /> - <ClInclude Include="include\internal\endian.h" /> - <ClInclude Include="include\internal\err.h" /> - <ClInclude Include="include\internal\ffc.h" /> - <ClInclude Include="include\internal\ktls.h" /> - <ClInclude Include="include\internal\namemap.h" /> - <ClInclude Include="include\internal\nelem.h" /> - <ClInclude Include="include\internal\numbers.h" /> - <ClInclude Include="include\internal\o_dir.h" /> - <ClInclude Include="include\internal\packet.h" /> - <ClInclude Include="include\internal\param_build_set.h" /> - <ClInclude Include="include\internal\passphrase.h" /> - <ClInclude Include="include\internal\property.h" /> - <ClInclude Include="include\internal\propertyerr.h" /> - <ClInclude Include="include\internal\provider.h" /> - <ClInclude Include="include\internal\refcount.h" /> - <ClInclude Include="include\internal\sha3.h" /> - <ClInclude Include="include\internal\sizes.h" /> - <ClInclude Include="include\internal\sm3.h" /> - <ClInclude Include="include\internal\sockets.h" /> - <ClInclude Include="include\internal\sslconf.h" /> - <ClInclude Include="include\internal\symhacks.h" /> - <ClInclude Include="include\internal\thread_once.h" /> - <ClInclude Include="include\internal\tlsgroups.h" /> - <ClInclude Include="include\internal\tsan_assist.h" /> - <ClInclude Include="include\internal\unicode.h" /> - <ClInclude Include="include\internal\__DECC_INCLUDE_EPILOGUE.H" /> - <ClInclude Include="include\internal\__DECC_INCLUDE_PROLOGUE.H" /> - <ClInclude Include="include\libcurl\include\curl\curl.h" /> - <ClInclude Include="include\libcurl\include\curl\curlver.h" /> - <ClInclude Include="include\libcurl\include\curl\easy.h" /> - <ClInclude Include="include\libcurl\include\curl\mprintf.h" /> - <ClInclude Include="include\libcurl\include\curl\multi.h" /> - <ClInclude Include="include\libcurl\include\curl\options.h" /> - <ClInclude Include="include\libcurl\include\curl\stdcheaders.h" /> - <ClInclude Include="include\libcurl\include\curl\system.h" /> - <ClInclude Include="include\libcurl\include\curl\typecheck-gcc.h" /> - <ClInclude Include="include\libcurl\include\curl\urlapi.h" /> - <ClInclude Include="include\MinHook.h" /> - <ClInclude Include="include\openssl\aes.h" /> - <ClInclude Include="include\openssl\asn1.h" /> - <ClInclude Include="include\openssl\asn1err.h" /> - <ClInclude Include="include\openssl\asn1t.h" /> - <ClInclude Include="include\openssl\asn1_mac.h" /> - <ClInclude Include="include\openssl\async.h" /> - <ClInclude Include="include\openssl\asyncerr.h" /> - <ClInclude Include="include\openssl\bio.h" /> - <ClInclude Include="include\openssl\bioerr.h" /> - <ClInclude Include="include\openssl\blowfish.h" /> - <ClInclude Include="include\openssl\bn.h" /> - <ClInclude Include="include\openssl\bnerr.h" /> - <ClInclude Include="include\openssl\buffer.h" /> - <ClInclude Include="include\openssl\buffererr.h" /> - <ClInclude Include="include\openssl\camellia.h" /> - <ClInclude Include="include\openssl\cast.h" /> - <ClInclude Include="include\openssl\cmac.h" /> - <ClInclude Include="include\openssl\cmp.h" /> - <ClInclude Include="include\openssl\cmperr.h" /> - <ClInclude Include="include\openssl\cmp_util.h" /> - <ClInclude Include="include\openssl\cms.h" /> - <ClInclude Include="include\openssl\cmserr.h" /> - <ClInclude Include="include\openssl\comp.h" /> - <ClInclude Include="include\openssl\comperr.h" /> - <ClInclude Include="include\openssl\conf.h" /> - <ClInclude Include="include\openssl\conferr.h" /> - <ClInclude Include="include\openssl\configuration.h" /> - <ClInclude Include="include\openssl\conftypes.h" /> - <ClInclude Include="include\openssl\conf_api.h" /> - <ClInclude Include="include\openssl\core.h" /> - <ClInclude Include="include\openssl\core_dispatch.h" /> - <ClInclude Include="include\openssl\core_names.h" /> - <ClInclude Include="include\openssl\core_object.h" /> - <ClInclude Include="include\openssl\crmf.h" /> - <ClInclude Include="include\openssl\crmferr.h" /> - <ClInclude Include="include\openssl\crypto.h" /> - <ClInclude Include="include\openssl\cryptoerr.h" /> - <ClInclude Include="include\openssl\cryptoerr_legacy.h" /> - <ClInclude Include="include\openssl\ct.h" /> - <ClInclude Include="include\openssl\cterr.h" /> - <ClInclude Include="include\openssl\decoder.h" /> - <ClInclude Include="include\openssl\decodererr.h" /> - <ClInclude Include="include\openssl\des.h" /> - <ClInclude Include="include\openssl\dh.h" /> - <ClInclude Include="include\openssl\dherr.h" /> - <ClInclude Include="include\openssl\dsa.h" /> - <ClInclude Include="include\openssl\dsaerr.h" /> - <ClInclude Include="include\openssl\dtls1.h" /> - <ClInclude Include="include\openssl\ebcdic.h" /> - <ClInclude Include="include\openssl\ec.h" /> - <ClInclude Include="include\openssl\ecdh.h" /> - <ClInclude Include="include\openssl\ecdsa.h" /> - <ClInclude Include="include\openssl\ecerr.h" /> - <ClInclude Include="include\openssl\encoder.h" /> - <ClInclude Include="include\openssl\encodererr.h" /> - <ClInclude Include="include\openssl\engine.h" /> - <ClInclude Include="include\openssl\engineerr.h" /> - <ClInclude Include="include\openssl\err.h" /> - <ClInclude Include="include\openssl\ess.h" /> - <ClInclude Include="include\openssl\esserr.h" /> - <ClInclude Include="include\openssl\evp.h" /> - <ClInclude Include="include\openssl\evperr.h" /> - <ClInclude Include="include\openssl\e_os2.h" /> - <ClInclude Include="include\openssl\fipskey.h" /> - <ClInclude Include="include\openssl\fips_names.h" /> - <ClInclude Include="include\openssl\hmac.h" /> - <ClInclude Include="include\openssl\http.h" /> - <ClInclude Include="include\openssl\httperr.h" /> - <ClInclude Include="include\openssl\idea.h" /> - <ClInclude Include="include\openssl\kdf.h" /> - <ClInclude Include="include\openssl\kdferr.h" /> - <ClInclude Include="include\openssl\lhash.h" /> - <ClInclude Include="include\openssl\macros.h" /> - <ClInclude Include="include\openssl\md2.h" /> - <ClInclude Include="include\openssl\md4.h" /> - <ClInclude Include="include\openssl\md5.h" /> - <ClInclude Include="include\openssl\mdc2.h" /> - <ClInclude Include="include\openssl\modes.h" /> - <ClInclude Include="include\openssl\objects.h" /> - <ClInclude Include="include\openssl\objectserr.h" /> - <ClInclude Include="include\openssl\obj_mac.h" /> - <ClInclude Include="include\openssl\ocsp.h" /> - <ClInclude Include="include\openssl\ocsperr.h" /> - <ClInclude Include="include\openssl\opensslconf.h" /> - <ClInclude Include="include\openssl\opensslv.h" /> - <ClInclude Include="include\openssl\ossl_typ.h" /> - <ClInclude Include="include\openssl\params.h" /> - <ClInclude Include="include\openssl\param_build.h" /> - <ClInclude Include="include\openssl\pem.h" /> - <ClInclude Include="include\openssl\pem2.h" /> - <ClInclude Include="include\openssl\pemerr.h" /> - <ClInclude Include="include\openssl\pkcs12.h" /> - <ClInclude Include="include\openssl\pkcs12err.h" /> - <ClInclude Include="include\openssl\pkcs7.h" /> - <ClInclude Include="include\openssl\pkcs7err.h" /> - <ClInclude Include="include\openssl\proverr.h" /> - <ClInclude Include="include\openssl\provider.h" /> - <ClInclude Include="include\openssl\prov_ssl.h" /> - <ClInclude Include="include\openssl\rand.h" /> - <ClInclude Include="include\openssl\randerr.h" /> - <ClInclude Include="include\openssl\rc2.h" /> - <ClInclude Include="include\openssl\rc4.h" /> - <ClInclude Include="include\openssl\rc5.h" /> - <ClInclude Include="include\openssl\ripemd.h" /> - <ClInclude Include="include\openssl\rsa.h" /> - <ClInclude Include="include\openssl\rsaerr.h" /> - <ClInclude Include="include\openssl\safestack.h" /> - <ClInclude Include="include\openssl\seed.h" /> - <ClInclude Include="include\openssl\self_test.h" /> - <ClInclude Include="include\openssl\sha.h" /> - <ClInclude Include="include\openssl\srp.h" /> - <ClInclude Include="include\openssl\srtp.h" /> - <ClInclude Include="include\openssl\ssl.h" /> - <ClInclude Include="include\openssl\ssl2.h" /> - <ClInclude Include="include\openssl\ssl3.h" /> - <ClInclude Include="include\openssl\sslerr.h" /> - <ClInclude Include="include\openssl\sslerr_legacy.h" /> - <ClInclude Include="include\openssl\stack.h" /> - <ClInclude Include="include\openssl\store.h" /> - <ClInclude Include="include\openssl\storeerr.h" /> - <ClInclude Include="include\openssl\symhacks.h" /> - <ClInclude Include="include\openssl\tls1.h" /> - <ClInclude Include="include\openssl\trace.h" /> - <ClInclude Include="include\openssl\ts.h" /> - <ClInclude Include="include\openssl\tserr.h" /> - <ClInclude Include="include\openssl\txt_db.h" /> - <ClInclude Include="include\openssl\types.h" /> - <ClInclude Include="include\openssl\ui.h" /> - <ClInclude Include="include\openssl\uierr.h" /> - <ClInclude Include="include\openssl\whrlpool.h" /> - <ClInclude Include="include\openssl\x509.h" /> - <ClInclude Include="include\openssl\x509err.h" /> - <ClInclude Include="include\openssl\x509v3.h" /> - <ClInclude Include="include\openssl\x509v3err.h" /> - <ClInclude Include="include\openssl\x509_vfy.h" /> - <ClInclude Include="include\openssl\__DECC_INCLUDE_EPILOGUE.H" /> - <ClInclude Include="include\openssl\__DECC_INCLUDE_PROLOGUE.H" /> - <ClInclude Include="include\rapidjson\allocators.h" /> - <ClInclude Include="include\rapidjson\document.h" /> - <ClInclude Include="include\rapidjson\encodedstream.h" /> - <ClInclude Include="include\rapidjson\encodings.h" /> - <ClInclude Include="include\rapidjson\error\en.h" /> - <ClInclude Include="include\rapidjson\error\error.h" /> - <ClInclude Include="include\rapidjson\filereadstream.h" /> - <ClInclude Include="include\rapidjson\filewritestream.h" /> - <ClInclude Include="include\rapidjson\fwd.h" /> - <ClInclude Include="include\rapidjson\internal\biginteger.h" /> - <ClInclude Include="include\rapidjson\internal\diyfp.h" /> - <ClInclude Include="include\rapidjson\internal\dtoa.h" /> - <ClInclude Include="include\rapidjson\internal\ieee754.h" /> - <ClInclude Include="include\rapidjson\internal\itoa.h" /> - <ClInclude Include="include\rapidjson\internal\meta.h" /> - <ClInclude Include="include\rapidjson\internal\pow10.h" /> - <ClInclude Include="include\rapidjson\internal\regex.h" /> - <ClInclude Include="include\rapidjson\internal\stack.h" /> - <ClInclude Include="include\rapidjson\internal\strfunc.h" /> - <ClInclude Include="include\rapidjson\internal\strtod.h" /> - <ClInclude Include="include\rapidjson\internal\swap.h" /> - <ClInclude Include="include\rapidjson\istreamwrapper.h" /> - <ClInclude Include="include\rapidjson\memorybuffer.h" /> - <ClInclude Include="include\rapidjson\memorystream.h" /> - <ClInclude Include="include\rapidjson\msinttypes\inttypes.h" /> - <ClInclude Include="include\rapidjson\msinttypes\stdint.h" /> - <ClInclude Include="include\rapidjson\ostreamwrapper.h" /> - <ClInclude Include="include\rapidjson\pointer.h" /> - <ClInclude Include="include\rapidjson\prettywriter.h" /> - <ClInclude Include="include\rapidjson\rapidjson.h" /> - <ClInclude Include="include\rapidjson\reader.h" /> - <ClInclude Include="include\rapidjson\schema.h" /> - <ClInclude Include="include\rapidjson\stream.h" /> - <ClInclude Include="include\rapidjson\stringbuffer.h" /> - <ClInclude Include="include\rapidjson\writer.h" /> - <ClInclude Include="include\spdlog\async.h" /> - <ClInclude Include="include\spdlog\async_logger-inl.h" /> - <ClInclude Include="include\spdlog\async_logger.h" /> - <ClInclude Include="include\spdlog\cfg\argv.h" /> - <ClInclude Include="include\spdlog\cfg\env.h" /> - <ClInclude Include="include\spdlog\cfg\helpers-inl.h" /> - <ClInclude Include="include\spdlog\cfg\helpers.h" /> - <ClInclude Include="include\spdlog\common-inl.h" /> - <ClInclude Include="include\spdlog\common.h" /> - <ClInclude Include="include\spdlog\details\backtracer-inl.h" /> - <ClInclude Include="include\spdlog\details\backtracer.h" /> - <ClInclude Include="include\spdlog\details\circular_q.h" /> - <ClInclude Include="include\spdlog\details\console_globals.h" /> - <ClInclude Include="include\spdlog\details\file_helper-inl.h" /> - <ClInclude Include="include\spdlog\details\file_helper.h" /> - <ClInclude Include="include\spdlog\details\fmt_helper.h" /> - <ClInclude Include="include\spdlog\details\log_msg-inl.h" /> - <ClInclude Include="include\spdlog\details\log_msg.h" /> - <ClInclude Include="include\spdlog\details\log_msg_buffer-inl.h" /> - <ClInclude Include="include\spdlog\details\log_msg_buffer.h" /> - <ClInclude Include="include\spdlog\details\mpmc_blocking_q.h" /> - <ClInclude Include="include\spdlog\details\null_mutex.h" /> - <ClInclude Include="include\spdlog\details\os-inl.h" /> - <ClInclude Include="include\spdlog\details\os.h" /> - <ClInclude Include="include\spdlog\details\periodic_worker-inl.h" /> - <ClInclude Include="include\spdlog\details\periodic_worker.h" /> - <ClInclude Include="include\spdlog\details\registry-inl.h" /> - <ClInclude Include="include\spdlog\details\registry.h" /> - <ClInclude Include="include\spdlog\details\synchronous_factory.h" /> - <ClInclude Include="include\spdlog\details\tcp_client-windows.h" /> - <ClInclude Include="include\spdlog\details\tcp_client.h" /> - <ClInclude Include="include\spdlog\details\thread_pool-inl.h" /> - <ClInclude Include="include\spdlog\details\thread_pool.h" /> - <ClInclude Include="include\spdlog\details\windows_include.h" /> - <ClInclude Include="include\spdlog\fmt\bin_to_hex.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\chrono.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\color.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\compile.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\core.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\format-inl.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\format.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\locale.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\os.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\ostream.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\posix.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\printf.h" /> - <ClInclude Include="include\spdlog\fmt\bundled\ranges.h" /> - <ClInclude Include="include\spdlog\fmt\chrono.h" /> - <ClInclude Include="include\spdlog\fmt\fmt.h" /> - <ClInclude Include="include\spdlog\fmt\ostr.h" /> - <ClInclude Include="include\spdlog\formatter.h" /> - <ClInclude Include="include\spdlog\fwd.h" /> - <ClInclude Include="include\spdlog\logger-inl.h" /> - <ClInclude Include="include\spdlog\logger.h" /> - <ClInclude Include="include\spdlog\pattern_formatter-inl.h" /> - <ClInclude Include="include\spdlog\pattern_formatter.h" /> - <ClInclude Include="include\spdlog\sinks\android_sink.h" /> - <ClInclude Include="include\spdlog\sinks\ansicolor_sink-inl.h" /> - <ClInclude Include="include\spdlog\sinks\ansicolor_sink.h" /> - <ClInclude Include="include\spdlog\sinks\base_sink-inl.h" /> - <ClInclude Include="include\spdlog\sinks\base_sink.h" /> - <ClInclude Include="include\spdlog\sinks\basic_file_sink-inl.h" /> - <ClInclude Include="include\spdlog\sinks\basic_file_sink.h" /> - <ClInclude Include="include\spdlog\sinks\daily_file_sink.h" /> - <ClInclude Include="include\spdlog\sinks\dist_sink.h" /> - <ClInclude Include="include\spdlog\sinks\dup_filter_sink.h" /> - <ClInclude Include="include\spdlog\sinks\hourly_file_sink.h" /> - <ClInclude Include="include\spdlog\sinks\msvc_sink.h" /> - <ClInclude Include="include\spdlog\sinks\null_sink.h" /> - <ClInclude Include="include\spdlog\sinks\ostream_sink.h" /> - <ClInclude Include="include\spdlog\sinks\ringbuffer_sink.h" /> - <ClInclude Include="include\spdlog\sinks\rotating_file_sink-inl.h" /> - <ClInclude Include="include\spdlog\sinks\rotating_file_sink.h" /> - <ClInclude Include="include\spdlog\sinks\sink-inl.h" /> - <ClInclude Include="include\spdlog\sinks\sink.h" /> - <ClInclude Include="include\spdlog\sinks\stdout_color_sinks-inl.h" /> - <ClInclude Include="include\spdlog\sinks\stdout_color_sinks.h" /> - <ClInclude Include="include\spdlog\sinks\stdout_sinks-inl.h" /> - <ClInclude Include="include\spdlog\sinks\stdout_sinks.h" /> - <ClInclude Include="include\spdlog\sinks\syslog_sink.h" /> - <ClInclude Include="include\spdlog\sinks\systemd_sink.h" /> - <ClInclude Include="include\spdlog\sinks\tcp_sink.h" /> - <ClInclude Include="include\spdlog\sinks\wincolor_sink-inl.h" /> - <ClInclude Include="include\spdlog\sinks\wincolor_sink.h" /> - <ClInclude Include="include\spdlog\sinks\win_eventlog_sink.h" /> - <ClInclude Include="include\spdlog\spdlog-inl.h" /> - <ClInclude Include="include\spdlog\spdlog.h" /> - <ClInclude Include="include\spdlog\stopwatch.h" /> - <ClInclude Include="include\spdlog\tweakme.h" /> - <ClInclude Include="include\spdlog\version.h" /> - <ClInclude Include="keyvalues.h" /> - <ClInclude Include="languagehooks.h" /> - <ClInclude Include="latencyflex.h" /> - <ClInclude Include="logging.h" /> - <ClInclude Include="main.h" /> - <ClInclude Include="masterserver.h" /> - <ClInclude Include="maxplayers.h" /> - <ClInclude Include="memalloc.h" /> - <ClInclude Include="miscclientfixes.h" /> - <ClInclude Include="misccommands.h" /> - <ClInclude Include="miscserverfixes.h" /> - <ClInclude Include="modlocalisation.h" /> - <ClInclude Include="modmanager.h" /> - <ClInclude Include="pch.h" /> - <ClInclude Include="pdef.h" /> - <ClInclude Include="playlist.h" /> - <ClInclude Include="miscserverscript.h" /> - <ClInclude Include="rpakfilesystem.h" /> - <ClInclude Include="scriptbrowserhooks.h" /> - <ClInclude Include="scriptmainmenupromos.h" /> - <ClInclude Include="scriptmodmenu.h" /> - <ClInclude Include="scriptserverbrowser.h" /> - <ClInclude Include="scriptsrson.h" /> - <ClInclude Include="serverauthentication.h" /> - <ClInclude Include="scriptservertoclientstringcommand.h" /> - <ClInclude Include="sigscanning.h" /> - <ClInclude Include="sourceconsole.h" /> - <ClInclude Include="sourceinterface.h" /> - <ClInclude Include="squirrel.h" /> - <ClInclude Include="state.h" /> - <ClInclude Include="ExploitFixes.h" /> - <ClInclude Include="ExploitFixes_UTF8Parser.h" /> - <ClInclude Include="NSMem.h" /> - <ClInclude Include="version.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="audio.cpp" /> - <ClCompile Include="bansystem.cpp" /> - <ClCompile Include="bits.cpp" /> - <ClCompile Include="buildainfile.cpp" /> - <ClCompile Include="chatcommand.cpp" /> - <ClCompile Include="clientauthhooks.cpp" /> - <ClCompile Include="clientchathooks.cpp" /> - <ClCompile Include="clientruihooks.cpp" /> - <ClCompile Include="clientvideooverrides.cpp" /> - <ClCompile Include="concommand.cpp" /> - <ClCompile Include="configurables.cpp" /> - <ClCompile Include="context.cpp" /> - <ClCompile Include="convar.cpp" /> - <ClCompile Include="cvar.cpp" /> - <ClCompile Include="debugoverlay.cpp" /> - <ClCompile Include="dedicated.cpp" /> - <ClCompile Include="dedicatedmaterialsystem.cpp" /> - <ClCompile Include="dllmain.cpp" /> - <ClCompile Include="emit_blocker.cpp" /> - <ClCompile Include="filesystem.cpp" /> - <ClCompile Include="gameutils.cpp" /> - <ClCompile Include="hooks.cpp" /> - <ClCompile Include="hookutils.cpp" /> - <ClCompile Include="keyvalues.cpp" /> - <ClCompile Include="latencyflex.cpp" /> - <ClCompile Include="localchatwriter.cpp" /> - <ClCompile Include="maxplayers.cpp" /> - <ClCompile Include="languagehooks.cpp" /> - <ClCompile Include="memalloc.cpp" /> - <ClCompile Include="miscclientfixes.cpp" /> - <ClCompile Include="misccommands.cpp" /> - <ClCompile Include="miscserverfixes.cpp" /> - <ClCompile Include="modlocalisation.cpp" /> - <ClCompile Include="logging.cpp" /> - <ClCompile Include="masterserver.cpp" /> - <ClCompile Include="modmanager.cpp" /> - <ClCompile Include="pch.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="pdef.cpp" /> - <ClCompile Include="playlist.cpp" /> - <ClCompile Include="plugins.cpp" /> - <ClCompile Include="rpakfilesystem.cpp" /> - <ClCompile Include="scriptbrowserhooks.cpp" /> - <ClCompile Include="scriptmainmenupromos.cpp" /> - <ClCompile Include="scriptmodmenu.cpp" /> - <ClCompile Include="scriptserverbrowser.cpp" /> - <ClCompile Include="scriptsrson.cpp" /> - <ClCompile Include="serverauthentication.cpp" /> - <ClCompile Include="miscserverscript.cpp" /> - <ClCompile Include="serverchathooks.cpp" /> - <ClCompile Include="scriptservertoclientstringcommand.cpp" /> - <ClCompile Include="sigscanning.cpp" /> - <ClCompile Include="sourceconsole.cpp" /> - <ClCompile Include="sourceinterface.cpp" /> - <ClCompile Include="squirrel.cpp" /> - <ClCompile Include="ExploitFixes.cpp" /> - <ClCompile Include="version.cpp" /> - </ItemGroup> - <ItemGroup> - <None Include="include\crypto\bn_conf.h.in" /> - <None Include="include\crypto\dso_conf.h.in" /> - <None Include="include\openssl\asn1.h.in" /> - <None Include="include\openssl\asn1t.h.in" /> - <None Include="include\openssl\bio.h.in" /> - <None Include="include\openssl\cmp.h.in" /> - <None Include="include\openssl\cms.h.in" /> - <None Include="include\openssl\conf.h.in" /> - <None Include="include\openssl\configuration.h.in" /> - <None Include="include\openssl\crmf.h.in" /> - <None Include="include\openssl\crypto.h.in" /> - <None Include="include\openssl\ct.h.in" /> - <None Include="include\openssl\err.h.in" /> - <None Include="include\openssl\ess.h.in" /> - <None Include="include\openssl\fipskey.h.in" /> - <None Include="include\openssl\lhash.h.in" /> - <None Include="include\openssl\ocsp.h.in" /> - <None Include="include\openssl\opensslv.h.in" /> - <None Include="include\openssl\pkcs12.h.in" /> - <None Include="include\openssl\pkcs7.h.in" /> - <None Include="include\openssl\safestack.h.in" /> - <None Include="include\openssl\srp.h.in" /> - <None Include="include\openssl\ssl.h.in" /> - <None Include="include\openssl\ui.h.in" /> - <None Include="include\openssl\x509.h.in" /> - <None Include="include\openssl\x509v3.h.in" /> - <None Include="include\openssl\x509_vfy.h.in" /> - <None Include="include\spdlog\fmt\bundled\LICENSE.rst" /> - </ItemGroup> - <ItemGroup> - <MASM Include="audio_asm.asm" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectGuid>{cfad2623-064f-453c-8196-79ee10292e32}</ProjectGuid>
+ <RootNamespace>NorthstarDedicatedTest</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <ProjectName>NorthstarDLL</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <TargetName>Northstar</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <TargetName>Northstar</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;NORTHSTARDEDICATEDTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <LanguageStandard>stdcpp20</LanguageStandard>
+ <AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableUAC>false</EnableUAC>
+ <AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcurl\lib\libcurl_a.lib;dbghelp.lib;Wldap32.lib;Normaliz.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ForceSymbolReferences>
+ </ForceSymbolReferences>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ <Command>copy /Y "$(TargetPath)" "$(SolutionDir)..\..\"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;NORTHSTARDEDICATEDTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <LanguageStandard>stdcpp20</LanguageStandard>
+ <AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableUAC>false</EnableUAC>
+ <AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcurl\lib\libcurl_a.lib;dbghelp.lib;Wldap32.lib;Normaliz.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ForceSymbolReferences>
+ </ForceSymbolReferences>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ <Command>copy /Y "$(TargetPath)" "$(SolutionDir)..\..\"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="audio.h" />
+ <ClInclude Include="bansystem.h" />
+ <ClInclude Include="bitbuf.h" />
+ <ClInclude Include="bits.h" />
+ <ClInclude Include="crashhandler.h" />
+ <ClInclude Include="squirreldatatypes.h" />
+ <ClInclude Include="limits.h" />
+ <ClInclude Include="maxplayers.h" />
+ <ClInclude Include="memory.h" />
+ <ClInclude Include="printcommand.h" />
+ <ClInclude Include="hoststate.h" />
+ <ClInclude Include="localchatwriter.h" />
+ <ClInclude Include="printmaps.h" />
+ <ClInclude Include="ns_version.h" />
+ <ClInclude Include="plugins.h" />
+ <ClInclude Include="plugin_abi.h" />
+ <ClInclude Include="r2client.h" />
+ <ClInclude Include="r2engine.h" />
+ <ClInclude Include="r2server.h" />
+ <ClInclude Include="serverchathooks.h" />
+ <ClInclude Include="color.h" />
+ <ClInclude Include="concommand.h" />
+ <ClInclude Include="nsprefix.h" />
+ <ClInclude Include="convar.h" />
+ <ClInclude Include="cvar.h" />
+ <ClInclude Include="dedicated.h" />
+ <ClInclude Include="filesystem.h" />
+ <ClInclude Include="hooks.h" />
+ <ClInclude Include="include\crypto\aes_platform.h" />
+ <ClInclude Include="include\crypto\aria.h" />
+ <ClInclude Include="include\crypto\asn1.h" />
+ <ClInclude Include="include\crypto\asn1err.h" />
+ <ClInclude Include="include\crypto\asn1_dsa.h" />
+ <ClInclude Include="include\crypto\async.h" />
+ <ClInclude Include="include\crypto\asyncerr.h" />
+ <ClInclude Include="include\crypto\bioerr.h" />
+ <ClInclude Include="include\crypto\bn.h" />
+ <ClInclude Include="include\crypto\bnerr.h" />
+ <ClInclude Include="include\crypto\bn_conf.h" />
+ <ClInclude Include="include\crypto\bn_dh.h" />
+ <ClInclude Include="include\crypto\bn_srp.h" />
+ <ClInclude Include="include\crypto\buffererr.h" />
+ <ClInclude Include="include\crypto\chacha.h" />
+ <ClInclude Include="include\crypto\cmll_platform.h" />
+ <ClInclude Include="include\crypto\cmperr.h" />
+ <ClInclude Include="include\crypto\cmserr.h" />
+ <ClInclude Include="include\crypto\comperr.h" />
+ <ClInclude Include="include\crypto\conferr.h" />
+ <ClInclude Include="include\crypto\crmferr.h" />
+ <ClInclude Include="include\crypto\cryptlib.h" />
+ <ClInclude Include="include\crypto\cryptoerr.h" />
+ <ClInclude Include="include\crypto\cterr.h" />
+ <ClInclude Include="include\crypto\ctype.h" />
+ <ClInclude Include="include\crypto\decoder.h" />
+ <ClInclude Include="include\crypto\decodererr.h" />
+ <ClInclude Include="include\crypto\des_platform.h" />
+ <ClInclude Include="include\crypto\dh.h" />
+ <ClInclude Include="include\crypto\dherr.h" />
+ <ClInclude Include="include\crypto\dsa.h" />
+ <ClInclude Include="include\crypto\dsaerr.h" />
+ <ClInclude Include="include\crypto\dso_conf.h" />
+ <ClInclude Include="include\crypto\ec.h" />
+ <ClInclude Include="include\crypto\ecerr.h" />
+ <ClInclude Include="include\crypto\ecx.h" />
+ <ClInclude Include="include\crypto\encoder.h" />
+ <ClInclude Include="include\crypto\encodererr.h" />
+ <ClInclude Include="include\crypto\engine.h" />
+ <ClInclude Include="include\crypto\engineerr.h" />
+ <ClInclude Include="include\crypto\err.h" />
+ <ClInclude Include="include\crypto\ess.h" />
+ <ClInclude Include="include\crypto\esserr.h" />
+ <ClInclude Include="include\crypto\evp.h" />
+ <ClInclude Include="include\crypto\evperr.h" />
+ <ClInclude Include="include\crypto\httperr.h" />
+ <ClInclude Include="include\crypto\lhash.h" />
+ <ClInclude Include="include\crypto\md32_common.h" />
+ <ClInclude Include="include\crypto\modes.h" />
+ <ClInclude Include="include\crypto\objects.h" />
+ <ClInclude Include="include\crypto\objectserr.h" />
+ <ClInclude Include="include\crypto\ocsperr.h" />
+ <ClInclude Include="include\crypto\pem.h" />
+ <ClInclude Include="include\crypto\pemerr.h" />
+ <ClInclude Include="include\crypto\pkcs12err.h" />
+ <ClInclude Include="include\crypto\pkcs7.h" />
+ <ClInclude Include="include\crypto\pkcs7err.h" />
+ <ClInclude Include="include\crypto\poly1305.h" />
+ <ClInclude Include="include\crypto\ppc_arch.h" />
+ <ClInclude Include="include\crypto\punycode.h" />
+ <ClInclude Include="include\crypto\rand.h" />
+ <ClInclude Include="include\crypto\randerr.h" />
+ <ClInclude Include="include\crypto\rand_pool.h" />
+ <ClInclude Include="include\crypto\rsa.h" />
+ <ClInclude Include="include\crypto\rsaerr.h" />
+ <ClInclude Include="include\crypto\security_bits.h" />
+ <ClInclude Include="include\crypto\sha.h" />
+ <ClInclude Include="include\crypto\siphash.h" />
+ <ClInclude Include="include\crypto\siv.h" />
+ <ClInclude Include="include\crypto\sm2.h" />
+ <ClInclude Include="include\crypto\sm2err.h" />
+ <ClInclude Include="include\crypto\sm4.h" />
+ <ClInclude Include="include\crypto\sparc_arch.h" />
+ <ClInclude Include="include\crypto\sparse_array.h" />
+ <ClInclude Include="include\crypto\store.h" />
+ <ClInclude Include="include\crypto\storeerr.h" />
+ <ClInclude Include="include\crypto\tserr.h" />
+ <ClInclude Include="include\crypto\types.h" />
+ <ClInclude Include="include\crypto\uierr.h" />
+ <ClInclude Include="include\crypto\x509.h" />
+ <ClInclude Include="include\crypto\x509err.h" />
+ <ClInclude Include="include\crypto\x509v3err.h" />
+ <ClInclude Include="include\crypto\__DECC_INCLUDE_EPILOGUE.H" />
+ <ClInclude Include="include\crypto\__DECC_INCLUDE_PROLOGUE.H" />
+ <ClInclude Include="include\httplib.h" />
+ <ClInclude Include="include\internal\asn1.h" />
+ <ClInclude Include="include\internal\bio.h" />
+ <ClInclude Include="include\internal\comp.h" />
+ <ClInclude Include="include\internal\conf.h" />
+ <ClInclude Include="include\internal\constant_time.h" />
+ <ClInclude Include="include\internal\core.h" />
+ <ClInclude Include="include\internal\cryptlib.h" />
+ <ClInclude Include="include\internal\dane.h" />
+ <ClInclude Include="include\internal\deprecated.h" />
+ <ClInclude Include="include\internal\der.h" />
+ <ClInclude Include="include\internal\dso.h" />
+ <ClInclude Include="include\internal\dsoerr.h" />
+ <ClInclude Include="include\internal\endian.h" />
+ <ClInclude Include="include\internal\err.h" />
+ <ClInclude Include="include\internal\ffc.h" />
+ <ClInclude Include="include\internal\ktls.h" />
+ <ClInclude Include="include\internal\namemap.h" />
+ <ClInclude Include="include\internal\nelem.h" />
+ <ClInclude Include="include\internal\numbers.h" />
+ <ClInclude Include="include\internal\o_dir.h" />
+ <ClInclude Include="include\internal\packet.h" />
+ <ClInclude Include="include\internal\param_build_set.h" />
+ <ClInclude Include="include\internal\passphrase.h" />
+ <ClInclude Include="include\internal\property.h" />
+ <ClInclude Include="include\internal\propertyerr.h" />
+ <ClInclude Include="include\internal\provider.h" />
+ <ClInclude Include="include\internal\refcount.h" />
+ <ClInclude Include="include\internal\sha3.h" />
+ <ClInclude Include="include\internal\sizes.h" />
+ <ClInclude Include="include\internal\sm3.h" />
+ <ClInclude Include="include\internal\sockets.h" />
+ <ClInclude Include="include\internal\sslconf.h" />
+ <ClInclude Include="include\internal\symhacks.h" />
+ <ClInclude Include="include\internal\thread_once.h" />
+ <ClInclude Include="include\internal\tlsgroups.h" />
+ <ClInclude Include="include\internal\tsan_assist.h" />
+ <ClInclude Include="include\internal\unicode.h" />
+ <ClInclude Include="include\internal\__DECC_INCLUDE_EPILOGUE.H" />
+ <ClInclude Include="include\internal\__DECC_INCLUDE_PROLOGUE.H" />
+ <ClInclude Include="include\libcurl\include\curl\curl.h" />
+ <ClInclude Include="include\libcurl\include\curl\curlver.h" />
+ <ClInclude Include="include\libcurl\include\curl\easy.h" />
+ <ClInclude Include="include\libcurl\include\curl\mprintf.h" />
+ <ClInclude Include="include\libcurl\include\curl\multi.h" />
+ <ClInclude Include="include\libcurl\include\curl\options.h" />
+ <ClInclude Include="include\libcurl\include\curl\stdcheaders.h" />
+ <ClInclude Include="include\libcurl\include\curl\system.h" />
+ <ClInclude Include="include\libcurl\include\curl\typecheck-gcc.h" />
+ <ClInclude Include="include\libcurl\include\curl\urlapi.h" />
+ <ClInclude Include="include\MinHook.h" />
+ <ClInclude Include="include\openssl\aes.h" />
+ <ClInclude Include="include\openssl\asn1.h" />
+ <ClInclude Include="include\openssl\asn1err.h" />
+ <ClInclude Include="include\openssl\asn1t.h" />
+ <ClInclude Include="include\openssl\asn1_mac.h" />
+ <ClInclude Include="include\openssl\async.h" />
+ <ClInclude Include="include\openssl\asyncerr.h" />
+ <ClInclude Include="include\openssl\bio.h" />
+ <ClInclude Include="include\openssl\bioerr.h" />
+ <ClInclude Include="include\openssl\blowfish.h" />
+ <ClInclude Include="include\openssl\bn.h" />
+ <ClInclude Include="include\openssl\bnerr.h" />
+ <ClInclude Include="include\openssl\buffer.h" />
+ <ClInclude Include="include\openssl\buffererr.h" />
+ <ClInclude Include="include\openssl\camellia.h" />
+ <ClInclude Include="include\openssl\cast.h" />
+ <ClInclude Include="include\openssl\cmac.h" />
+ <ClInclude Include="include\openssl\cmp.h" />
+ <ClInclude Include="include\openssl\cmperr.h" />
+ <ClInclude Include="include\openssl\cmp_util.h" />
+ <ClInclude Include="include\openssl\cms.h" />
+ <ClInclude Include="include\openssl\cmserr.h" />
+ <ClInclude Include="include\openssl\comp.h" />
+ <ClInclude Include="include\openssl\comperr.h" />
+ <ClInclude Include="include\openssl\conf.h" />
+ <ClInclude Include="include\openssl\conferr.h" />
+ <ClInclude Include="include\openssl\configuration.h" />
+ <ClInclude Include="include\openssl\conftypes.h" />
+ <ClInclude Include="include\openssl\conf_api.h" />
+ <ClInclude Include="include\openssl\core.h" />
+ <ClInclude Include="include\openssl\core_dispatch.h" />
+ <ClInclude Include="include\openssl\core_names.h" />
+ <ClInclude Include="include\openssl\core_object.h" />
+ <ClInclude Include="include\openssl\crmf.h" />
+ <ClInclude Include="include\openssl\crmferr.h" />
+ <ClInclude Include="include\openssl\crypto.h" />
+ <ClInclude Include="include\openssl\cryptoerr.h" />
+ <ClInclude Include="include\openssl\cryptoerr_legacy.h" />
+ <ClInclude Include="include\openssl\ct.h" />
+ <ClInclude Include="include\openssl\cterr.h" />
+ <ClInclude Include="include\openssl\decoder.h" />
+ <ClInclude Include="include\openssl\decodererr.h" />
+ <ClInclude Include="include\openssl\des.h" />
+ <ClInclude Include="include\openssl\dh.h" />
+ <ClInclude Include="include\openssl\dherr.h" />
+ <ClInclude Include="include\openssl\dsa.h" />
+ <ClInclude Include="include\openssl\dsaerr.h" />
+ <ClInclude Include="include\openssl\dtls1.h" />
+ <ClInclude Include="include\openssl\ebcdic.h" />
+ <ClInclude Include="include\openssl\ec.h" />
+ <ClInclude Include="include\openssl\ecdh.h" />
+ <ClInclude Include="include\openssl\ecdsa.h" />
+ <ClInclude Include="include\openssl\ecerr.h" />
+ <ClInclude Include="include\openssl\encoder.h" />
+ <ClInclude Include="include\openssl\encodererr.h" />
+ <ClInclude Include="include\openssl\engine.h" />
+ <ClInclude Include="include\openssl\engineerr.h" />
+ <ClInclude Include="include\openssl\err.h" />
+ <ClInclude Include="include\openssl\ess.h" />
+ <ClInclude Include="include\openssl\esserr.h" />
+ <ClInclude Include="include\openssl\evp.h" />
+ <ClInclude Include="include\openssl\evperr.h" />
+ <ClInclude Include="include\openssl\e_os2.h" />
+ <ClInclude Include="include\openssl\fipskey.h" />
+ <ClInclude Include="include\openssl\fips_names.h" />
+ <ClInclude Include="include\openssl\hmac.h" />
+ <ClInclude Include="include\openssl\http.h" />
+ <ClInclude Include="include\openssl\httperr.h" />
+ <ClInclude Include="include\openssl\idea.h" />
+ <ClInclude Include="include\openssl\kdf.h" />
+ <ClInclude Include="include\openssl\kdferr.h" />
+ <ClInclude Include="include\openssl\lhash.h" />
+ <ClInclude Include="include\openssl\macros.h" />
+ <ClInclude Include="include\openssl\md2.h" />
+ <ClInclude Include="include\openssl\md4.h" />
+ <ClInclude Include="include\openssl\md5.h" />
+ <ClInclude Include="include\openssl\mdc2.h" />
+ <ClInclude Include="include\openssl\modes.h" />
+ <ClInclude Include="include\openssl\objects.h" />
+ <ClInclude Include="include\openssl\objectserr.h" />
+ <ClInclude Include="include\openssl\obj_mac.h" />
+ <ClInclude Include="include\openssl\ocsp.h" />
+ <ClInclude Include="include\openssl\ocsperr.h" />
+ <ClInclude Include="include\openssl\opensslconf.h" />
+ <ClInclude Include="include\openssl\opensslv.h" />
+ <ClInclude Include="include\openssl\ossl_typ.h" />
+ <ClInclude Include="include\openssl\params.h" />
+ <ClInclude Include="include\openssl\param_build.h" />
+ <ClInclude Include="include\openssl\pem.h" />
+ <ClInclude Include="include\openssl\pem2.h" />
+ <ClInclude Include="include\openssl\pemerr.h" />
+ <ClInclude Include="include\openssl\pkcs12.h" />
+ <ClInclude Include="include\openssl\pkcs12err.h" />
+ <ClInclude Include="include\openssl\pkcs7.h" />
+ <ClInclude Include="include\openssl\pkcs7err.h" />
+ <ClInclude Include="include\openssl\proverr.h" />
+ <ClInclude Include="include\openssl\provider.h" />
+ <ClInclude Include="include\openssl\prov_ssl.h" />
+ <ClInclude Include="include\openssl\rand.h" />
+ <ClInclude Include="include\openssl\randerr.h" />
+ <ClInclude Include="include\openssl\rc2.h" />
+ <ClInclude Include="include\openssl\rc4.h" />
+ <ClInclude Include="include\openssl\rc5.h" />
+ <ClInclude Include="include\openssl\ripemd.h" />
+ <ClInclude Include="include\openssl\rsa.h" />
+ <ClInclude Include="include\openssl\rsaerr.h" />
+ <ClInclude Include="include\openssl\safestack.h" />
+ <ClInclude Include="include\openssl\seed.h" />
+ <ClInclude Include="include\openssl\self_test.h" />
+ <ClInclude Include="include\openssl\sha.h" />
+ <ClInclude Include="include\openssl\srp.h" />
+ <ClInclude Include="include\openssl\srtp.h" />
+ <ClInclude Include="include\openssl\ssl.h" />
+ <ClInclude Include="include\openssl\ssl2.h" />
+ <ClInclude Include="include\openssl\ssl3.h" />
+ <ClInclude Include="include\openssl\sslerr.h" />
+ <ClInclude Include="include\openssl\sslerr_legacy.h" />
+ <ClInclude Include="include\openssl\stack.h" />
+ <ClInclude Include="include\openssl\store.h" />
+ <ClInclude Include="include\openssl\storeerr.h" />
+ <ClInclude Include="include\openssl\symhacks.h" />
+ <ClInclude Include="include\openssl\tls1.h" />
+ <ClInclude Include="include\openssl\trace.h" />
+ <ClInclude Include="include\openssl\ts.h" />
+ <ClInclude Include="include\openssl\tserr.h" />
+ <ClInclude Include="include\openssl\txt_db.h" />
+ <ClInclude Include="include\openssl\types.h" />
+ <ClInclude Include="include\openssl\ui.h" />
+ <ClInclude Include="include\openssl\uierr.h" />
+ <ClInclude Include="include\openssl\whrlpool.h" />
+ <ClInclude Include="include\openssl\x509.h" />
+ <ClInclude Include="include\openssl\x509err.h" />
+ <ClInclude Include="include\openssl\x509v3.h" />
+ <ClInclude Include="include\openssl\x509v3err.h" />
+ <ClInclude Include="include\openssl\x509_vfy.h" />
+ <ClInclude Include="include\openssl\__DECC_INCLUDE_EPILOGUE.H" />
+ <ClInclude Include="include\openssl\__DECC_INCLUDE_PROLOGUE.H" />
+ <ClInclude Include="include\rapidjson\allocators.h" />
+ <ClInclude Include="include\rapidjson\document.h" />
+ <ClInclude Include="include\rapidjson\encodedstream.h" />
+ <ClInclude Include="include\rapidjson\encodings.h" />
+ <ClInclude Include="include\rapidjson\error\en.h" />
+ <ClInclude Include="include\rapidjson\error\error.h" />
+ <ClInclude Include="include\rapidjson\filereadstream.h" />
+ <ClInclude Include="include\rapidjson\filewritestream.h" />
+ <ClInclude Include="include\rapidjson\fwd.h" />
+ <ClInclude Include="include\rapidjson\internal\biginteger.h" />
+ <ClInclude Include="include\rapidjson\internal\diyfp.h" />
+ <ClInclude Include="include\rapidjson\internal\dtoa.h" />
+ <ClInclude Include="include\rapidjson\internal\ieee754.h" />
+ <ClInclude Include="include\rapidjson\internal\itoa.h" />
+ <ClInclude Include="include\rapidjson\internal\meta.h" />
+ <ClInclude Include="include\rapidjson\internal\pow10.h" />
+ <ClInclude Include="include\rapidjson\internal\regex.h" />
+ <ClInclude Include="include\rapidjson\internal\stack.h" />
+ <ClInclude Include="include\rapidjson\internal\strfunc.h" />
+ <ClInclude Include="include\rapidjson\internal\strtod.h" />
+ <ClInclude Include="include\rapidjson\internal\swap.h" />
+ <ClInclude Include="include\rapidjson\istreamwrapper.h" />
+ <ClInclude Include="include\rapidjson\memorybuffer.h" />
+ <ClInclude Include="include\rapidjson\memorystream.h" />
+ <ClInclude Include="include\rapidjson\msinttypes\inttypes.h" />
+ <ClInclude Include="include\rapidjson\msinttypes\stdint.h" />
+ <ClInclude Include="include\rapidjson\ostreamwrapper.h" />
+ <ClInclude Include="include\rapidjson\pointer.h" />
+ <ClInclude Include="include\rapidjson\prettywriter.h" />
+ <ClInclude Include="include\rapidjson\rapidjson.h" />
+ <ClInclude Include="include\rapidjson\reader.h" />
+ <ClInclude Include="include\rapidjson\schema.h" />
+ <ClInclude Include="include\rapidjson\stream.h" />
+ <ClInclude Include="include\rapidjson\stringbuffer.h" />
+ <ClInclude Include="include\rapidjson\writer.h" />
+ <ClInclude Include="include\spdlog\async.h" />
+ <ClInclude Include="include\spdlog\async_logger-inl.h" />
+ <ClInclude Include="include\spdlog\async_logger.h" />
+ <ClInclude Include="include\spdlog\cfg\argv.h" />
+ <ClInclude Include="include\spdlog\cfg\env.h" />
+ <ClInclude Include="include\spdlog\cfg\helpers-inl.h" />
+ <ClInclude Include="include\spdlog\cfg\helpers.h" />
+ <ClInclude Include="include\spdlog\common-inl.h" />
+ <ClInclude Include="include\spdlog\common.h" />
+ <ClInclude Include="include\spdlog\details\backtracer-inl.h" />
+ <ClInclude Include="include\spdlog\details\backtracer.h" />
+ <ClInclude Include="include\spdlog\details\circular_q.h" />
+ <ClInclude Include="include\spdlog\details\console_globals.h" />
+ <ClInclude Include="include\spdlog\details\file_helper-inl.h" />
+ <ClInclude Include="include\spdlog\details\file_helper.h" />
+ <ClInclude Include="include\spdlog\details\fmt_helper.h" />
+ <ClInclude Include="include\spdlog\details\log_msg-inl.h" />
+ <ClInclude Include="include\spdlog\details\log_msg.h" />
+ <ClInclude Include="include\spdlog\details\log_msg_buffer-inl.h" />
+ <ClInclude Include="include\spdlog\details\log_msg_buffer.h" />
+ <ClInclude Include="include\spdlog\details\mpmc_blocking_q.h" />
+ <ClInclude Include="include\spdlog\details\null_mutex.h" />
+ <ClInclude Include="include\spdlog\details\os-inl.h" />
+ <ClInclude Include="include\spdlog\details\os.h" />
+ <ClInclude Include="include\spdlog\details\periodic_worker-inl.h" />
+ <ClInclude Include="include\spdlog\details\periodic_worker.h" />
+ <ClInclude Include="include\spdlog\details\registry-inl.h" />
+ <ClInclude Include="include\spdlog\details\registry.h" />
+ <ClInclude Include="include\spdlog\details\synchronous_factory.h" />
+ <ClInclude Include="include\spdlog\details\tcp_client-windows.h" />
+ <ClInclude Include="include\spdlog\details\tcp_client.h" />
+ <ClInclude Include="include\spdlog\details\thread_pool-inl.h" />
+ <ClInclude Include="include\spdlog\details\thread_pool.h" />
+ <ClInclude Include="include\spdlog\details\windows_include.h" />
+ <ClInclude Include="include\spdlog\fmt\bin_to_hex.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\chrono.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\color.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\compile.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\core.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\format-inl.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\format.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\locale.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\os.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\ostream.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\posix.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\printf.h" />
+ <ClInclude Include="include\spdlog\fmt\bundled\ranges.h" />
+ <ClInclude Include="include\spdlog\fmt\chrono.h" />
+ <ClInclude Include="include\spdlog\fmt\fmt.h" />
+ <ClInclude Include="include\spdlog\fmt\ostr.h" />
+ <ClInclude Include="include\spdlog\formatter.h" />
+ <ClInclude Include="include\spdlog\fwd.h" />
+ <ClInclude Include="include\spdlog\logger-inl.h" />
+ <ClInclude Include="include\spdlog\logger.h" />
+ <ClInclude Include="include\spdlog\pattern_formatter-inl.h" />
+ <ClInclude Include="include\spdlog\pattern_formatter.h" />
+ <ClInclude Include="include\spdlog\sinks\android_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\ansicolor_sink-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\ansicolor_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\base_sink-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\base_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\basic_file_sink-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\basic_file_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\daily_file_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\dist_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\dup_filter_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\hourly_file_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\msvc_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\null_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\ostream_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\ringbuffer_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\rotating_file_sink-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\rotating_file_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\sink-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\sink.h" />
+ <ClInclude Include="include\spdlog\sinks\stdout_color_sinks-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\stdout_color_sinks.h" />
+ <ClInclude Include="include\spdlog\sinks\stdout_sinks-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\stdout_sinks.h" />
+ <ClInclude Include="include\spdlog\sinks\syslog_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\systemd_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\tcp_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\wincolor_sink-inl.h" />
+ <ClInclude Include="include\spdlog\sinks\wincolor_sink.h" />
+ <ClInclude Include="include\spdlog\sinks\win_eventlog_sink.h" />
+ <ClInclude Include="include\spdlog\spdlog-inl.h" />
+ <ClInclude Include="include\spdlog\spdlog.h" />
+ <ClInclude Include="include\spdlog\stopwatch.h" />
+ <ClInclude Include="include\spdlog\tweakme.h" />
+ <ClInclude Include="include\spdlog\version.h" />
+ <ClInclude Include="logging.h" />
+ <ClInclude Include="main.h" />
+ <ClInclude Include="masterserver.h" />
+ <ClInclude Include="memalloc.h" />
+ <ClInclude Include="misccommands.h" />
+ <ClInclude Include="modmanager.h" />
+ <ClInclude Include="pch.h" />
+ <ClInclude Include="pdef.h" />
+ <ClInclude Include="playlist.h" />
+ <ClInclude Include="rpakfilesystem.h" />
+ <ClInclude Include="scriptsrson.h" />
+ <ClInclude Include="serverauthentication.h" />
+ <ClInclude Include="serverpresence.h" />
+ <ClInclude Include="sourceconsole.h" />
+ <ClInclude Include="sourceinterface.h" />
+ <ClInclude Include="squirrel.h" />
+ <ClInclude Include="exploitfixes_utf8parser.cpp" />
+ <ClInclude Include="tier0.h" />
+ <ClInclude Include="vector.h" />
+ <ClInclude Include="version.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="audio.cpp" />
+ <ClCompile Include="bansystem.cpp" />
+ <ClCompile Include="bits.cpp" />
+ <ClCompile Include="buildainfile.cpp" />
+ <ClCompile Include="chatcommand.cpp" />
+ <ClCompile Include="clientauthhooks.cpp" />
+ <ClCompile Include="clientchathooks.cpp" />
+ <ClCompile Include="clientruihooks.cpp" />
+ <ClCompile Include="clientvideooverrides.cpp" />
+ <ClCompile Include="concommand.cpp" />
+ <ClCompile Include="exploitfixes_lzss.cpp" />
+ <ClCompile Include="limits.cpp" />
+ <ClCompile Include="memory.cpp" />
+ <ClCompile Include="nsprefix.cpp" />
+ <ClCompile Include="convar.cpp" />
+ <ClCompile Include="crashhandler.cpp" />
+ <ClCompile Include="cvar.cpp" />
+ <ClCompile Include="debugoverlay.cpp" />
+ <ClCompile Include="dedicated.cpp" />
+ <ClCompile Include="dedicatedmaterialsystem.cpp" />
+ <ClCompile Include="demofixes.cpp" />
+ <ClCompile Include="dllmain.cpp" />
+ <ClCompile Include="filesystem.cpp" />
+ <ClCompile Include="hooks.cpp" />
+ <ClCompile Include="host.cpp" />
+ <ClCompile Include="hoststate.cpp" />
+ <ClCompile Include="keyvalues.cpp" />
+ <ClCompile Include="latencyflex.cpp" />
+ <ClCompile Include="localchatwriter.cpp" />
+ <ClCompile Include="printmaps.cpp" />
+ <ClCompile Include="maxplayers.cpp" />
+ <ClCompile Include="languagehooks.cpp" />
+ <ClCompile Include="memalloc.cpp" />
+ <ClCompile Include="misccommands.cpp" />
+ <ClCompile Include="miscserverfixes.cpp" />
+ <ClCompile Include="modlocalisation.cpp" />
+ <ClCompile Include="logging.cpp" />
+ <ClCompile Include="masterserver.cpp" />
+ <ClCompile Include="modmanager.cpp" />
+ <ClCompile Include="pch.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="pdef.cpp" />
+ <ClCompile Include="playlist.cpp" />
+ <ClCompile Include="plugins.cpp" />
+ <ClCompile Include="printcommands.cpp" />
+ <ClCompile Include="r2client.cpp" />
+ <ClCompile Include="r2engine.cpp" />
+ <ClCompile Include="r2server.cpp" />
+ <ClCompile Include="rpakfilesystem.cpp" />
+ <ClCompile Include="runframe.cpp" />
+ <ClCompile Include="scriptbrowserhooks.cpp" />
+ <ClCompile Include="scriptjson.cpp" />
+ <ClCompile Include="scriptdatatables.cpp" />
+ <ClCompile Include="scriptmainmenupromos.cpp" />
+ <ClCompile Include="scriptmodmenu.cpp" />
+ <ClCompile Include="scriptserverbrowser.cpp" />
+ <ClCompile Include="scriptsrson.cpp" />
+ <ClCompile Include="scriptutility.cpp" />
+ <ClCompile Include="serverauthentication.cpp" />
+ <ClCompile Include="miscserverscript.cpp" />
+ <ClCompile Include="serverchathooks.cpp" />
+ <ClCompile Include="scriptservertoclientstringcommand.cpp" />
+ <ClCompile Include="serverpresence.cpp" />
+ <ClCompile Include="sourceconsole.cpp" />
+ <ClCompile Include="sourceinterface.cpp" />
+ <ClCompile Include="squirrel.cpp" />
+ <ClCompile Include="exploitfixes.cpp" />
+ <ClCompile Include="tier0.cpp" />
+ <ClCompile Include="version.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="include\crypto\bn_conf.h.in" />
+ <None Include="include\crypto\dso_conf.h.in" />
+ <None Include="include\openssl\asn1.h.in" />
+ <None Include="include\openssl\asn1t.h.in" />
+ <None Include="include\openssl\bio.h.in" />
+ <None Include="include\openssl\cmp.h.in" />
+ <None Include="include\openssl\cms.h.in" />
+ <None Include="include\openssl\conf.h.in" />
+ <None Include="include\openssl\configuration.h.in" />
+ <None Include="include\openssl\crmf.h.in" />
+ <None Include="include\openssl\crypto.h.in" />
+ <None Include="include\openssl\ct.h.in" />
+ <None Include="include\openssl\err.h.in" />
+ <None Include="include\openssl\ess.h.in" />
+ <None Include="include\openssl\fipskey.h.in" />
+ <None Include="include\openssl\lhash.h.in" />
+ <None Include="include\openssl\ocsp.h.in" />
+ <None Include="include\openssl\opensslv.h.in" />
+ <None Include="include\openssl\pkcs12.h.in" />
+ <None Include="include\openssl\pkcs7.h.in" />
+ <None Include="include\openssl\safestack.h.in" />
+ <None Include="include\openssl\srp.h.in" />
+ <None Include="include\openssl\ssl.h.in" />
+ <None Include="include\openssl\ui.h.in" />
+ <None Include="include\openssl\x509.h.in" />
+ <None Include="include\openssl\x509v3.h.in" />
+ <None Include="include\openssl\x509_vfy.h.in" />
+ <None Include="include\spdlog\fmt\bundled\LICENSE.rst" />
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="audio_asm.asm" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
+ </ImportGroup>
</Project>
\ No newline at end of file diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDLL/NorthstarDLL.vcxproj.filters index 8e429c9f..9b5837d2 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters +++ b/NorthstarDLL/NorthstarDLL.vcxproj.filters @@ -1,1783 +1,1795 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - <Filter Include="Header Files\include"> - <UniqueIdentifier>{d4199e4b-10d2-43ce-af9c-e1fa79e1e64e}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared"> - <UniqueIdentifier>{4d322431-dcaa-4f75-aee0-3b6371cf52a6}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\Hooks"> - <UniqueIdentifier>{94259c8c-5411-48bf-af4f-46ca32b7d0bb}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared"> - <UniqueIdentifier>{4f525372-34a8-40b3-8a95-81d77cdfcf7f}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Dedicated"> - <UniqueIdentifier>{947835db-67d6-42c0-870d-62743f85231f}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Dedicated"> - <UniqueIdentifier>{8b8ed12a-9269-4dc3-b932-0daefdf6a388}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Client"> - <UniqueIdentifier>{b6f79919-9735-476d-8798-067a75cbeca0}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Client"> - <UniqueIdentifier>{ca657be5-c2d8-4322-a689-1154aaafe57b}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Convar"> - <UniqueIdentifier>{a18afb37-5fdd-4340-a6b4-a6541593e398}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\Convar"> - <UniqueIdentifier>{9751b551-5886-45d4-a039-cbd10445263d}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\spdlog"> - <UniqueIdentifier>{8596cc1c-0492-4467-91e3-1f03b7e19f77}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\spdlog\cfg"> - <UniqueIdentifier>{11eaa578-6336-456e-9c7c-8bd202470945}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\spdlog\fmt"> - <UniqueIdentifier>{7ecd75d2-7eee-41c4-87b6-3b7c2213f34e}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\spdlog\fmt\bundled"> - <UniqueIdentifier>{8afc70f1-639c-49ef-9348-ef6dcece114e}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\spdlog\sinks"> - <UniqueIdentifier>{398efed5-0a92-4d32-b5ba-b4a725b2a70a}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\spdlog\details"> - <UniqueIdentifier>{74567974-c66b-45ef-ab28-97b7154ca224}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Mods"> - <UniqueIdentifier>{3e892d07-2239-44da-9cf3-c288a34cf9a2}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\Mods"> - <UniqueIdentifier>{6bbce8a5-38b4-4763-a7cb-4e98012ec245}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\rapidjson"> - <UniqueIdentifier>{4ca5392e-7d3d-4066-833f-f534cd5787c3}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\rapidjson\error"> - <UniqueIdentifier>{94b15898-ef33-41c7-995a-31791fccb7e2}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\rapidjson\internal"> - <UniqueIdentifier>{6495657f-ea55-4552-8aa7-b54eb8e86a99}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\rapidjson\msinttypes"> - <UniqueIdentifier>{85aacdee-0f92-4ec4-b20c-0739c1175055}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Hooks"> - <UniqueIdentifier>{4db0d1e9-9035-457f-87f1-5dc3f13b6b9e}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\Mods\Compiled"> - <UniqueIdentifier>{d1f93d1e-0ecb-44fe-a277-d3e75aec2570}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Mods\Compiled"> - <UniqueIdentifier>{14fc0931-acad-46ec-a55e-94f4469d4235}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Server"> - <UniqueIdentifier>{3d41d3fc-8a3b-4358-b3e8-4f06dc96abfe}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Server\Authentication"> - <UniqueIdentifier>{d69760a9-d5ec-4f3e-8f43-f74041654d44}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Server"> - <UniqueIdentifier>{365e5c1f-4b2f-4d8b-a1d8-cdef401ca689}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Server\Authentication"> - <UniqueIdentifier>{24fd0855-9288-4129-93ba-c6cafdc98d1b}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Game Functions"> - <UniqueIdentifier>{2cbddb28-0b17-4881-847d-8773da52b268}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\Game Functions"> - <UniqueIdentifier>{0c93d909-e0d6-4c35-a8a4-a13f681a1012}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\openssl"> - <UniqueIdentifier>{4cb0dd89-5f16-4549-a864-34ca3075352a}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\openssl\openssl"> - <UniqueIdentifier>{914d8b8f-6b19-4f23-b746-f40062d72906}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\openssl\internal"> - <UniqueIdentifier>{09516029-fac7-4235-ad61-402977534a0b}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\openssl\crypto"> - <UniqueIdentifier>{8cc1ae44-9dbf-4719-91a2-82e00b8d78e2}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\include\libcurl"> - <UniqueIdentifier>{ea1e17a6-40b7-4e1b-8edb-e9ae704ce604}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Math"> - <UniqueIdentifier>{59b0f68f-daa7-4641-b6fa-8464b56da2bb}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\Math"> - <UniqueIdentifier>{44a83740-9d70-480d-9a7a-43b81f8eab9e}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Exploit Fixes"> - <UniqueIdentifier>{4a8a695a-a103-4b1f-b314-0ec19a253119}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Shared\Exploit Fixes\UTF8Parser"> - <UniqueIdentifier>{b30e08b1-b962-4264-8cbb-a0a31924b93e}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Shared\ExploitFixes"> - <UniqueIdentifier>{7f609cee-d2c0-46a2-b06e-83b9f0511915}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="pch.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="include\MinHook.h"> - <Filter>Header Files\include</Filter> - </ClInclude> - <ClInclude Include="hooks.h"> - <Filter>Header Files\Shared\Hooks</Filter> - </ClInclude> - <ClInclude Include="hookutils.h"> - <Filter>Header Files\Shared\Hooks</Filter> - </ClInclude> - <ClInclude Include="main.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="dedicated.h"> - <Filter>Header Files\Dedicated</Filter> - </ClInclude> - <ClInclude Include="sourceconsole.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="squirrel.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="sigscanning.h"> - <Filter>Header Files\Shared\Hooks</Filter> - </ClInclude> - <ClInclude Include="logging.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="context.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="sourceinterface.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="concommand.h"> - <Filter>Header Files\Shared\Convar</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\async.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\async_logger.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\async_logger-inl.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\common.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\common-inl.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\formatter.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fwd.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\logger.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\logger-inl.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\pattern_formatter.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\pattern_formatter-inl.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\spdlog.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\spdlog-inl.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\stopwatch.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\tweakme.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\version.h"> - <Filter>Header Files\include\spdlog</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\cfg\argv.h"> - <Filter>Header Files\include\spdlog\cfg</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\cfg\env.h"> - <Filter>Header Files\include\spdlog\cfg</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\cfg\helpers.h"> - <Filter>Header Files\include\spdlog\cfg</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\cfg\helpers-inl.h"> - <Filter>Header Files\include\spdlog\cfg</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bin_to_hex.h"> - <Filter>Header Files\include\spdlog\fmt</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\chrono.h"> - <Filter>Header Files\include\spdlog\fmt</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\fmt.h"> - <Filter>Header Files\include\spdlog\fmt</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\ostr.h"> - <Filter>Header Files\include\spdlog\fmt</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\chrono.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\color.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\compile.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\core.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\format.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\format-inl.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\locale.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\os.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\ostream.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\posix.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\printf.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\fmt\bundled\ranges.h"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\android_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\ansicolor_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\ansicolor_sink-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\base_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\base_sink-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\basic_file_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\basic_file_sink-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\daily_file_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\dist_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\dup_filter_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\hourly_file_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\msvc_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\null_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\ostream_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\ringbuffer_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\rotating_file_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\rotating_file_sink-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\sink-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\stdout_color_sinks.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\stdout_color_sinks-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\stdout_sinks.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\stdout_sinks-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\syslog_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\systemd_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\tcp_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\win_eventlog_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\wincolor_sink.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\sinks\wincolor_sink-inl.h"> - <Filter>Header Files\include\spdlog\sinks</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\backtracer.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\backtracer-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\circular_q.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\console_globals.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\file_helper.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\file_helper-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\fmt_helper.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\log_msg.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\log_msg_buffer.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\log_msg_buffer-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\log_msg-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\mpmc_blocking_q.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\null_mutex.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\os.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\os-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\periodic_worker.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\periodic_worker-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\registry.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\registry-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\synchronous_factory.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\tcp_client.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\tcp_client-windows.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\thread_pool.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\thread_pool-inl.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="include\spdlog\details\windows_include.h"> - <Filter>Header Files\include\spdlog\details</Filter> - </ClInclude> - <ClInclude Include="convar.h"> - <Filter>Header Files\Shared\Convar</Filter> - </ClInclude> - <ClInclude Include="modmanager.h"> - <Filter>Header Files\Shared\Mods</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\allocators.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\document.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\encodedstream.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\encodings.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\filereadstream.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\filewritestream.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\fwd.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\istreamwrapper.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\memorybuffer.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\memorystream.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\ostreamwrapper.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\pointer.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\prettywriter.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\rapidjson.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\reader.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\schema.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\stream.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\stringbuffer.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\writer.h"> - <Filter>Header Files\include\rapidjson</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\error\en.h"> - <Filter>Header Files\include\rapidjson\error</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\error\error.h"> - <Filter>Header Files\include\rapidjson\error</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\biginteger.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\diyfp.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\dtoa.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\ieee754.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\itoa.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\meta.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\pow10.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\regex.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\stack.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\strfunc.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\strtod.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\internal\swap.h"> - <Filter>Header Files\include\rapidjson\internal</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\msinttypes\inttypes.h"> - <Filter>Header Files\include\rapidjson\msinttypes</Filter> - </ClInclude> - <ClInclude Include="include\rapidjson\msinttypes\stdint.h"> - <Filter>Header Files\include\rapidjson\msinttypes</Filter> - </ClInclude> - <ClInclude Include="filesystem.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="scriptsrson.h"> - <Filter>Header Files\Shared\Mods\Compiled</Filter> - </ClInclude> - <ClInclude Include="serverauthentication.h"> - <Filter>Header Files\Server\Authentication</Filter> - </ClInclude> - <ClInclude Include="scriptmodmenu.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="scriptserverbrowser.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="keyvalues.h"> - <Filter>Header Files\Shared\Mods\Compiled</Filter> - </ClInclude> - <ClInclude Include="include\httplib.h"> - <Filter>Header Files\include</Filter> - </ClInclude> - <ClInclude Include="masterserver.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="chatcommand.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="modlocalisation.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="playlist.h"> - <Filter>Header Files\Server</Filter> - </ClInclude> - <ClInclude Include="dedicatedmaterialsystem.h"> - <Filter>Header Files\Dedicated</Filter> - </ClInclude> - <ClInclude Include="misccommands.h"> - <Filter>Header Files\Shared\Convar</Filter> - </ClInclude> - <ClInclude Include="miscserverscript.h"> - <Filter>Header Files\Server</Filter> - </ClInclude> - <ClInclude Include="pdef.h"> - <Filter>Header Files\Shared\Mods\Compiled</Filter> - </ClInclude> - <ClInclude Include="clientauthhooks.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="scriptbrowserhooks.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="gameutils.h"> - <Filter>Header Files\Shared\Game Functions</Filter> - </ClInclude> - <ClInclude Include="memalloc.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="scriptmainmenupromos.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="miscclientfixes.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="include\openssl\__DECC_INCLUDE_EPILOGUE.H"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\__DECC_INCLUDE_PROLOGUE.H"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\aes.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\asn1.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\asn1_mac.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\asn1err.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\asn1t.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\async.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\asyncerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\bio.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\bioerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\blowfish.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\bn.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\bnerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\buffer.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\buffererr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\camellia.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cast.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cmac.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cmp.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cmp_util.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cmperr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cms.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cmserr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\comp.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\comperr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\conf.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\conf_api.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\conferr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\configuration.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\conftypes.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\core.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\core_dispatch.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\core_names.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\core_object.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\crmf.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\crmferr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\crypto.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cryptoerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cryptoerr_legacy.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ct.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\cterr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\decoder.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\decodererr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\des.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\dh.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\dherr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\dsa.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\dsaerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\dtls1.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\e_os2.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ebcdic.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ec.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ecdh.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ecdsa.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ecerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\encoder.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\encodererr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\engine.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\engineerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\err.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ess.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\esserr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\evp.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\evperr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\fips_names.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\fipskey.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\hmac.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\http.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\httperr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\idea.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\kdf.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\kdferr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\lhash.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\macros.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\md2.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\md4.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\md5.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\mdc2.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\modes.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\obj_mac.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\objects.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\objectserr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ocsp.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ocsperr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\opensslconf.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\opensslv.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ossl_typ.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\param_build.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\params.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pem.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pem2.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pemerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pkcs7.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pkcs7err.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pkcs12.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\pkcs12err.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\prov_ssl.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\proverr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\provider.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\rand.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\randerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\rc2.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\rc4.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\rc5.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ripemd.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\rsa.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\rsaerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\safestack.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\seed.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\self_test.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\sha.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\srp.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\srtp.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ssl.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ssl2.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ssl3.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\sslerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\sslerr_legacy.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\stack.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\store.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\storeerr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\symhacks.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\tls1.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\trace.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ts.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\tserr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\txt_db.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\types.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\ui.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\uierr.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\whrlpool.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\x509.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\x509_vfy.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\x509err.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\x509v3.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\openssl\x509v3err.h"> - <Filter>Header Files\include\openssl\openssl</Filter> - </ClInclude> - <ClInclude Include="include\crypto\__DECC_INCLUDE_EPILOGUE.H"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\__DECC_INCLUDE_PROLOGUE.H"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\aes_platform.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\aria.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\asn1.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\asn1_dsa.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\asn1err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\async.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\asyncerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\bioerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\bn.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\bn_conf.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\bn_dh.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\bn_srp.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\bnerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\buffererr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\chacha.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\cmll_platform.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\cmperr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\cmserr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\comperr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\conferr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\crmferr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\cryptlib.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\cryptoerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\cterr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ctype.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\decoder.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\decodererr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\des_platform.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\dh.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\dherr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\dsa.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\dsaerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\dso_conf.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ec.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ecerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ecx.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\encoder.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\encodererr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\engine.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\engineerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ess.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\esserr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\evp.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\evperr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\httperr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\lhash.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\md32_common.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\modes.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\objects.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\objectserr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ocsperr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\pem.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\pemerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\pkcs7.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\pkcs7err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\pkcs12err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\poly1305.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\ppc_arch.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\punycode.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\rand.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\rand_pool.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\randerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\rsa.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\rsaerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\security_bits.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\sha.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\siphash.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\siv.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\sm2.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\sm2err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\sm4.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\sparc_arch.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\sparse_array.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\store.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\storeerr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\tserr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\types.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\uierr.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\x509.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\x509err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\crypto\x509v3err.h"> - <Filter>Header Files\include\openssl\crypto</Filter> - </ClInclude> - <ClInclude Include="include\internal\__DECC_INCLUDE_EPILOGUE.H"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\__DECC_INCLUDE_PROLOGUE.H"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\asn1.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\bio.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\comp.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\conf.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\constant_time.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\core.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\cryptlib.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\dane.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\deprecated.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\der.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\dso.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\dsoerr.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\endian.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\err.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\ffc.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\ktls.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\namemap.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\nelem.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\numbers.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\o_dir.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\packet.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\param_build_set.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\passphrase.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\property.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\propertyerr.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\provider.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\refcount.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\sha3.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\sizes.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\sm3.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\sockets.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\sslconf.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\symhacks.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\thread_once.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\tlsgroups.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\tsan_assist.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="include\internal\unicode.h"> - <Filter>Header Files\include\openssl\internal</Filter> - </ClInclude> - <ClInclude Include="miscserverfixes.h"> - <Filter>Header Files\Server</Filter> - </ClInclude> - <ClInclude Include="maxplayers.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\curl.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\curlver.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\easy.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\mprintf.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\multi.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\options.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\stdcheaders.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\system.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\typecheck-gcc.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="include\libcurl\include\curl\urlapi.h"> - <Filter>Header Files\include\libcurl</Filter> - </ClInclude> - <ClInclude Include="rpakfilesystem.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="bansystem.h"> - <Filter>Header Files\Server\Authentication</Filter> - </ClInclude> - <ClInclude Include="languagehooks.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="latencyflex.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="audio.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="buildainfile.h"> - <Filter>Header Files\Server</Filter> - </ClInclude> - <ClInclude Include="bitbuf.h"> - <Filter>Header Files\Shared</Filter> - </ClInclude> - <ClInclude Include="configurables.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="cvar.h"> - <Filter>Header Files\Shared\Convar</Filter> - </ClInclude> - <ClInclude Include="color.h"> - <Filter>Header Files\Shared\Math</Filter> - </ClInclude> - <ClInclude Include="bits.h"> - <Filter>Header Files\Shared\Math</Filter> - </ClInclude> - <ClInclude Include="serverchathooks.h"> - <Filter>Header Files\Server</Filter> - </ClInclude> - <ClInclude Include="clientchathooks.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="localchatwriter.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="scriptservertoclientstringcommand.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="plugins.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="state.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="plugin_abi.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="debugoverlay.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="clientvideooverrides.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="ExploitFixes_UTF8Parser.h"> - <Filter>Source Files\Shared\Exploit Fixes\UTF8Parser</Filter> - </ClInclude> - <ClInclude Include="version.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="clientruihooks.h"> - <Filter>Header Files\Client</Filter> - </ClInclude> - <ClInclude Include="ns_version.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ExploitFixes.h"> - <Filter>Header Files\Shared\ExploitFixes</Filter> - </ClInclude> - <ClInclude Include="NSMem.h"> - <Filter>Header Files\Shared\ExploitFixes</Filter> - </ClInclude> - <ClInclude Include="emit_blocker.h"> - <Filter>Header Files\Shared\ExploitFixes</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="dllmain.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="pch.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="hooks.cpp"> - <Filter>Source Files\Shared\Hooks</Filter> - </ClCompile> - <ClCompile Include="hookutils.cpp"> - <Filter>Source Files\Shared\Hooks</Filter> - </ClCompile> - <ClCompile Include="dedicated.cpp"> - <Filter>Source Files\Dedicated</Filter> - </ClCompile> - <ClCompile Include="sourceconsole.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="squirrel.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="sigscanning.cpp"> - <Filter>Source Files\Shared\Hooks</Filter> - </ClCompile> - <ClCompile Include="logging.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="context.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="sourceinterface.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="convar.cpp"> - <Filter>Source Files\Shared\Convar</Filter> - </ClCompile> - <ClCompile Include="concommand.cpp"> - <Filter>Source Files\Shared\Convar</Filter> - </ClCompile> - <ClCompile Include="modmanager.cpp"> - <Filter>Source Files\Shared\Mods</Filter> - </ClCompile> - <ClCompile Include="filesystem.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="scriptsrson.cpp"> - <Filter>Source Files\Shared\Mods\Compiled</Filter> - </ClCompile> - <ClCompile Include="serverauthentication.cpp"> - <Filter>Source Files\Server\Authentication</Filter> - </ClCompile> - <ClCompile Include="scriptmodmenu.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="scriptserverbrowser.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="keyvalues.cpp"> - <Filter>Source Files\Shared\Mods\Compiled</Filter> - </ClCompile> - <ClCompile Include="masterserver.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="gameutils.cpp"> - <Filter>Source Files\Shared\Game Functions</Filter> - </ClCompile> - <ClCompile Include="chatcommand.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="modlocalisation.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="playlist.cpp"> - <Filter>Source Files\Server</Filter> - </ClCompile> - <ClCompile Include="dedicatedmaterialsystem.cpp"> - <Filter>Source Files\Dedicated</Filter> - </ClCompile> - <ClCompile Include="misccommands.cpp"> - <Filter>Source Files\Shared\Convar</Filter> - </ClCompile> - <ClCompile Include="miscserverscript.cpp"> - <Filter>Source Files\Server</Filter> - </ClCompile> - <ClCompile Include="pdef.cpp"> - <Filter>Source Files\Shared\Mods\Compiled</Filter> - </ClCompile> - <ClCompile Include="clientauthhooks.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="scriptbrowserhooks.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="memalloc.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="scriptmainmenupromos.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="miscclientfixes.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="maxplayers.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="miscserverfixes.cpp"> - <Filter>Source Files\Server</Filter> - </ClCompile> - <ClCompile Include="rpakfilesystem.cpp"> - <Filter>Source Files\Shared</Filter> - </ClCompile> - <ClCompile Include="bansystem.cpp"> - <Filter>Source Files\Server\Authentication</Filter> - </ClCompile> - <ClCompile Include="languagehooks.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="latencyflex.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="audio.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="buildainfile.cpp"> - <Filter>Source Files\Server</Filter> - </ClCompile> - <ClCompile Include="configurables.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="cvar.cpp"> - <Filter>Source Files\Shared\Convar</Filter> - </ClCompile> - <ClCompile Include="bits.cpp"> - <Filter>Source Files\Shared\Math</Filter> - </ClCompile> - <ClCompile Include="serverchathooks.cpp"> - <Filter>Source Files\Server</Filter> - </ClCompile> - <ClCompile Include="clientchathooks.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="localchatwriter.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="scriptservertoclientstringcommand.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="plugins.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="debugoverlay.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="clientvideooverrides.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="ExploitFixes.cpp"> - <Filter>Source Files\Shared\Exploit Fixes</Filter> - </ClCompile> - <ClCompile Include="version.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="clientruihooks.cpp"> - <Filter>Source Files\Client</Filter> - </ClCompile> - <ClCompile Include="emit_blocker.cpp"> - <Filter>Source Files\Shared\Exploit Fixes</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <MASM Include="audio_asm.asm"> - <Filter>Source Files\Client</Filter> - </MASM> - </ItemGroup> - <ItemGroup> - <None Include="include\spdlog\fmt\bundled\LICENSE.rst"> - <Filter>Header Files\include\spdlog\fmt\bundled</Filter> - </None> - <None Include="include\openssl\asn1.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\asn1t.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\bio.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\cmp.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\cms.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\conf.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\configuration.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\crmf.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\crypto.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\ct.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\err.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\ess.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\fipskey.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\lhash.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\ocsp.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\opensslv.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\pkcs7.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\pkcs12.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\safestack.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\srp.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\ssl.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\ui.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\x509.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\x509_vfy.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\openssl\x509v3.h.in"> - <Filter>Header Files\include\openssl\openssl</Filter> - </None> - <None Include="include\crypto\bn_conf.h.in"> - <Filter>Header Files\include\openssl\crypto</Filter> - </None> - <None Include="include\crypto\dso_conf.h.in"> - <Filter>Header Files\include\openssl\crypto</Filter> - </None> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Header Files\include">
+ <UniqueIdentifier>{d4199e4b-10d2-43ce-af9c-e1fa79e1e64e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Client">
+ <UniqueIdentifier>{b6f79919-9735-476d-8798-067a75cbeca0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Client">
+ <UniqueIdentifier>{ca657be5-c2d8-4322-a689-1154aaafe57b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\spdlog">
+ <UniqueIdentifier>{8596cc1c-0492-4467-91e3-1f03b7e19f77}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\spdlog\cfg">
+ <UniqueIdentifier>{11eaa578-6336-456e-9c7c-8bd202470945}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\spdlog\fmt">
+ <UniqueIdentifier>{7ecd75d2-7eee-41c4-87b6-3b7c2213f34e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\spdlog\fmt\bundled">
+ <UniqueIdentifier>{8afc70f1-639c-49ef-9348-ef6dcece114e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\spdlog\sinks">
+ <UniqueIdentifier>{398efed5-0a92-4d32-b5ba-b4a725b2a70a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\spdlog\details">
+ <UniqueIdentifier>{74567974-c66b-45ef-ab28-97b7154ca224}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\rapidjson">
+ <UniqueIdentifier>{4ca5392e-7d3d-4066-833f-f534cd5787c3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\rapidjson\error">
+ <UniqueIdentifier>{94b15898-ef33-41c7-995a-31791fccb7e2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\rapidjson\internal">
+ <UniqueIdentifier>{6495657f-ea55-4552-8aa7-b54eb8e86a99}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\rapidjson\msinttypes">
+ <UniqueIdentifier>{85aacdee-0f92-4ec4-b20c-0739c1175055}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Server">
+ <UniqueIdentifier>{3d41d3fc-8a3b-4358-b3e8-4f06dc96abfe}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Server\Authentication">
+ <UniqueIdentifier>{d69760a9-d5ec-4f3e-8f43-f74041654d44}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Server">
+ <UniqueIdentifier>{365e5c1f-4b2f-4d8b-a1d8-cdef401ca689}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Server\Authentication">
+ <UniqueIdentifier>{24fd0855-9288-4129-93ba-c6cafdc98d1b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\openssl">
+ <UniqueIdentifier>{4cb0dd89-5f16-4549-a864-34ca3075352a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\openssl\openssl">
+ <UniqueIdentifier>{914d8b8f-6b19-4f23-b746-f40062d72906}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\openssl\internal">
+ <UniqueIdentifier>{09516029-fac7-4235-ad61-402977534a0b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\openssl\crypto">
+ <UniqueIdentifier>{8cc1ae44-9dbf-4719-91a2-82e00b8d78e2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\include\libcurl">
+ <UniqueIdentifier>{ea1e17a6-40b7-4e1b-8edb-e9ae704ce604}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Client\Scripted">
+ <UniqueIdentifier>{51910ba0-2ff8-461d-9f67-8d7907b57d22}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Server\Scripted">
+ <UniqueIdentifier>{325e0d7d-6832-496d-8d8e-968fdfa5dd40}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Server\Scripted">
+ <UniqueIdentifier>{802d0771-62f1-4733-89f9-57a4d8864b8d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Console">
+ <UniqueIdentifier>{04fd662a-6e70-494c-b720-c694a5cc2fb1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Convar">
+ <UniqueIdentifier>{a18afb37-5fdd-4340-a6b4-a6541593e398}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Exploit Fixes">
+ <UniqueIdentifier>{4a8a695a-a103-4b1f-b314-0ec19a253119}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Filesystem">
+ <UniqueIdentifier>{d8a83b5e-9a23-4124-824f-eab37880cb08}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Game Functions">
+ <UniqueIdentifier>{2cbddb28-0b17-4881-847d-8773da52b268}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Hooks">
+ <UniqueIdentifier>{4db0d1e9-9035-457f-87f1-5dc3f13b6b9e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Math">
+ <UniqueIdentifier>{59b0f68f-daa7-4641-b6fa-8464b56da2bb}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Mods">
+ <UniqueIdentifier>{3e892d07-2239-44da-9cf3-c288a34cf9a2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Mods\Compiled Assets">
+ <UniqueIdentifier>{14fc0931-acad-46ec-a55e-94f4469d4235}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Dedicated Server">
+ <UniqueIdentifier>{947835db-67d6-42c0-870d-62743f85231f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Console">
+ <UniqueIdentifier>{bf0769d8-40fd-4701-85e9-7ed94aab2283}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Convar">
+ <UniqueIdentifier>{9751b551-5886-45d4-a039-cbd10445263d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Exploit Fixes">
+ <UniqueIdentifier>{96101d42-72af-4fd1-8559-8d1d1ff66240}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Filesystem">
+ <UniqueIdentifier>{ee3ba13a-3061-41d7-981d-328ac2596fd2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Game Functions">
+ <UniqueIdentifier>{0c93d909-e0d6-4c35-a8a4-a13f681a1012}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Hooks">
+ <UniqueIdentifier>{94259c8c-5411-48bf-af4f-46ca32b7d0bb}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Math">
+ <UniqueIdentifier>{44a83740-9d70-480d-9a7a-43b81f8eab9e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Mods">
+ <UniqueIdentifier>{6bbce8a5-38b4-4763-a7cb-4e98012ec245}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Mods\Compiled Assets">
+ <UniqueIdentifier>{826d5193-3ad0-434b-ba7c-dd24ed4bbd0c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Dedicated Server">
+ <UniqueIdentifier>{0f1ba4c4-78ee-4b05-afa5-6f598063f5c1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Squirrel">
+ <UniqueIdentifier>{ca669b16-b8bb-4654-993f-fffa44c914f1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Squirrel">
+ <UniqueIdentifier>{26365f16-ff52-4e80-a01b-2ca020376c93}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Scripted">
+ <UniqueIdentifier>{7263403a-7550-4aa2-a724-f622ab200eed}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="pch.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\MinHook.h">
+ <Filter>Header Files\include</Filter>
+ </ClInclude>
+ <ClInclude Include="main.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sourceconsole.h">
+ <Filter>Header Files\Client</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\async.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\async_logger.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\async_logger-inl.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\common.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\common-inl.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\formatter.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fwd.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\logger.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\logger-inl.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\pattern_formatter.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\pattern_formatter-inl.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\spdlog.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\spdlog-inl.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\stopwatch.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\tweakme.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\version.h">
+ <Filter>Header Files\include\spdlog</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\cfg\argv.h">
+ <Filter>Header Files\include\spdlog\cfg</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\cfg\env.h">
+ <Filter>Header Files\include\spdlog\cfg</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\cfg\helpers.h">
+ <Filter>Header Files\include\spdlog\cfg</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\cfg\helpers-inl.h">
+ <Filter>Header Files\include\spdlog\cfg</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bin_to_hex.h">
+ <Filter>Header Files\include\spdlog\fmt</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\chrono.h">
+ <Filter>Header Files\include\spdlog\fmt</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\fmt.h">
+ <Filter>Header Files\include\spdlog\fmt</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\ostr.h">
+ <Filter>Header Files\include\spdlog\fmt</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\chrono.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\color.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\compile.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\core.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\format.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\format-inl.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\locale.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\os.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\ostream.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\posix.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\printf.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\fmt\bundled\ranges.h">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\android_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\ansicolor_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\ansicolor_sink-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\base_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\base_sink-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\basic_file_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\basic_file_sink-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\daily_file_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\dist_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\dup_filter_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\hourly_file_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\msvc_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\null_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\ostream_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\ringbuffer_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\rotating_file_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\rotating_file_sink-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\sink-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\stdout_color_sinks.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\stdout_color_sinks-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\stdout_sinks.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\stdout_sinks-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\syslog_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\systemd_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\tcp_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\win_eventlog_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\wincolor_sink.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\sinks\wincolor_sink-inl.h">
+ <Filter>Header Files\include\spdlog\sinks</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\backtracer.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\backtracer-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\circular_q.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\console_globals.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\file_helper.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\file_helper-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\fmt_helper.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\log_msg.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\log_msg_buffer.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\log_msg_buffer-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\log_msg-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\mpmc_blocking_q.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\null_mutex.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\os.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\os-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\periodic_worker.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\periodic_worker-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\registry.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\registry-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\synchronous_factory.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\tcp_client.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\tcp_client-windows.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\thread_pool.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\thread_pool-inl.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\spdlog\details\windows_include.h">
+ <Filter>Header Files\include\spdlog\details</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\allocators.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\document.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\encodedstream.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\encodings.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\filereadstream.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\filewritestream.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\fwd.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\istreamwrapper.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\memorybuffer.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\memorystream.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\ostreamwrapper.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\pointer.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\prettywriter.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\rapidjson.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\reader.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\schema.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\stream.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\stringbuffer.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\writer.h">
+ <Filter>Header Files\include\rapidjson</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\error\en.h">
+ <Filter>Header Files\include\rapidjson\error</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\error\error.h">
+ <Filter>Header Files\include\rapidjson\error</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\biginteger.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\diyfp.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\dtoa.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\ieee754.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\itoa.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\meta.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\pow10.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\regex.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\stack.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\strfunc.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\strtod.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\internal\swap.h">
+ <Filter>Header Files\include\rapidjson\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\msinttypes\inttypes.h">
+ <Filter>Header Files\include\rapidjson\msinttypes</Filter>
+ </ClInclude>
+ <ClInclude Include="include\rapidjson\msinttypes\stdint.h">
+ <Filter>Header Files\include\rapidjson\msinttypes</Filter>
+ </ClInclude>
+ <ClInclude Include="serverauthentication.h">
+ <Filter>Header Files\Server\Authentication</Filter>
+ </ClInclude>
+ <ClInclude Include="include\httplib.h">
+ <Filter>Header Files\include</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\__DECC_INCLUDE_EPILOGUE.H">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\__DECC_INCLUDE_PROLOGUE.H">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\aes.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\asn1.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\asn1_mac.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\asn1err.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\asn1t.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\async.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\asyncerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\bio.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\bioerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\blowfish.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\bn.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\bnerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\buffer.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\buffererr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\camellia.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cast.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cmac.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cmp.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cmp_util.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cmperr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cms.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cmserr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\comp.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\comperr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\conf.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\conf_api.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\conferr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\configuration.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\conftypes.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\core.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\core_dispatch.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\core_names.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\core_object.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\crmf.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\crmferr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\crypto.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cryptoerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cryptoerr_legacy.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ct.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\cterr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\decoder.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\decodererr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\des.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\dh.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\dherr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\dsa.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\dsaerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\dtls1.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\e_os2.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ebcdic.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ec.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ecdh.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ecdsa.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ecerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\encoder.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\encodererr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\engine.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\engineerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\err.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ess.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\esserr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\evp.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\evperr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\fips_names.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\fipskey.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\hmac.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\http.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\httperr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\idea.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\kdf.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\kdferr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\lhash.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\macros.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\md2.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\md4.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\md5.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\mdc2.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\modes.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\obj_mac.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\objects.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\objectserr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ocsp.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ocsperr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\opensslconf.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\opensslv.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ossl_typ.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\param_build.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\params.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pem.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pem2.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pemerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pkcs7.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pkcs7err.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pkcs12.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\pkcs12err.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\prov_ssl.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\proverr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\provider.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\rand.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\randerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\rc2.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\rc4.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\rc5.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ripemd.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\rsa.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\rsaerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\safestack.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\seed.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\self_test.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\sha.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\srp.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\srtp.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ssl.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ssl2.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ssl3.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\sslerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\sslerr_legacy.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\stack.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\store.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\storeerr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\symhacks.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\tls1.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\trace.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ts.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\tserr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\txt_db.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\types.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\ui.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\uierr.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\whrlpool.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\x509.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\x509_vfy.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\x509err.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\x509v3.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\openssl\x509v3err.h">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\__DECC_INCLUDE_EPILOGUE.H">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\__DECC_INCLUDE_PROLOGUE.H">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\aes_platform.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\aria.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\asn1.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\asn1_dsa.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\asn1err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\async.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\asyncerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\bioerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\bn.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\bn_conf.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\bn_dh.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\bn_srp.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\bnerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\buffererr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\chacha.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\cmll_platform.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\cmperr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\cmserr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\comperr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\conferr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\crmferr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\cryptlib.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\cryptoerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\cterr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ctype.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\decoder.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\decodererr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\des_platform.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\dh.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\dherr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\dsa.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\dsaerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\dso_conf.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ec.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ecerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ecx.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\encoder.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\encodererr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\engine.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\engineerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ess.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\esserr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\evp.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\evperr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\httperr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\lhash.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\md32_common.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\modes.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\objects.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\objectserr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ocsperr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\pem.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\pemerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\pkcs7.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\pkcs7err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\pkcs12err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\poly1305.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\ppc_arch.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\punycode.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\rand.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\rand_pool.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\randerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\rsa.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\rsaerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\security_bits.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\sha.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\siphash.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\siv.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\sm2.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\sm2err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\sm4.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\sparc_arch.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\sparse_array.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\store.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\storeerr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\tserr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\types.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\uierr.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\x509.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\x509err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\crypto\x509v3err.h">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\__DECC_INCLUDE_EPILOGUE.H">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\__DECC_INCLUDE_PROLOGUE.H">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\asn1.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\bio.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\comp.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\conf.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\constant_time.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\core.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\cryptlib.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\dane.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\deprecated.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\der.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\dso.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\dsoerr.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\endian.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\err.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\ffc.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\ktls.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\namemap.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\nelem.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\numbers.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\o_dir.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\packet.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\param_build_set.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\passphrase.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\property.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\propertyerr.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\provider.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\refcount.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\sha3.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\sizes.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\sm3.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\sockets.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\sslconf.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\symhacks.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\thread_once.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\tlsgroups.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\tsan_assist.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\internal\unicode.h">
+ <Filter>Header Files\include\openssl\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\curl.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\curlver.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\easy.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\mprintf.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\multi.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\options.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\stdcheaders.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\system.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\typecheck-gcc.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="include\libcurl\include\curl\urlapi.h">
+ <Filter>Header Files\include\libcurl</Filter>
+ </ClInclude>
+ <ClInclude Include="bansystem.h">
+ <Filter>Header Files\Server\Authentication</Filter>
+ </ClInclude>
+ <ClInclude Include="audio.h">
+ <Filter>Header Files\Client</Filter>
+ </ClInclude>
+ <ClInclude Include="localchatwriter.h">
+ <Filter>Header Files\Client</Filter>
+ </ClInclude>
+ <ClInclude Include="plugins.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="plugin_abi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ns_version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="serverchathooks.h">
+ <Filter>Header Files\Server\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="dedicated.h">
+ <Filter>Header Files\Dedicated Server</Filter>
+ </ClInclude>
+ <ClInclude Include="nsprefix.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="exploitfixes_utf8parser.cpp">
+ <Filter>Source Files\Exploit Fixes</Filter>
+ </ClInclude>
+ <ClInclude Include="crashhandler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="hoststate.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="masterserver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="memalloc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="playlist.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sourceinterface.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="bits.h">
+ <Filter>Header Files\Math</Filter>
+ </ClInclude>
+ <ClInclude Include="bitbuf.h">
+ <Filter>Header Files\Math</Filter>
+ </ClInclude>
+ <ClInclude Include="convar.h">
+ <Filter>Header Files\Convar</Filter>
+ </ClInclude>
+ <ClInclude Include="concommand.h">
+ <Filter>Header Files\Convar</Filter>
+ </ClInclude>
+ <ClInclude Include="cvar.h">
+ <Filter>Header Files\Convar</Filter>
+ </ClInclude>
+ <ClInclude Include="filesystem.h">
+ <Filter>Header Files\Filesystem</Filter>
+ </ClInclude>
+ <ClInclude Include="hooks.h">
+ <Filter>Header Files\Hooks</Filter>
+ </ClInclude>
+ <ClInclude Include="limits.h">
+ <Filter>Header Files\Exploit Fixes</Filter>
+ </ClInclude>
+ <ClInclude Include="logging.h">
+ <Filter>Header Files\Console</Filter>
+ </ClInclude>
+ <ClInclude Include="misccommands.h">
+ <Filter>Header Files\Convar</Filter>
+ </ClInclude>
+ <ClInclude Include="modmanager.h">
+ <Filter>Header Files\Mods</Filter>
+ </ClInclude>
+ <ClInclude Include="pdef.h">
+ <Filter>Header Files\Mods\Compiled Assets</Filter>
+ </ClInclude>
+ <ClInclude Include="printcommand.h">
+ <Filter>Header Files\Console</Filter>
+ </ClInclude>
+ <ClInclude Include="printmaps.h">
+ <Filter>Header Files\Console</Filter>
+ </ClInclude>
+ <ClInclude Include="r2client.h">
+ <Filter>Header Files\Game Functions</Filter>
+ </ClInclude>
+ <ClInclude Include="r2engine.h">
+ <Filter>Header Files\Game Functions</Filter>
+ </ClInclude>
+ <ClInclude Include="r2server.h">
+ <Filter>Header Files\Game Functions</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptsrson.h">
+ <Filter>Header Files\Mods\Compiled Assets</Filter>
+ </ClInclude>
+ <ClInclude Include="tier0.h">
+ <Filter>Header Files\Game Functions</Filter>
+ </ClInclude>
+ <ClInclude Include="rpakfilesystem.h">
+ <Filter>Header Files\Filesystem</Filter>
+ </ClInclude>
+ <ClInclude Include="color.h">
+ <Filter>Header Files\Math</Filter>
+ </ClInclude>
+ <ClInclude Include="serverpresence.h">
+ <Filter>Header Files\Server</Filter>
+ </ClInclude>
+ <ClInclude Include="memory.h">
+ <Filter>Header Files\Hooks</Filter>
+ </ClInclude>
+ <ClInclude Include="maxplayers.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="squirrel.h">
+ <Filter>Header Files\Squirrel</Filter>
+ </ClInclude>
+ <ClInclude Include="squirreldatatypes.h">
+ <Filter>Header Files\Squirrel</Filter>
+ </ClInclude>
+ <ClInclude Include="vector.h">
+ <Filter>Header Files\Math</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="pch.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dedicated.cpp">
+ <Filter>Source Files\Dedicated Server</Filter>
+ </ClCompile>
+ <ClCompile Include="sourceconsole.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="modmanager.cpp">
+ <Filter>Source Files\Mods</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptsrson.cpp">
+ <Filter>Source Files\Mods\Compiled Assets</Filter>
+ </ClCompile>
+ <ClCompile Include="serverauthentication.cpp">
+ <Filter>Source Files\Server\Authentication</Filter>
+ </ClCompile>
+ <ClCompile Include="keyvalues.cpp">
+ <Filter>Source Files\Mods\Compiled Assets</Filter>
+ </ClCompile>
+ <ClCompile Include="chatcommand.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="modlocalisation.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="dedicatedmaterialsystem.cpp">
+ <Filter>Source Files\Dedicated Server</Filter>
+ </ClCompile>
+ <ClCompile Include="pdef.cpp">
+ <Filter>Source Files\Mods\Compiled Assets</Filter>
+ </ClCompile>
+ <ClCompile Include="clientauthhooks.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="miscserverfixes.cpp">
+ <Filter>Source Files\Server</Filter>
+ </ClCompile>
+ <ClCompile Include="bansystem.cpp">
+ <Filter>Source Files\Server\Authentication</Filter>
+ </ClCompile>
+ <ClCompile Include="languagehooks.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="latencyflex.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="audio.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="buildainfile.cpp">
+ <Filter>Source Files\Server</Filter>
+ </ClCompile>
+ <ClCompile Include="localchatwriter.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="plugins.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="debugoverlay.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="clientvideooverrides.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="version.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="clientruihooks.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptmainmenupromos.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="clientchathooks.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptmodmenu.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptservertoclientstringcommand.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptserverbrowser.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptbrowserhooks.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="serverchathooks.cpp">
+ <Filter>Source Files\Server\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="miscserverscript.cpp">
+ <Filter>Source Files\Server\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="demofixes.cpp">
+ <Filter>Source Files\Client</Filter>
+ </ClCompile>
+ <ClCompile Include="nsprefix.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dllmain.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="crashhandler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="host.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="hoststate.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="masterserver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="maxplayers.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="memalloc.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="playlist.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sourceinterface.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r2server.cpp">
+ <Filter>Source Files\Game Functions</Filter>
+ </ClCompile>
+ <ClCompile Include="r2client.cpp">
+ <Filter>Source Files\Game Functions</Filter>
+ </ClCompile>
+ <ClCompile Include="r2engine.cpp">
+ <Filter>Source Files\Game Functions</Filter>
+ </ClCompile>
+ <ClCompile Include="rpakfilesystem.cpp">
+ <Filter>Source Files\Filesystem</Filter>
+ </ClCompile>
+ <ClCompile Include="filesystem.cpp">
+ <Filter>Source Files\Filesystem</Filter>
+ </ClCompile>
+ <ClCompile Include="exploitfixes.cpp">
+ <Filter>Source Files\Exploit Fixes</Filter>
+ </ClCompile>
+ <ClCompile Include="limits.cpp">
+ <Filter>Source Files\Exploit Fixes</Filter>
+ </ClCompile>
+ <ClCompile Include="hooks.cpp">
+ <Filter>Source Files\Hooks</Filter>
+ </ClCompile>
+ <ClCompile Include="bits.cpp">
+ <Filter>Source Files\Math</Filter>
+ </ClCompile>
+ <ClCompile Include="convar.cpp">
+ <Filter>Source Files\Convar</Filter>
+ </ClCompile>
+ <ClCompile Include="concommand.cpp">
+ <Filter>Source Files\Convar</Filter>
+ </ClCompile>
+ <ClCompile Include="printcommands.cpp">
+ <Filter>Source Files\Console</Filter>
+ </ClCompile>
+ <ClCompile Include="printmaps.cpp">
+ <Filter>Source Files\Console</Filter>
+ </ClCompile>
+ <ClCompile Include="cvar.cpp">
+ <Filter>Source Files\Convar</Filter>
+ </ClCompile>
+ <ClCompile Include="misccommands.cpp">
+ <Filter>Source Files\Convar</Filter>
+ </ClCompile>
+ <ClCompile Include="tier0.cpp">
+ <Filter>Source Files\Game Functions</Filter>
+ </ClCompile>
+ <ClCompile Include="logging.cpp">
+ <Filter>Source Files\Console</Filter>
+ </ClCompile>
+ <ClCompile Include="serverpresence.cpp">
+ <Filter>Source Files\Server</Filter>
+ </ClCompile>
+ <ClCompile Include="runframe.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="memory.cpp">
+ <Filter>Source Files\Hooks</Filter>
+ </ClCompile>
+ <ClCompile Include="exploitfixes_lzss.cpp">
+ <Filter>Source Files\Exploit Fixes</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptutility.cpp">
+ <Filter>Source Files\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptjson.cpp">
+ <Filter>Source Files\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="squirrel.cpp">
+ <Filter>Source Files\Squirrel</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptdatatables.cpp">
+ <Filter>Source Files\Scripted</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="audio_asm.asm">
+ <Filter>Source Files\Client</Filter>
+ </MASM>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="include\spdlog\fmt\bundled\LICENSE.rst">
+ <Filter>Header Files\include\spdlog\fmt\bundled</Filter>
+ </None>
+ <None Include="include\openssl\asn1.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\asn1t.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\bio.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\cmp.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\cms.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\conf.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\configuration.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\crmf.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\crypto.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\ct.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\err.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\ess.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\fipskey.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\lhash.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\ocsp.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\opensslv.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\pkcs7.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\pkcs12.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\safestack.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\srp.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\ssl.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\ui.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\x509.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\x509_vfy.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\openssl\x509v3.h.in">
+ <Filter>Header Files\include\openssl\openssl</Filter>
+ </None>
+ <None Include="include\crypto\bn_conf.h.in">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </None>
+ <None Include="include\crypto\dso_conf.h.in">
+ <Filter>Header Files\include\openssl\crypto</Filter>
+ </None>
+ </ItemGroup>
</Project>
\ No newline at end of file diff --git a/NorthstarDedicatedTest/audio.cpp b/NorthstarDLL/audio.cpp index 0b65670f..268175bf 100644 --- a/NorthstarDedicatedTest/audio.cpp +++ b/NorthstarDLL/audio.cpp @@ -1,13 +1,15 @@ #include "pch.h" #include "audio.h" #include "dedicated.h" +#include "convar.h" #include "rapidjson/error/en.h" #include <fstream> #include <iostream> #include <sstream> #include <random> -#include "convar.h" + +AUTOHOOK_INIT() extern "C" { @@ -194,7 +196,7 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa std::string pathString = file.path().string(); // Open the file. - std::basic_ifstream<uint8_t> wavStream(pathString, std::ios::binary); + std::ifstream wavStream(pathString, std::ios::binary); if (wavStream.fail()) { @@ -219,7 +221,7 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa [pathString, fileSize, data] { std::shared_lock lock(g_CustomAudioManager.m_loadingMutex); - std::basic_ifstream<uint8_t> wavStream(pathString, std::ios::binary); + std::ifstream wavStream(pathString, std::ios::binary); // would be weird if this got hit, since it would've worked previously if (wavStream.fail()) @@ -229,10 +231,8 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa } // read from after the header first to preserve the empty header, then read the header last - wavStream.seekg(sizeof(EMPTY_WAVE), std::ios::beg); - wavStream.read(&data[sizeof(EMPTY_WAVE)], fileSize - sizeof(EMPTY_WAVE)); wavStream.seekg(0, std::ios::beg); - wavStream.read(data, sizeof(EMPTY_WAVE)); + wavStream.read(reinterpret_cast<char*>(data), fileSize); wavStream.close(); spdlog::info("Finished async read of audio sample {}", pathString); @@ -265,7 +265,7 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath) { - if (IsDedicated()) + if (IsDedicatedServer()) return true; // silently fail std::ifstream jsonStream(defPath); @@ -308,13 +308,14 @@ MilesStopAll_Type MilesStopAll; void CustomAudioManager::ClearAudioOverrides() { - if (IsDedicated()) + if (IsDedicatedServer()) return; if (m_loadedAudioOverrides.size() > 0 || m_loadedAudioOverridesRegex.size() > 0) { // stop all miles sounds beforehand // miles_stop_all + MilesStopAll(); // this is cancer but it works @@ -329,9 +330,6 @@ void CustomAudioManager::ClearAudioOverrides() m_loadedAudioOverridesRegex.clear(); } -typedef bool (*LoadSampleMetadata_Type)(void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType); -LoadSampleMetadata_Type LoadSampleMetadata_Original; - template <typename Iter, typename RandomGenerator> Iter select_randomly(Iter start, Iter end, RandomGenerator& g) { std::uniform_int_distribution<> dis(0, std::distance(start, end) - 1); @@ -368,6 +366,26 @@ bool ShouldPlayAudioEvent(const char* eventName, const std::shared_ptr<EventOver return true; // good to go } +// forward declare +bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( + uintptr_t parentEvent, void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType); + +// DO NOT TOUCH THIS FUNCTION +// The actual logic of it in a separate function (forcefully not inlined) to preserve the r12 register, which holds the event pointer. +// clang-format off +AUTOHOOK(LoadSampleMetadata, mileswin64.dll + 0xF110, +bool, __fastcall, (void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType)) +// clang-format on +{ + uintptr_t parentEvent = (uintptr_t)Audio_GetParentEvent(); + + // Raw source, used for voice data only + if (audioType == 0) + return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType); + + return LoadSampleMetadata_Internal(parentEvent, sample, audioBuffer, audioBufferLength, audioType); +} + // DO NOT INLINE THIS FUNCTION // See comment below. bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( @@ -398,7 +416,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( if (!overrideData) // not found either - return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType); + return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType); else { // cache found pattern to improve performance @@ -412,7 +430,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( overrideData = iter->second; if (!ShouldPlayAudioEvent(eventName, overrideData)) - return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType); + return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType); void* data = 0; unsigned int dataLength = 0; @@ -454,7 +472,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( if (!data) { spdlog::warn("Could not fetch override sample data for event {}! Using original data instead.", eventName); - return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType); + return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType); } audioBuffer = data; @@ -465,51 +483,25 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal( *(unsigned int*)((uintptr_t)sample + 0xF0) = audioBufferLength; // 64 - Auto-detect sample type - bool res = LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, 64); + bool res = LoadSampleMetadata(sample, audioBuffer, audioBufferLength, 64); if (!res) spdlog::error("LoadSampleMetadata failed! The game will crash :("); return res; } -// DO NOT TOUCH THIS FUNCTION -// The actual logic of it in a separate function (forcefully not inlined) to preserve the r12 register, which holds the event pointer. -bool __fastcall LoadSampleMetadata_Hook(void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType) -{ - uintptr_t parentEvent = (uintptr_t)Audio_GetParentEvent(); - - // Raw source, used for voice data only - if (audioType == 0) - return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType); - - return LoadSampleMetadata_Internal(parentEvent, sample, audioBuffer, audioBufferLength, audioType); -} - -typedef bool (*MilesLog_Type)(int level, const char* string); -MilesLog_Type MilesLog_Original; - -void __fastcall MilesLog_Hook(int level, const char* string) +// clang-format off +AUTOHOOK(MilesLog, client.dll + 0x57DAD0, +void, __fastcall, (int level, const char* string)) +// clang-format on { spdlog::info("[MSS] {} - {}", level, string); } -void InitialiseMilesAudioHooks(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", AudioHooks, ConVar, (CModule module)) { - Cvar_ns_print_played_sounds = new ConVar("ns_print_played_sounds", "0", FCVAR_NONE, ""); - - if (IsDedicated()) - return; - - uintptr_t milesAudioBase = (uintptr_t)GetModuleHandleA("mileswin64.dll"); - - if (!milesAudioBase) - return spdlog::error("miles audio not found :terror:"); + AUTOHOOK_DISPATCH() - HookEnabler hook; - - ENABLER_CREATEHOOK( - hook, (char*)milesAudioBase + 0xF110, &LoadSampleMetadata_Hook, reinterpret_cast<LPVOID*>(&LoadSampleMetadata_Original)); - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x57DAD0, &MilesLog_Hook, reinterpret_cast<LPVOID*>(&MilesLog_Original)); - - MilesStopAll = (MilesStopAll_Type)((char*)baseAddress + 0x580850); -}
\ No newline at end of file + Cvar_ns_print_played_sounds = new ConVar("ns_print_played_sounds", "0", FCVAR_NONE, ""); + MilesStopAll = module.Offset(0x580850).As<MilesStopAll_Type>(); +} diff --git a/NorthstarDedicatedTest/audio.h b/NorthstarDLL/audio.h index 6ed3ce57..26cda205 100644 --- a/NorthstarDedicatedTest/audio.h +++ b/NorthstarDLL/audio.h @@ -5,8 +5,6 @@ #include <regex> #include <shared_mutex> -namespace fs = std::filesystem; - enum class AudioSelectionStrategy { INVALID = -1, @@ -46,5 +44,3 @@ class CustomAudioManager }; extern CustomAudioManager g_CustomAudioManager; - -void InitialiseMilesAudioHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/audio_asm.asm b/NorthstarDLL/audio_asm.asm index 4c527f9d..1b2d3f8d 100644 --- a/NorthstarDedicatedTest/audio_asm.asm +++ b/NorthstarDLL/audio_asm.asm @@ -5,4 +5,4 @@ Audio_GetParentEvent proc mov rax, r12 ret Audio_GetParentEvent endp -end
\ No newline at end of file +end diff --git a/NorthstarDLL/bansystem.cpp b/NorthstarDLL/bansystem.cpp new file mode 100644 index 00000000..25c0e6bf --- /dev/null +++ b/NorthstarDLL/bansystem.cpp @@ -0,0 +1,222 @@ +#pragma once +#include "pch.h" +#include "bansystem.h" +#include "serverauthentication.h" +#include "maxplayers.h" +#include "concommand.h" +#include "r2server.h" +#include "r2engine.h" +#include "nsprefix.h" + +#include <filesystem> + +const char* BANLIST_PATH_SUFFIX = "/banlist.txt"; +const char BANLIST_COMMENT_CHAR = '#'; + +ServerBanSystem* g_pBanSystem; + +void ServerBanSystem::OpenBanlist() +{ + std::ifstream banlistStream(GetNorthstarPrefix() + "/banlist.txt"); + + if (!banlistStream.fail()) + { + std::string line; + while (std::getline(banlistStream, line)) + { + // ignore line if first char is # or line is empty + if (line == "" || line.front() == BANLIST_COMMENT_CHAR) + continue; + + // remove tabs which shouldnt be there but maybe someone did the funny + line.erase(std::remove(line.begin(), line.end(), '\t'), line.end()); + // remove spaces to allow for spaces before uids + line.erase(std::remove(line.begin(), line.end(), ' '), line.end()); + + // check if line is empty to allow for newlines in the file + if (line == "") + continue; + + // for inline comments like: 123123123 #banned for unfunny + std::string uid = line.substr(0, line.find(BANLIST_COMMENT_CHAR)); + + m_vBannedUids.push_back(strtoull(uid.c_str(), nullptr, 10)); + } + + banlistStream.close(); + } + + // open write stream for banlist // dont do this to allow for all time access + // m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary | std::ofstream::app); +} + +void ServerBanSystem::ReloadBanlist() +{ + std::ifstream fsBanlist(GetNorthstarPrefix() + "/banlist.txt"); + + if (!fsBanlist.fail()) + { + std::string line; + // since we wanna use this as the reload func we need to clear the list + m_vBannedUids.clear(); + while (std::getline(fsBanlist, line)) + m_vBannedUids.push_back(strtoull(line.c_str(), nullptr, 10)); + + fsBanlist.close(); + } +} + +void ServerBanSystem::ClearBanlist() +{ + m_vBannedUids.clear(); + + // reopen the file, don't provide std::ofstream::app so it clears on open + m_sBanlistStream.close(); + m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary); + m_sBanlistStream.close(); +} + +void ServerBanSystem::BanUID(uint64_t uid) +{ + // checking if last char is \n to make sure uids arent getting fucked + std::ifstream fsBanlist(GetNorthstarPrefix() + "/banlist.txt"); + std::string content((std::istreambuf_iterator<char>(fsBanlist)), (std::istreambuf_iterator<char>())); + fsBanlist.close(); + + m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary | std::ofstream::app); + if (content.back() != '\n') + m_sBanlistStream << std::endl; + + m_vBannedUids.push_back(uid); + m_sBanlistStream << std::to_string(uid) << std::endl; + m_sBanlistStream.close(); + spdlog::info("{} was banned", uid); +} + +void ServerBanSystem::UnbanUID(uint64_t uid) +{ + auto findResult = std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid); + if (findResult == m_vBannedUids.end()) + return; + + m_vBannedUids.erase(findResult); + + std::vector<std::string> banlistText; + std::ifstream fs_readBanlist(GetNorthstarPrefix() + "/banlist.txt"); + + if (!fs_readBanlist.fail()) + { + std::string line; + while (std::getline(fs_readBanlist, line)) + { + // support for comments and newlines added in https://github.com/R2Northstar/NorthstarLauncher/pull/227 + + std::string modLine = line; // copy the line into a free var that we can fuck with, line will be the original + + // remove tabs which shouldnt be there but maybe someone did the funny + modLine.erase(std::remove(modLine.begin(), modLine.end(), '\t'), modLine.end()); + // remove spaces to allow for spaces before uids + modLine.erase(std::remove(modLine.begin(), modLine.end(), ' '), modLine.end()); + + // ignore line if first char is # or empty line, just add it + if (line.front() == BANLIST_COMMENT_CHAR || modLine == "") + { + banlistText.push_back(line); + continue; + } + + // for inline comments like: 123123123 #banned for unfunny + std::string lineUid = line.substr(0, line.find(BANLIST_COMMENT_CHAR)); + // have to erase spaces or else inline comments will fuck up the uid finding + lineUid.erase(std::remove(lineUid.begin(), lineUid.end(), '\t'), lineUid.end()); + lineUid.erase(std::remove(lineUid.begin(), lineUid.end(), ' '), lineUid.end()); + + // if the uid in the line is the uid we wanna unban + if (std::to_string(uid) == lineUid) + { + // comment the uid out + line.insert(0, "# "); + + // add a comment with unban date + // not necessary but i feel like this makes it better + std::time_t t = std::time(0); + std::tm* now = std::localtime(&t); + + std::ostringstream unbanComment; + + //{y}/{m}/{d} {h}:{m} + unbanComment << " # unban date: "; + unbanComment << now->tm_year + 1900 << "-"; // this lib is so fucking awful + unbanComment << std::setw(2) << std::setfill('0') << now->tm_mon + 1 << "-"; + unbanComment << std::setw(2) << std::setfill('0') << now->tm_mday << " "; + unbanComment << std::setw(2) << std::setfill('0') << now->tm_hour << ":"; + unbanComment << std::setw(2) << std::setfill('0') << now->tm_min; + + line.append(unbanComment.str()); + } + + banlistText.push_back(line); + } + + fs_readBanlist.close(); + } + + // open write stream for banlist // without append so we clear the file + if (m_sBanlistStream.is_open()) + m_sBanlistStream.close(); + m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary); + + for (std::string updatedLine : banlistText) + m_sBanlistStream << updatedLine << std::endl; + + m_sBanlistStream.close(); + spdlog::info("{} was unbanned", uid); +} + +bool ServerBanSystem::IsUIDAllowed(uint64_t uid) +{ + ReloadBanlist(); // Reload to have up to date list on join + return std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid) == m_vBannedUids.end(); +} + +void ConCommand_ban(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + for (int i = 0; i < R2::GetMaxPlayers(); i++) + { + R2::CBaseClient* player = &R2::g_pClientArray[i]; + + if (!strcmp(player->m_Name, args.Arg(1)) || !strcmp(player->m_UID, args.Arg(1))) + { + g_pBanSystem->BanUID(strtoull(player->m_UID, nullptr, 10)); + R2::CBaseClient__Disconnect(player, 1, "Banned from server"); + break; + } + } +} + +void ConCommand_unban(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + // assumedly the player being unbanned here wasn't already connected, so don't need to iterate over players or anything + g_pBanSystem->UnbanUID(strtoull(args.Arg(1), nullptr, 10)); +} + +void ConCommand_clearbanlist(const CCommand& args) +{ + g_pBanSystem->ClearBanlist(); +} + +ON_DLL_LOAD_RELIESON("engine.dll", BanSystem, ConCommand, (CModule module)) +{ + g_pBanSystem = new ServerBanSystem; + g_pBanSystem->OpenBanlist(); + + RegisterConCommand("ban", ConCommand_ban, "bans a given player by uid or name", FCVAR_GAMEDLL); + RegisterConCommand("unban", ConCommand_unban, "unbans a given player by uid", FCVAR_GAMEDLL); + RegisterConCommand("clearbanlist", ConCommand_clearbanlist, "clears all uids on the banlist", FCVAR_GAMEDLL); +} diff --git a/NorthstarDedicatedTest/bansystem.h b/NorthstarDLL/bansystem.h index 0f618843..6f180126 100644 --- a/NorthstarDedicatedTest/bansystem.h +++ b/NorthstarDLL/bansystem.h @@ -9,12 +9,11 @@ class ServerBanSystem public: void OpenBanlist(); + void ReloadBanlist(); void ClearBanlist(); void BanUID(uint64_t uid); void UnbanUID(uint64_t uid); bool IsUIDAllowed(uint64_t uid); }; -extern ServerBanSystem* g_ServerBanSystem; - -void InitialiseBanSystem(HMODULE baseAddress);
\ No newline at end of file +extern ServerBanSystem* g_pBanSystem; diff --git a/NorthstarDedicatedTest/bitbuf.h b/NorthstarDLL/bitbuf.h index 520e5d0a..8e8e216f 100644 --- a/NorthstarDedicatedTest/bitbuf.h +++ b/NorthstarDLL/bitbuf.h @@ -1145,4 +1145,4 @@ class BFWrite : public BitBufferBase bool m_Flushed = false; // :flushed: }; -#undef INLINE
\ No newline at end of file +#undef INLINE diff --git a/NorthstarDedicatedTest/bits.cpp b/NorthstarDLL/bits.cpp index 014899f2..014899f2 100644 --- a/NorthstarDedicatedTest/bits.cpp +++ b/NorthstarDLL/bits.cpp diff --git a/NorthstarDedicatedTest/bits.h b/NorthstarDLL/bits.h index 0532a9bd..0532a9bd 100644 --- a/NorthstarDedicatedTest/bits.h +++ b/NorthstarDLL/bits.h diff --git a/NorthstarDedicatedTest/buildainfile.cpp b/NorthstarDLL/buildainfile.cpp index 010f0975..8190adba 100644 --- a/NorthstarDedicatedTest/buildainfile.cpp +++ b/NorthstarDLL/buildainfile.cpp @@ -1,19 +1,19 @@ #include "pch.h" -#include "buildainfile.h" #include "convar.h" -#include "hookutils.h" +#include "hoststate.h" +#include "r2engine.h" + #include <fstream> #include <filesystem> -#include "NSMem.h" -namespace fs = std::filesystem; +AUTOHOOK_INIT() const int AINET_VERSION_NUMBER = 57; const int AINET_SCRIPT_VERSION_NUMBER = 21; -const int MAP_VERSION_TEMP = 30; const int PLACEHOLDER_CRC = 0; const int MAX_HULLS = 5; +#pragma pack(push, 1) struct CAI_NodeLink { short srcId; @@ -24,6 +24,7 @@ struct CAI_NodeLink char unk2[5]; int64_t flags; }; +#pragma pack(pop) #pragma pack(push, 1) struct CAI_NodeLinkDisk @@ -33,7 +34,9 @@ struct CAI_NodeLinkDisk char unk0; bool hulls[MAX_HULLS]; }; +#pragma pack(pop) +#pragma pack(push, 1) struct CAI_Node { int index; // not present on disk @@ -62,6 +65,7 @@ struct CAI_Node char unk9[8]; // padding until next bit char unk10[8]; // should match up to unk6 on disk }; +#pragma pack(pop) // the way CAI_Nodes are represented in on-disk ain files #pragma pack(push, 1) @@ -81,7 +85,9 @@ struct CAI_NodeDisk short unk5; char unk6[8]; }; // total size of 68 bytes +#pragma pack(pop) +#pragma pack(push, 1) struct UnkNodeStruct0 { int index; @@ -106,10 +112,12 @@ struct UnkNodeStruct0 char pad4[132]; char unk5; }; +#pragma pack(pop) int* pUnkStruct0Count; UnkNodeStruct0*** pppUnkNodeStruct0s; +#pragma pack(push, 1) struct UnkLinkStruct1 { short unk0; @@ -119,10 +127,12 @@ struct UnkLinkStruct1 char unk4; char unk5; }; +#pragma pack(pop) int* pUnkLinkStruct1Count; UnkLinkStruct1*** pppUnkStruct1s; +#pragma pack(push, 1) struct CAI_ScriptNode { float x; @@ -130,7 +140,9 @@ struct CAI_ScriptNode float z; uint64_t scriptdata; }; +#pragma pack(pop) +#pragma pack(push, 1) struct CAI_Network { // +0 @@ -160,16 +172,16 @@ struct CAI_Network // +84176 CAI_Node** nodes; }; +#pragma pack(pop) char** pUnkServerMapversionGlobal; -char* pMapName; ConVar* Cvar_ns_ai_dumpAINfileFromLoad; void DumpAINInfo(CAI_Network* aiNetwork) { - fs::path writePath("r2/maps/graphs"); - writePath /= pMapName; + fs::path writePath(fmt::format("{}/maps/graphs", R2::g_pModName)); + writePath /= R2::g_pHostState->m_levelName; writePath += ".ain"; // dump from memory @@ -349,20 +361,20 @@ void DumpAINInfo(CAI_Network* aiNetwork) writeStream.close(); } -typedef void (*CAI_NetworkBuilder__BuildType)(void* builder, CAI_Network* aiNetwork, void* unknown); -CAI_NetworkBuilder__BuildType CAI_NetworkBuilder__Build; - -void CAI_NetworkBuilder__BuildHook(void* builder, CAI_Network* aiNetwork, void* unknown) +// clang-format off +AUTOHOOK(CAI_NetworkBuilder__Build, server.dll + 0x385E20, +void, __fastcall, (void* builder, CAI_Network* aiNetwork, void* unknown)) +// clang-format on { CAI_NetworkBuilder__Build(builder, aiNetwork, unknown); DumpAINInfo(aiNetwork); } -typedef void (*LoadAINFileType)(void* aimanager, void* buf, const char* filename); -LoadAINFileType LoadAINFile; - -void LoadAINFileHook(void* aimanager, void* buf, const char* filename) +// clang-format off +AUTOHOOK(LoadAINFile, server.dll + 0x3933A0, +void, __fastcall, (void* aimanager, void* buf, const char* filename)) +// clang-format on { LoadAINFile(aimanager, buf, filename); @@ -373,28 +385,16 @@ void LoadAINFileHook(void* aimanager, void* buf, const char* filename) } } -void InitialiseBuildAINFileHooks(HMODULE baseAddress) +ON_DLL_LOAD("server.dll", BuildAINFile, (CModule module)) { + AUTOHOOK_DISPATCH() + Cvar_ns_ai_dumpAINfileFromLoad = new ConVar( "ns_ai_dumpAINfileFromLoad", "0", FCVAR_NONE, "For debugging: whether we should dump ain data for ains loaded from disk"); - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x385E20, &CAI_NetworkBuilder__BuildHook, reinterpret_cast<LPVOID*>(&CAI_NetworkBuilder__Build)); - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x3933A0, &LoadAINFileHook, reinterpret_cast<LPVOID*>(&LoadAINFile)); - - pUnkStruct0Count = (int*)((char*)baseAddress + 0x1063BF8); - pppUnkNodeStruct0s = (UnkNodeStruct0***)((char*)baseAddress + 0x1063BE0); - - pUnkLinkStruct1Count = (int*)((char*)baseAddress + 0x1063AA8); - pppUnkStruct1s = (UnkLinkStruct1***)((char*)baseAddress + 0x1063A90); - pUnkServerMapversionGlobal = (char**)((char*)baseAddress + 0xBFBE08); - pMapName = (char*)baseAddress + 0x1053370; - - uintptr_t base = (uintptr_t)baseAddress; - - // remove a check that prevents a logging function in link generation from working - // due to the sheer amount of logging this is a massive perf hit to generation, but spewlog_enable 0 exists so whatever - NSMem::NOP(base + 0x3889B6, 6); - NSMem::NOP(base + 0x3889BF, 6); -}
\ No newline at end of file + pUnkStruct0Count = module.Offset(0x1063BF8).As<int*>(); + pppUnkNodeStruct0s = module.Offset(0x1063BE0).As<UnkNodeStruct0***>(); + pUnkLinkStruct1Count = module.Offset(0x1063AA8).As<int*>(); + pppUnkStruct1s = module.Offset(0x1063A90).As<UnkLinkStruct1***>(); + pUnkServerMapversionGlobal = module.Offset(0xBFBE08).As<char**>(); +} diff --git a/NorthstarDedicatedTest/chatcommand.cpp b/NorthstarDLL/chatcommand.cpp index 2aa51737..37c438f3 100644 --- a/NorthstarDedicatedTest/chatcommand.cpp +++ b/NorthstarDLL/chatcommand.cpp @@ -1,13 +1,11 @@ #include "pch.h" #include "convar.h" #include "concommand.h" -#include "chatcommand.h" #include "localchatwriter.h" // note: isIngameChat is an int64 because the whole register the arg is stored in needs to be 0'd out to work // if isIngameChat is false, we use network chat instead -typedef void(__fastcall* ClientSayTextType)(void* a1, const char* message, __int64 isIngameChat, bool isTeamChat); -ClientSayTextType ClientSayText; +void(__fastcall* ClientSayText)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat); void ConCommand_say(const CCommand& args) { @@ -29,9 +27,9 @@ void ConCommand_log(const CCommand& args) } } -void InitialiseChatCommands(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientChatCommand, ConCommand, (CModule module)) { - ClientSayText = (ClientSayTextType)((char*)baseAddress + 0x54780); + ClientSayText = module.Offset(0x54780).As<void(__fastcall*)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat)>(); RegisterConCommand("say", ConCommand_say, "Enters a message in public chat", FCVAR_CLIENTDLL); RegisterConCommand("say_team", ConCommand_say_team, "Enters a message in team chat", FCVAR_CLIENTDLL); RegisterConCommand("log", ConCommand_log, "Log a message to the local chat window", FCVAR_CLIENTDLL); diff --git a/NorthstarDedicatedTest/clientauthhooks.cpp b/NorthstarDLL/clientauthhooks.cpp index 5c1c4510..ccd7432e 100644 --- a/NorthstarDedicatedTest/clientauthhooks.cpp +++ b/NorthstarDLL/clientauthhooks.cpp @@ -1,12 +1,9 @@ #include "pch.h" -#include "clientauthhooks.h" -#include "hookutils.h" -#include "gameutils.h" #include "masterserver.h" #include "convar.h" +#include "r2client.h" -typedef void (*AuthWithStryderType)(void* a1); -AuthWithStryderType AuthWithStryder; +AUTOHOOK_INIT() ConVar* Cvar_ns_has_agreed_to_send_token; @@ -15,33 +12,35 @@ const int NOT_DECIDED_TO_SEND_TOKEN = 0; const int AGREED_TO_SEND_TOKEN = 1; const int DISAGREED_TO_SEND_TOKEN = 2; -void AuthWithStryderHook(void* a1) +// clang-format off +AUTOHOOK(AuthWithStryder, engine.dll + 0x1843A0, +void, __fastcall, (void* a1)) +// clang-format on { // game will call this forever, until it gets a valid auth key // so, we need to manually invalidate our key until we're authed with northstar, then we'll allow game to auth with stryder - if (!g_MasterServerManager->m_bOriginAuthWithMasterServerDone && Cvar_ns_has_agreed_to_send_token->GetInt() != DISAGREED_TO_SEND_TOKEN) + if (!g_pMasterServerManager->m_bOriginAuthWithMasterServerDone && Cvar_ns_has_agreed_to_send_token->GetInt() != DISAGREED_TO_SEND_TOKEN) { // if player has agreed to send token and we aren't already authing, try to auth if (Cvar_ns_has_agreed_to_send_token->GetInt() == AGREED_TO_SEND_TOKEN && - !g_MasterServerManager->m_bOriginAuthWithMasterServerInProgress) - g_MasterServerManager->AuthenticateOriginWithMasterServer(g_LocalPlayerUserID, g_LocalPlayerOriginToken); + !g_pMasterServerManager->m_bOriginAuthWithMasterServerInProgress) + g_pMasterServerManager->AuthenticateOriginWithMasterServer(R2::g_pLocalPlayerUserID, R2::g_pLocalPlayerOriginToken); // invalidate key so auth will fail - *g_LocalPlayerOriginToken = 0; + *R2::g_pLocalPlayerOriginToken = 0; } AuthWithStryder(a1); } -void InitialiseClientAuthHooks(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientAuthHooks, ConVar, (CModule module)) { + AUTOHOOK_DISPATCH() + // this cvar will save to cfg once initially agreed with Cvar_ns_has_agreed_to_send_token = new ConVar( "ns_has_agreed_to_send_token", "0", FCVAR_ARCHIVE_PLAYERPROFILE, "whether the user has agreed to send their origin token to the northstar masterserver"); - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1843A0, &AuthWithStryderHook, reinterpret_cast<LPVOID*>(&AuthWithStryder)); -}
\ No newline at end of file +} diff --git a/NorthstarDLL/clientchathooks.cpp b/NorthstarDLL/clientchathooks.cpp new file mode 100644 index 00000000..a7a42689 --- /dev/null +++ b/NorthstarDLL/clientchathooks.cpp @@ -0,0 +1,83 @@ +#include "pch.h" +#include "squirrel.h" +#include "serverchathooks.h" +#include "localchatwriter.h" + +#include <rapidjson/document.h> + +AUTOHOOK_INIT() + +// clang-format off +AUTOHOOK(CHudChat__AddGameLine, client.dll + 0x22E580, +void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bool isDead)) +// clang-format on +{ + // This hook is called for each HUD, but we only want our logic to run once. + if (self != *CHudChat::allHuds) + return; + + if (g_pSquirrel<ScriptContext::CLIENT>->setupfunc("CHudChat_ProcessMessageStartThread") != SQRESULT_ERROR) + { + int senderId = inboxId & CUSTOM_MESSAGE_INDEX_MASK; + bool isAnonymous = senderId == 0; + bool isCustom = isAnonymous || (inboxId & CUSTOM_MESSAGE_INDEX_BIT); + + // Type is set to 0 for non-custom messages, custom messages have a type encoded as the first byte + int type = 0; + const char* payload = message; + if (isCustom) + { + type = message[0]; + payload = message + 1; + } + + g_pSquirrel<ScriptContext::CLIENT>->pushinteger(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, (int)senderId - 1); + g_pSquirrel<ScriptContext::CLIENT>->pushstring(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, payload); + g_pSquirrel<ScriptContext::CLIENT>->pushbool(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, isTeam); + g_pSquirrel<ScriptContext::CLIENT>->pushbool(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, isDead); + g_pSquirrel<ScriptContext::CLIENT>->pushinteger(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, type); + g_pSquirrel<ScriptContext::CLIENT>->call(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, 5); + } + else + for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next) + CHudChat__AddGameLine(hud, message, inboxId, isTeam, isDead); +} + +// void NSChatWrite( int context, string str ) +SQRESULT SQ_ChatWrite(HSquirrelVM* sqvm) +{ + int context = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1); + const char* str = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2); + + LocalChatWriter((LocalChatWriter::Context)context).Write(str); + return SQRESULT_NULL; +} + +// void NSChatWriteRaw( int context, string str ) +SQRESULT SQ_ChatWriteRaw(HSquirrelVM* sqvm) +{ + int context = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1); + const char* str = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2); + + LocalChatWriter((LocalChatWriter::Context)context).InsertText(str); + return SQRESULT_NULL; +} + +// void NSChatWriteLine( int context, string str ) +SQRESULT SQ_ChatWriteLine(HSquirrelVM* sqvm) +{ + int context = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1); + const char* str = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2); + + LocalChatWriter((LocalChatWriter::Context)context).WriteLine(str); + return SQRESULT_NULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientChatHooks, ClientSquirrel, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration("void", "NSChatWrite", "int context, string text", "", SQ_ChatWrite); + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration("void", "NSChatWriteRaw", "int context, string text", "", SQ_ChatWriteRaw); + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration("void", "NSChatWriteLine", "int context, string text", "", SQ_ChatWriteLine); +} diff --git a/NorthstarDLL/clientruihooks.cpp b/NorthstarDLL/clientruihooks.cpp new file mode 100644 index 00000000..3cb08368 --- /dev/null +++ b/NorthstarDLL/clientruihooks.cpp @@ -0,0 +1,24 @@ +#include "pch.h" +#include "convar.h" + +AUTOHOOK_INIT() + +ConVar* Cvar_rui_drawEnable; + +// clang-format off +AUTOHOOK(DrawRUIFunc, engine.dll + 0xFC500, +bool, __fastcall, (void* a1, float* a2)) +// clang-format on +{ + if (!Cvar_rui_drawEnable->GetBool()) + return 0; + + return DrawRUIFunc(a1, a2); +} + +ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", RUI, ConVar, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + Cvar_rui_drawEnable = new ConVar("rui_drawEnable", "1", FCVAR_CLIENTDLL, "Controls whether RUI should be drawn"); +} diff --git a/NorthstarDLL/clientvideooverrides.cpp b/NorthstarDLL/clientvideooverrides.cpp new file mode 100644 index 00000000..b9954bf2 --- /dev/null +++ b/NorthstarDLL/clientvideooverrides.cpp @@ -0,0 +1,42 @@ +#include "pch.h" +#include "modmanager.h" + +AUTOHOOK_INIT() + +// clang-format off +AUTOHOOK_PROCADDRESS(BinkOpen, bink2w64.dll, BinkOpen, +void*, __fastcall, (const char* path, uint32_t flags)) +// clang-format on +{ + std::string filename(fs::path(path).filename().string()); + spdlog::info("BinkOpen {}", filename); + + // figure out which mod is handling the bink + Mod* fileOwner = nullptr; + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + if (std::find(mod.BinkVideos.begin(), mod.BinkVideos.end(), filename) != mod.BinkVideos.end()) + fileOwner = &mod; + } + + if (fileOwner) + { + // create new path + fs::path binkPath(fileOwner->m_ModDirectory / "media" / filename); + return BinkOpen(binkPath.string().c_str(), flags); + } + else + return BinkOpen(path, flags); +} + +ON_DLL_LOAD_CLIENT("client.dll", BinkVideo, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + // remove engine check for whether the bik we're trying to load exists in r2/media, as this will fail for biks in mods + // note: the check in engine is actually unnecessary, so it's just useless in practice and we lose nothing by removing it + module.Offset(0x459AD).NOP(6); +} diff --git a/NorthstarDedicatedTest/color.h b/NorthstarDLL/color.h index e2c1ebba..e2c1ebba 100644 --- a/NorthstarDedicatedTest/color.h +++ b/NorthstarDLL/color.h diff --git a/NorthstarDedicatedTest/concommand.cpp b/NorthstarDLL/concommand.cpp index 1bdda91b..6d77e137 100644 --- a/NorthstarDedicatedTest/concommand.cpp +++ b/NorthstarDLL/concommand.cpp @@ -1,27 +1,8 @@ #include "pch.h" #include "concommand.h" -#include "gameutils.h" #include "misccommands.h" -#include <iostream> - -typedef void (*ConCommandConstructorType)( - ConCommand* newCommand, const char* name, void (*callback)(const CCommand&), const char* helpString, int flags, void* parent); -ConCommandConstructorType conCommandConstructor; - -void RegisterConCommand(const char* name, void (*callback)(const CCommand&), const char* helpString, int flags) -{ - spdlog::info("Registering ConCommand {}", name); - - // no need to free this ever really, it should exist as long as game does - ConCommand* newCommand = new ConCommand; - conCommandConstructor(newCommand, name, callback, helpString, flags, nullptr); -} -void InitialiseConCommands(HMODULE baseAddress) -{ - conCommandConstructor = (ConCommandConstructorType)((char*)baseAddress + 0x415F60); - AddMiscConCommands(); -} +#include <iostream> //----------------------------------------------------------------------------- // Purpose: Returns true if this is a command @@ -57,7 +38,7 @@ bool ConCommandBase::IsRegistered(void) const //----------------------------------------------------------------------------- bool ConCommandBase::IsFlagSet(int nFlags) const { - return false; // !TODO: Returning false on every query? (original implementation in Northstar before ConCommandBase refactor) + return m_nFlags & nFlags; } //----------------------------------------------------------------------------- @@ -138,3 +119,33 @@ char* ConCommandBase::CopyString(const char* szFrom) const } return szTo; } + +typedef void (*ConCommandConstructorType)( + ConCommand* newCommand, const char* name, FnCommandCallback_t callback, const char* helpString, int flags, void* parent); +ConCommandConstructorType ConCommandConstructor; + +void RegisterConCommand(const char* name, FnCommandCallback_t callback, const char* helpString, int flags) +{ + spdlog::info("Registering ConCommand {}", name); + + // no need to free this ever really, it should exist as long as game does + ConCommand* newCommand = new ConCommand; + ConCommandConstructor(newCommand, name, callback, helpString, flags, nullptr); +} + +void RegisterConCommand( + const char* name, FnCommandCallback_t callback, const char* helpString, int flags, FnCommandCompletionCallback completionCallback) +{ + spdlog::info("Registering ConCommand {}", name); + + // no need to free this ever really, it should exist as long as game does + ConCommand* newCommand = new ConCommand; + ConCommandConstructor(newCommand, name, callback, helpString, flags, nullptr); + newCommand->m_pCompletionCallback = completionCallback; +} + +ON_DLL_LOAD("engine.dll", ConCommand, (CModule module)) +{ + ConCommandConstructor = module.Offset(0x415F60).As<ConCommandConstructorType>(); + AddMiscConCommands(); +} diff --git a/NorthstarDedicatedTest/concommand.h b/NorthstarDLL/concommand.h index ea35ec1f..89363bc7 100644 --- a/NorthstarDedicatedTest/concommand.h +++ b/NorthstarDLL/concommand.h @@ -72,6 +72,20 @@ inline const char* CCommand::operator[](int nIndex) const return Arg(nIndex); } +//----------------------------------------------------------------------------- +// Called when a ConCommand needs to execute +//----------------------------------------------------------------------------- +typedef void (*FnCommandCallback_t)(const CCommand& command); + +#define COMMAND_COMPLETION_MAXITEMS 64 +#define COMMAND_COMPLETION_ITEM_LENGTH 128 + +//----------------------------------------------------------------------------- +// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings +//----------------------------------------------------------------------------- +typedef int (*__fastcall FnCommandCompletionCallback)( + const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); + // From r5reloaded class ConCommandBase { @@ -113,8 +127,8 @@ class ConCommand : public ConCommandBase void Init(void); bool IsCommand(void) const; - void* m_pCommandCallback {}; // 0x0040 <- starts from 0x40 since we inherit ConCommandBase. - void* m_pCompletionCallback {}; // 0x0048 <- defaults to sub_180417410 ('xor eax, eax'). + FnCommandCallback_t m_pCommandCallback {}; // 0x0040 <- starts from 0x40 since we inherit ConCommandBase. + FnCommandCompletionCallback m_pCompletionCallback {}; // 0x0048 <- defaults to sub_180417410 ('xor eax, eax'). int m_nCallbackFlags {}; // 0x0050 char pad_0054[4]; // 0x0054 int unk0; // 0x0058 @@ -122,6 +136,5 @@ class ConCommand : public ConCommandBase }; // Size: 0x0060 void RegisterConCommand(const char* name, void (*callback)(const CCommand&), const char* helpString, int flags); -void InitialiseConCommands(HMODULE baseAddress); - -#define MAKE_CONCMD(name, helpStr, flags, fn) RegisterConCommand(name, fn, helpStr, flags);
\ No newline at end of file +void RegisterConCommand( + const char* name, void (*callback)(const CCommand&), const char* helpString, int flags, FnCommandCompletionCallback completionCallback); diff --git a/NorthstarDedicatedTest/convar.cpp b/NorthstarDLL/convar.cpp index 346e7b69..c8f63922 100644 --- a/NorthstarDedicatedTest/convar.cpp +++ b/NorthstarDLL/convar.cpp @@ -2,10 +2,10 @@ #include "bits.h" #include "cvar.h" #include "convar.h" -#include "hookutils.h" -#include "gameutils.h" #include "sourceinterface.h" +#include <float.h> + typedef void (*ConVarRegisterType)( ConVar* pConVar, const char* pszName, @@ -25,25 +25,19 @@ ConVarMallocType conVarMalloc; void* g_pConVar_Vtable = nullptr; void* g_pIConVar_Vtable = nullptr; -typedef bool (*CvarIsFlagSetType)(ConVar* self, int flags); -CvarIsFlagSetType CvarIsFlagSet; - //----------------------------------------------------------------------------- // Purpose: ConVar interface initialization //----------------------------------------------------------------------------- -void InitialiseConVars(HMODULE baseAddress) +ON_DLL_LOAD("engine.dll", ConVar, (CModule module)) { - conVarMalloc = (ConVarMallocType)((char*)baseAddress + 0x415C20); - conVarRegister = (ConVarRegisterType)((char*)baseAddress + 0x417230); + conVarMalloc = module.Offset(0x415C20).As<ConVarMallocType>(); + conVarRegister = module.Offset(0x417230).As<ConVarRegisterType>(); - g_pConVar_Vtable = (char*)baseAddress + 0x67FD28; - g_pIConVar_Vtable = (char*)baseAddress + 0x67FDC8; + g_pConVar_Vtable = module.Offset(0x67FD28); + g_pIConVar_Vtable = module.Offset(0x67FDC8); - g_pCVarInterface = new SourceInterface<CCvar>("vstdlib.dll", "VEngineCvar007"); - g_pCVar = *g_pCVarInterface; - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x417FA0, &ConVar::IsFlagSet, reinterpret_cast<LPVOID*>(&CvarIsFlagSet)); + R2::g_pCVarInterface = new SourceInterface<CCvar>("vstdlib.dll", "VEngineCvar007"); + R2::g_pCVar = *R2::g_pCVarInterface; } //----------------------------------------------------------------------------- @@ -72,7 +66,7 @@ ConVar::ConVar( float fMin, bool bMax, float fMax, - void* pCallback) + FnChangeCallback_t pCallback) { spdlog::info("Registering Convar {}", pszName); @@ -474,16 +468,12 @@ bool ConVar::IsCommand(void) const //----------------------------------------------------------------------------- // Purpose: Test each ConVar query before setting the value. -// Input : *pConVar - nFlags +// Input : nFlags // Output : False if change is permitted, true if not. //----------------------------------------------------------------------------- -bool ConVar::IsFlagSet(ConVar* pConVar, int nFlags) +bool ConVar::IsFlagSet(int nFlags) const { - // unrestrict FCVAR_DEVELOPMENTONLY and FCVAR_HIDDEN - if (pConVar && (nFlags == FCVAR_DEVELOPMENTONLY || nFlags == FCVAR_HIDDEN)) - return false; - - return CvarIsFlagSet(pConVar, nFlags); + return m_ConCommandBase.m_nFlags & nFlags; } //----------------------------------------------------------------------------- diff --git a/NorthstarDedicatedTest/convar.h b/NorthstarDLL/convar.h index b1424fb7..176d0d72 100644 --- a/NorthstarDedicatedTest/convar.h +++ b/NorthstarDLL/convar.h @@ -58,15 +58,58 @@ // ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd. #define FCVAR_SERVER_CANNOT_QUERY \ (1 << 29) // If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue). + +// !!!NOTE!!! : this is likely incorrect, there are multiple concommands that the vanilla game registers with this flag that 100% should not +// be remotely executable i.e. multiple commands that only exist on client (screenshot, joystick_initialize) we now use +// FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS in all places this flag was previously used #define FCVAR_CLIENTCMD_CAN_EXECUTE \ (1 << 30) // IVEngineClient::ClientCmd is allowed to execute this command. // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command. #define FCVAR_ACCESSIBLE_FROM_THREADS (1 << 25) // used as a debugging tool necessary to check material system thread convars + +// TODO: could be cool to repurpose these for northstar use somehow? // #define FCVAR_AVAILABLE (1<<26) // #define FCVAR_AVAILABLE (1<<27) // #define FCVAR_AVAILABLE (1<<31) +// flag => string stuff +const std::multimap<int, const char*> g_PrintCommandFlags = { + {FCVAR_UNREGISTERED, "UNREGISTERED"}, + {FCVAR_DEVELOPMENTONLY, "DEVELOPMENTONLY"}, + {FCVAR_GAMEDLL, "GAMEDLL"}, + {FCVAR_CLIENTDLL, "CLIENTDLL"}, + {FCVAR_HIDDEN, "HIDDEN"}, + {FCVAR_PROTECTED, "PROTECTED"}, + {FCVAR_SPONLY, "SPONLY"}, + {FCVAR_ARCHIVE, "ARCHIVE"}, + {FCVAR_NOTIFY, "NOTIFY"}, + {FCVAR_USERINFO, "USERINFO"}, + + // TODO: PRINTABLEONLY and GAMEDLL_FOR_REMOTE_CLIENTS are both 1<<10, one is for vars and one is for commands + // this fucking sucks i think + {FCVAR_PRINTABLEONLY, "PRINTABLEONLY"}, + {FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS, "GAMEDLL_FOR_REMOTE_CLIENTS"}, + + {FCVAR_UNLOGGED, "UNLOGGED"}, + {FCVAR_NEVER_AS_STRING, "NEVER_AS_STRING"}, + {FCVAR_REPLICATED, "REPLICATED"}, + {FCVAR_CHEAT, "CHEAT"}, + {FCVAR_SS, "SS"}, + {FCVAR_DEMO, "DEMO"}, + {FCVAR_DONTRECORD, "DONTRECORD"}, + {FCVAR_SS_ADDED, "SS_ADDED"}, + {FCVAR_RELEASE, "RELEASE"}, + {FCVAR_RELOAD_MATERIALS, "RELOAD_MATERIALS"}, + {FCVAR_RELOAD_TEXTURES, "RELOAD_TEXTURES"}, + {FCVAR_NOT_CONNECTED, "NOT_CONNECTED"}, + {FCVAR_MATERIAL_SYSTEM_THREAD, "MATERIAL_SYSTEM_THREAD"}, + {FCVAR_ARCHIVE_PLAYERPROFILE, "ARCHIVE_PLAYERPROFILE"}, + {FCVAR_SERVER_CAN_EXECUTE, "SERVER_CAN_EXECUTE"}, + {FCVAR_SERVER_CANNOT_QUERY, "SERVER_CANNOT_QUERY"}, + {FCVAR_CLIENTCMD_CAN_EXECUTE, "UNKNOWN"}, + {FCVAR_ACCESSIBLE_FROM_THREADS, "ACCESSIBLE_FROM_THREADS"}}; + //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- @@ -74,6 +117,8 @@ class ConCommandBase; class ConCommand; class ConVar; +typedef void (*FnChangeCallback_t)(ConVar* var, const char* pOldValue, float flOldValue); + //----------------------------------------------------------------------------- // Purpose: A console variable //----------------------------------------------------------------------------- @@ -91,7 +136,7 @@ class ConVar float fMin, bool bMax, float fMax, - void* pCallback); + FnChangeCallback_t pCallback); ~ConVar(void); const char* GetBaseName(void) const; @@ -125,7 +170,7 @@ class ConVar bool IsRegistered(void) const; bool IsCommand(void) const; - static bool IsFlagSet(ConVar* pConVar, int nFlags); + bool IsFlagSet(int nFlags) const; struct CVValue_t { @@ -145,5 +190,3 @@ class ConVar void* m_pMalloc {}; // 0x0070 char m_pPad80[10] {}; // 0x0080 }; // Size: 0x0080 - -void InitialiseConVars(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/logging.cpp b/NorthstarDLL/crashhandler.cpp index 5936007f..8e083078 100644 --- a/NorthstarDedicatedTest/logging.cpp +++ b/NorthstarDLL/crashhandler.cpp @@ -1,35 +1,11 @@ #include "pch.h" -#include "logging.h" -#include "sourceconsole.h" -#include "spdlog/sinks/basic_file_sink.h" -#include "hookutils.h" +#include "crashhandler.h" #include "dedicated.h" -#include "convar.h" -#include <iomanip> -#include <sstream> -#include <Psapi.h> -#include <minidumpapiset.h> -#include "configurables.h" +#include "nsprefix.h" -// This needs to be called after hooks are loaded so we can access the command line args -void CreateLogFiles() -{ - if (strstr(GetCommandLineA(), "-disablelogs")) - { - spdlog::default_logger()->set_level(spdlog::level::off); - } - else - { - // todo: might be good to delete logs that are too old - time_t time = std::time(nullptr); - tm currentTime = *std::localtime(&time); - std::stringstream stream; +#include <minidumpapiset.h> - stream << std::put_time(¤tTime, (GetNorthstarPrefix() + "/logs/nslog%Y-%m-%d %H-%M-%S.txt").c_str()); - spdlog::default_logger()->sinks().push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(stream.str(), false)); - spdlog::flush_on(spdlog::level::info); - } -} +HANDLE hExceptionFilter; long __stdcall ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) { @@ -204,7 +180,7 @@ long __stdcall ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) else spdlog::error("Failed to write minidump file {}!", stream.str()); - if (!IsDedicated()) + if (!IsDedicatedServer()) MessageBoxA( 0, "Northstar has crashed! Crash info can be found in R2Northstar/logs", "Northstar has crashed!", MB_ICONERROR | MB_OK); } @@ -213,8 +189,6 @@ long __stdcall ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) return EXCEPTION_EXECUTE_HANDLER; } -HANDLE hExceptionFilter; - BOOL WINAPI ConsoleHandlerRoutine(DWORD eventCode) { switch (eventCode) @@ -222,7 +196,7 @@ BOOL WINAPI ConsoleHandlerRoutine(DWORD eventCode) case CTRL_CLOSE_EVENT: // User closed console, shut everything down spdlog::info("Exiting due to console close..."); - RemoveVectoredExceptionHandler(hExceptionFilter); + RemoveCrashHandler(); exit(EXIT_SUCCESS); return FALSE; } @@ -230,258 +204,13 @@ BOOL WINAPI ConsoleHandlerRoutine(DWORD eventCode) return TRUE; } -void InitialiseLogging() +void InitialiseCrashHandler() { hExceptionFilter = AddVectoredExceptionHandler(TRUE, ExceptionFilter); - - AllocConsole(); - freopen("CONOUT$", "w", stdout); - freopen("CONOUT$", "w", stderr); - spdlog::default_logger()->set_pattern("[%H:%M:%S] [%l] %v"); - SetConsoleCtrlHandler(ConsoleHandlerRoutine, true); } -ConVar* Cvar_spewlog_enable; - -enum SpewType_t -{ - SPEW_MESSAGE = 0, - - SPEW_WARNING, - SPEW_ASSERT, - SPEW_ERROR, - SPEW_LOG, - - SPEW_TYPE_COUNT -}; - -typedef void (*EngineSpewFuncType)(); -EngineSpewFuncType EngineSpewFunc; - -void EngineSpewFuncHook(void* engineServer, SpewType_t type, const char* format, va_list args) +void RemoveCrashHandler() { - if (!Cvar_spewlog_enable->GetBool()) - return; - - const char* typeStr; - switch (type) - { - case SPEW_MESSAGE: - { - typeStr = "SPEW_MESSAGE"; - break; - } - - case SPEW_WARNING: - { - typeStr = "SPEW_WARNING"; - break; - } - - case SPEW_ASSERT: - { - typeStr = "SPEW_ASSERT"; - break; - } - - case SPEW_ERROR: - { - typeStr = "SPEW_ERROR"; - break; - } - - case SPEW_LOG: - { - typeStr = "SPEW_LOG"; - break; - } - - default: - { - typeStr = "SPEW_UNKNOWN"; - break; - } - } - - char formatted[2048] = {0}; - bool shouldFormat = true; - - // because titanfall 2 is quite possibly the worst thing to yet exist, it sometimes gives invalid specifiers which will crash - // ttf2sdk had a way to prevent them from crashing but it doesnt work in debug builds - // so we use this instead - for (int i = 0; format[i]; i++) - { - if (format[i] == '%') - { - switch (format[i + 1]) - { - // this is fucking awful lol - case 'd': - case 'i': - case 'u': - case 'x': - case 'X': - case 'f': - case 'F': - case 'g': - case 'G': - case 'a': - case 'A': - case 'c': - case 's': - case 'p': - case 'n': - case '%': - case '-': - case '+': - case ' ': - case '#': - case '*': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - - default: - { - shouldFormat = false; - break; - } - } - } - } - - if (shouldFormat) - vsnprintf(formatted, sizeof(formatted), format, args); - else - { - spdlog::warn("Failed to format {} \"{}\"", typeStr, format); - } - - auto endpos = strlen(formatted); - if (formatted[endpos - 1] == '\n') - formatted[endpos - 1] = '\0'; // cut off repeated newline - - spdlog::info("[SERVER {}] {}", typeStr, formatted); -} - -typedef void (*Status_ConMsg_Type)(const char* text, ...); -Status_ConMsg_Type Status_ConMsg_Original; - -void Status_ConMsg_Hook(const char* text, ...) -{ - char formatted[2048]; - va_list list; - - va_start(list, text); - vsprintf_s(formatted, text, list); - va_end(list); - - auto endpos = strlen(formatted); - if (formatted[endpos - 1] == '\n') - formatted[endpos - 1] = '\0'; // cut off repeated newline - - spdlog::info(formatted); -} - -typedef bool (*CClientState_ProcessPrint_Type)(__int64 thisptr, __int64 msg); -CClientState_ProcessPrint_Type CClientState_ProcessPrint_Original; - -bool CClientState_ProcessPrint_Hook(__int64 thisptr, __int64 msg) -{ - char* text = *(char**)(msg + 0x20); - - auto endpos = strlen(text); - if (text[endpos - 1] == '\n') - text[endpos - 1] = '\0'; // cut off repeated newline - - spdlog::info(text); - return true; -} - -void InitialiseEngineSpewFuncHooks(HMODULE baseAddress) -{ - HookEnabler hook; - - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x11CA80, EngineSpewFuncHook, reinterpret_cast<LPVOID*>(&EngineSpewFunc)); - - // Hook print function that status concmd uses to actually print data - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x15ABD0, Status_ConMsg_Hook, reinterpret_cast<LPVOID*>(&Status_ConMsg_Original)); - - // Hook CClientState::ProcessPrint - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x1A1530, - CClientState_ProcessPrint_Hook, - reinterpret_cast<LPVOID*>(&CClientState_ProcessPrint_Original)); - - Cvar_spewlog_enable = new ConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged"); + RemoveVectoredExceptionHandler(hExceptionFilter); } - -#include "bitbuf.h" - -ConVar* Cvar_cl_showtextmsg; - -typedef void (*TextMsg_Type)(__int64); -TextMsg_Type TextMsg_Original; - -class ICenterPrint -{ - public: - virtual void ctor() = 0; - virtual void Clear(void) = 0; - virtual void ColorPrint(int r, int g, int b, int a, wchar_t* text) = 0; - virtual void ColorPrint(int r, int g, int b, int a, char* text) = 0; - virtual void Print(wchar_t* text) = 0; - virtual void Print(char* text) = 0; - virtual void SetTextColor(int r, int g, int b, int a) = 0; -}; - -ICenterPrint* internalCenterPrint = NULL; - -void TextMsgHook(BFRead* msg) -{ - int msg_dest = msg->ReadByte(); - - char text[256]; - msg->ReadString(text, sizeof(text)); - - if (!Cvar_cl_showtextmsg->GetBool()) - return; - - switch (msg_dest) - { - case 4: // HUD_PRINTCENTER - internalCenterPrint->Print(text); - break; - default: - spdlog::warn("Unimplemented TextMsg type {}! printing to console", msg_dest); - [[fallthrough]]; - case 2: // HUD_PRINTCONSOLE - auto endpos = strlen(text); - if (text[endpos - 1] == '\n') - text[endpos - 1] = '\0'; // cut off repeated newline - spdlog::info(text); - break; - } -} - -void InitialiseClientPrintHooks(HMODULE baseAddress) -{ - HookEnabler hook; - - internalCenterPrint = (ICenterPrint*)((char*)baseAddress + 0x216E940); - - // "TextMsg" usermessage - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x198710, TextMsgHook, reinterpret_cast<LPVOID*>(&TextMsg_Original)); - - Cvar_cl_showtextmsg = new ConVar("cl_showtextmsg", "1", FCVAR_NONE, "Enable/disable text messages printing on the screen."); -}
\ No newline at end of file diff --git a/NorthstarDLL/crashhandler.h b/NorthstarDLL/crashhandler.h new file mode 100644 index 00000000..e0dc6906 --- /dev/null +++ b/NorthstarDLL/crashhandler.h @@ -0,0 +1,4 @@ +#pragma once + +void InitialiseCrashHandler(); +void RemoveCrashHandler(); diff --git a/NorthstarDedicatedTest/cvar.cpp b/NorthstarDLL/cvar.cpp index 23d767fd..787790be 100644 --- a/NorthstarDedicatedTest/cvar.cpp +++ b/NorthstarDLL/cvar.cpp @@ -23,5 +23,9 @@ std::unordered_map<std::string, ConCommandBase*> CCvar::DumpToMap() return allConVars; } -SourceInterface<CCvar>* g_pCVarInterface; -CCvar* g_pCVar;
\ No newline at end of file +// use the R2 namespace for game funcs +namespace R2 +{ + SourceInterface<CCvar>* g_pCVarInterface; + CCvar* g_pCVar; +} // namespace R2 diff --git a/NorthstarDedicatedTest/cvar.h b/NorthstarDLL/cvar.h index c4525cef..e65e5145 100644 --- a/NorthstarDedicatedTest/cvar.h +++ b/NorthstarDLL/cvar.h @@ -35,5 +35,9 @@ class CCvar std::unordered_map<std::string, ConCommandBase*> DumpToMap(); }; -extern SourceInterface<CCvar>* g_pCVarInterface; -extern CCvar* g_pCVar;
\ No newline at end of file +// use the R2 namespace for game funcs +namespace R2 +{ + extern SourceInterface<CCvar>* g_pCVarInterface; + extern CCvar* g_pCVar; +} // namespace R2 diff --git a/NorthstarDedicatedTest/debugoverlay.cpp b/NorthstarDLL/debugoverlay.cpp index e29da96b..ef456867 100644 --- a/NorthstarDedicatedTest/debugoverlay.cpp +++ b/NorthstarDLL/debugoverlay.cpp @@ -1,17 +1,9 @@ #include "pch.h" -#include "debugoverlay.h" #include "dedicated.h" #include "cvar.h" +#include "vector.h" -struct Vector3 -{ - float x, y, z; -}; - -struct QAngle -{ - float x, y, z, w; -}; +AUTOHOOK_INIT() enum OverlayType_t { @@ -40,7 +32,7 @@ struct OverlayBase_t int m_nServerCount; // Latch server count, too float m_flEndTime; // When does this box go away OverlayBase_t* m_pNextOverlay; - __int64 m_pUnk; + void* m_pUnk; }; struct OverlayLine_t : public OverlayBase_t @@ -76,37 +68,18 @@ struct OverlayBox_t : public OverlayBase_t int a; }; -// this is in cvar.h, don't need it here -/*class Color -{ - public: - Color(int r, int g, int b, int a) - { - _color[0] = (unsigned char)r; - _color[1] = (unsigned char)g; - _color[2] = (unsigned char)b; - _color[3] = (unsigned char)a; - } - - private: - unsigned char _color[4]; -};*/ - static HMODULE sEngineModule; -typedef void (*DrawOverlayType)(OverlayBase_t* a1); -DrawOverlayType DrawOverlay; - typedef void (*RenderLineType)(Vector3 v1, Vector3 v2, Color c, bool bZBuffer); static RenderLineType RenderLine; - typedef void (*RenderBoxType)(Vector3 vOrigin, QAngle angles, Vector3 vMins, Vector3 vMaxs, Color c, bool bZBuffer, bool bInsideOut); static RenderBoxType RenderBox; - static RenderBoxType RenderWireframeBox; -// engine.dll+0xABCB0 -void __fastcall DrawOverlayHook(OverlayBase_t* pOverlay) +// clang-format off +AUTOHOOK(DrawOverlay, engine.dll + 0xABCB0, +void, __fastcall, (OverlayBase_t * pOverlay)) +// clang-format on { EnterCriticalSection((LPCRITICAL_SECTION)((char*)sEngineModule + 0x10DB0A38)); // s_OverlayMutex @@ -151,25 +124,18 @@ void __fastcall DrawOverlayHook(OverlayBase_t* pOverlay) LeaveCriticalSection((LPCRITICAL_SECTION)((char*)sEngineModule + 0x10DB0A38)); } -void InitialiseDebugOverlay(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", DebugOverlay, ConVar, (CModule module)) { - if (IsDedicated()) - return; - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xABCB0, &DrawOverlayHook, reinterpret_cast<LPVOID*>(&DrawOverlay)); + AUTOHOOK_DISPATCH() - RenderLine = reinterpret_cast<RenderLineType>((char*)baseAddress + 0x192A70); - - RenderBox = reinterpret_cast<RenderBoxType>((char*)baseAddress + 0x192520); - - RenderWireframeBox = reinterpret_cast<RenderBoxType>((char*)baseAddress + 0x193DA0); - - sEngineModule = baseAddress; + RenderLine = module.Offset(0x192A70).As<RenderLineType>(); + RenderBox = module.Offset(0x192520).As<RenderBoxType>(); + RenderWireframeBox = module.Offset(0x193DA0).As<RenderBoxType>(); + sEngineModule = reinterpret_cast<HMODULE>(module.m_nAddress); // not in g_pCVar->FindVar by this point for whatever reason, so have to get from memory - ConVar* Cvar_enable_debug_overlays = (ConVar*)((char*)baseAddress + 0x10DB0990); + ConVar* Cvar_enable_debug_overlays = module.Offset(0x10DB0990).As<ConVar*>(); Cvar_enable_debug_overlays->SetValue(false); Cvar_enable_debug_overlays->m_pszDefaultValue = (char*)"0"; Cvar_enable_debug_overlays->AddFlags(FCVAR_CHEAT); -}
\ No newline at end of file +} diff --git a/NorthstarDLL/dedicated.cpp b/NorthstarDLL/dedicated.cpp new file mode 100644 index 00000000..251e2437 --- /dev/null +++ b/NorthstarDLL/dedicated.cpp @@ -0,0 +1,293 @@ +#include "pch.h" +#include "dedicated.h" +#include "tier0.h" +#include "playlist.h" +#include "r2engine.h" +#include "hoststate.h" +#include "serverauthentication.h" +#include "masterserver.h" +#include "printcommand.h" + +AUTOHOOK_INIT() + +using namespace R2; + +bool IsDedicatedServer() +{ + static bool result = strstr(GetCommandLineA(), "-dedicated"); + return result; +} + +// CDedidcatedExports defs +struct CDedicatedExports; // forward declare + +typedef void (*DedicatedSys_PrintfType)(CDedicatedExports* dedicated, const char* msg); +typedef void (*DedicatedRunServerType)(CDedicatedExports* dedicated); + +// would've liked to just do this as a class but have not been able to get it to work +struct CDedicatedExports +{ + void* vtable; // because it's easier, we just set this to &this, since CDedicatedExports has no props we care about other than funcs + + char unused[56]; + + DedicatedSys_PrintfType Sys_Printf; + DedicatedRunServerType RunServer; +}; + +void Sys_Printf(CDedicatedExports* dedicated, const char* msg) +{ + spdlog::info("[DEDICATED SERVER] {}", msg); +} + +void RunServer(CDedicatedExports* dedicated) +{ + spdlog::info("CDedicatedExports::RunServer(): starting"); + spdlog::info(Tier0::CommandLine()->GetCmdLine()); + + // initialise engine + g_pEngine->Frame(); + + // add +map if not present + // don't manually execute this from cbuf as users may have it in their startup args anyway, easier just to run from stuffcmds if present + if (!Tier0::CommandLine()->CheckParm("+map")) + Tier0::CommandLine()->AppendParm("+map", g_pCVar->FindVar("match_defaultMap")->GetString()); + + // re-run commandline + Cbuf_AddText(Cbuf_GetCurrentPlayer(), "stuffcmds", cmd_source_t::kCommandSrcCode); + Cbuf_Execute(); + + // get tickinterval + ConVar* Cvar_base_tickinterval_mp = g_pCVar->FindVar("base_tickinterval_mp"); + + // main loop + double frameTitle = 0; + while (g_pEngine->m_nQuitting == EngineQuitState::QUIT_NOTQUITTING) + { + double frameStart = Tier0::Plat_FloatTime(); + g_pEngine->Frame(); + + std::this_thread::sleep_for(std::chrono::duration<double, std::ratio<1>>( + Cvar_base_tickinterval_mp->GetFloat() - fmin(Tier0::Plat_FloatTime() - frameStart, 0.25))); + } +} + +// use server presence to update window title +class DedicatedConsoleServerPresence : public ServerPresenceReporter +{ + void ReportPresence(const ServerPresence* pServerPresence) override + { + SetConsoleTitleA(fmt::format( + "{} - {} {}/{} players ({})", + pServerPresence->m_sServerName, + pServerPresence->m_MapName, + pServerPresence->m_iPlayerCount, + pServerPresence->m_iMaxPlayers, + pServerPresence->m_PlaylistName) + .c_str()); + } +}; + +HANDLE consoleInputThreadHandle = NULL; +DWORD WINAPI ConsoleInputThread(PVOID pThreadParameter) +{ + while (!g_pEngine || !g_pHostState || g_pHostState->m_iCurrentState != HostState_t::HS_RUN) + Sleep(1000); + + // Bind stdin to receive console input. + FILE* fp = nullptr; + freopen_s(&fp, "CONIN$", "r", stdin); + + spdlog::info("Ready to receive console commands."); + + { + // Process console input + std::string input; + while (g_pEngine && g_pEngine->m_nQuitting == EngineQuitState::QUIT_NOTQUITTING && std::getline(std::cin, input)) + { + input += "\n"; + Cbuf_AddText(Cbuf_GetCurrentPlayer(), input.c_str(), cmd_source_t::kCommandSrcCode); + TryPrintCvarHelpForCommand(input.c_str()); // this needs to be done on main thread, unstable in this one + } + } + + return 0; +} + +// clang-format off +AUTOHOOK(IsGameActiveWindow, engine.dll + 0x1CDC80, +bool,, ()) +// clang-format on +{ + return true; +} + +ON_DLL_LOAD_DEDI_RELIESON("engine.dll", DedicatedServer, ServerPresence, (CModule module)) +{ + spdlog::info("InitialiseDedicated"); + + AUTOHOOK_DISPATCH_MODULE("engine.dll") + + // Host_Init + // prevent a particle init that relies on client dll + module.Offset(0x156799).NOP(5); + + // Host_Init + // don't call Key_Init to avoid loading some extra rsons from rpak (will be necessary to boot if we ever wanna disable rpaks entirely on + // dedi) + module.Offset(0x1565B0).NOP(5); + + { + // CModAppSystemGroup::Create + // force the engine into dedicated mode by changing the first comparison to IsServerOnly to an assignment + MemoryAddress base = module.Offset(0x1C4EBD); + + // cmp => mov + base.Offset(1).Patch("C6 87"); + + // 00 => 01 + base.Offset(7).Patch("01"); + } + + // Some init that i'm not sure of that crashes + // nop the call to it + module.Offset(0x156A63).NOP(5); + + // runframeserver + // nop some access violations + module.Offset(0x159819).NOP(17); + + module.Offset(0x156B4C).NOP(7); + + // previously patched these, took me a couple weeks to figure out they were the issue + // removing these will mess up register state when this function is over, so we'll write HS_RUN to the wrong address + // so uhh, don't do that + // NSMem::NOP(ea + 0x156B4C + 7, 8); + module.Offset(0x156B4C).Offset(15).NOP(9); + + // HostState_State_NewGame + // nop an access violation + module.Offset(0xB934C).NOP(9); + + // CEngineAPI::Connect + // remove call to Shader_Connect + module.Offset(0x1C4D7D).NOP(5); + + // Host_Init + // remove call to ui loading stuff + module.Offset(0x156595).NOP(5); + + // some function that gets called from RunFrameServer + // nop a function that makes requests to stryder, this will eventually access violation if left alone and isn't necessary anyway + module.Offset(0x15A0BB).NOP(5); + + // RunFrameServer + // nop a function that access violations + module.Offset(0x159BF3).NOP(5); + + // func that checks if origin is inited + // always return 1 + module.Offset(0x183B70).Patch("B0 01 C3"); // mov al,01 ret + + // HostState_State_ChangeLevel + // nop clientinterface call + module.Offset(0x1552ED).NOP(16); + + // HostState_State_ChangeLevel + // nop clientinterface call + module.Offset(0x155363).NOP(16); + + // IVideoMode::CreateGameWindow + // nop call to ShowWindow + module.Offset(0x1CD146).NOP(5); + + CDedicatedExports* dedicatedExports = new CDedicatedExports; + dedicatedExports->vtable = dedicatedExports; + dedicatedExports->Sys_Printf = Sys_Printf; + dedicatedExports->RunServer = RunServer; + + *module.Offset(0x13F0B668).As<CDedicatedExports**>() = dedicatedExports; + + // extra potential patches: + // nop engine.dll+1c67d1 and +1c67d8 to skip videomode creategamewindow + // also look into launcher.dll+d381, seems to cause renderthread to get made + // this crashes HARD if no window which makes sense tbh + // also look into materialsystem + 5B344 since it seems to be the base of all the renderthread stuff + + // big note: datatable gets registered in window creation + // make sure it still gets registered + + // add cmdline args that are good for dedi + Tier0::CommandLine()->AppendParm("-nomenuvid", 0); + Tier0::CommandLine()->AppendParm("-nosound", 0); + Tier0::CommandLine()->AppendParm("-windowed", 0); + Tier0::CommandLine()->AppendParm("-nomessagebox", 0); + Tier0::CommandLine()->AppendParm("+host_preload_shaders", "0"); + Tier0::CommandLine()->AppendParm("+net_usesocketsforloopback", "1"); + + // use presence reporter for console title + DedicatedConsoleServerPresence* presenceReporter = new DedicatedConsoleServerPresence; + g_pServerPresence->AddPresenceReporter(presenceReporter); + + // Disable Quick Edit mode to reduce chance of user unintentionally hanging their server by selecting something. + if (!Tier0::CommandLine()->CheckParm("-bringbackquickedit")) + { + HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + + if (GetConsoleMode(stdIn, &mode)) + { + if (mode & ENABLE_QUICK_EDIT_MODE) + { + mode &= ~ENABLE_QUICK_EDIT_MODE; + mode &= ~ENABLE_MOUSE_INPUT; + + mode |= ENABLE_PROCESSED_INPUT; + + SetConsoleMode(stdIn, mode); + } + } + } + else + spdlog::info("Quick Edit enabled by user request"); + + // create console input thread + if (!Tier0::CommandLine()->CheckParm("-noconsoleinput")) + consoleInputThreadHandle = CreateThread(0, 0, ConsoleInputThread, 0, 0, NULL); + else + spdlog::info("Console input disabled by user request"); +} + +ON_DLL_LOAD_DEDI("tier0.dll", DedicatedServerOrigin, (CModule module)) +{ + // disable origin on dedicated + // for any big ea lawyers, this can't be used to play the game without origin, game will throw a fit if you try to do anything without + // an origin id as a client for dedi it's fine though, game doesn't care if origin is disabled as long as there's only a server + module.GetExport("Tier0_InitOrigin").Patch("C3"); +} + +// clang-format off +AUTOHOOK(PrintSquirrelError, server.dll + 0x794D0, +void, __fastcall, (void* sqvm)) +// clang-format on +{ + PrintSquirrelError(sqvm); + + // close dedicated server if a fatal error is hit + static ConVar* Cvar_fatal_script_errors = g_pCVar->FindVar("fatal_script_errors"); + if (Cvar_fatal_script_errors->GetBool()) + abort(); +} + +ON_DLL_LOAD_DEDI("server.dll", DedicatedServerGameDLL, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(server.dll) + + if (Tier0::CommandLine()->CheckParm("-nopakdedi")) + { + module.Offset(0x6BA350).Patch("C3"); // dont load skins.rson from rpak if we don't have rpaks, as loading it will cause a crash + module.Offset(0x6BA300).Patch( + "B8 C8 00 00 00 C3"); // return 200 as the number of skins from server.dll + 6BA300, this is the normal value read from + // skins.rson and should be updated when we need it more modular + } +} diff --git a/NorthstarDLL/dedicated.h b/NorthstarDLL/dedicated.h new file mode 100644 index 00000000..82806763 --- /dev/null +++ b/NorthstarDLL/dedicated.h @@ -0,0 +1,3 @@ +#pragma once + +bool IsDedicatedServer(); diff --git a/NorthstarDLL/dedicatedmaterialsystem.cpp b/NorthstarDLL/dedicatedmaterialsystem.cpp new file mode 100644 index 00000000..28ee9b76 --- /dev/null +++ b/NorthstarDLL/dedicatedmaterialsystem.cpp @@ -0,0 +1,41 @@ +#include "pch.h" +#include "dedicated.h" +#include "tier0.h" + +AUTOHOOK_INIT() + +// clang-format off +AUTOHOOK(D3D11CreateDevice, materialsystem_dx11.dll + 0xD9A0E, +HRESULT, __stdcall, ( + void* pAdapter, + int DriverType, + HMODULE Software, + UINT Flags, + int* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + void** ppDevice, + int* pFeatureLevel, + void** ppImmediateContext)) +// clang-format on +{ + // note: this is super duper temp pretty much just messing around with it + // does run surprisingly well on dedi for a software driver tho if you ignore the +1gb ram usage at times, seems like dedi doesn't + // really call gpu much even with renderthread still being a thing will be using this hook for actual d3d stubbing and stuff later + + // note: this has been succeeded by the d3d11 and gfsdk stubs, and is only being kept around for posterity and as a fallback option + if (Tier0::CommandLine()->CheckParm("-softwared3d11")) + DriverType = 5; // D3D_DRIVER_TYPE_WARP + + return D3D11CreateDevice( + pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext); +} + +ON_DLL_LOAD_DEDI("materialsystem_dx11.dll", DedicatedServerMaterialSystem, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + // CMaterialSystem::FindMaterial + // make the game always use the error material + module.Offset(0x5F0F1).Patch("E9 34 03 00"); +} diff --git a/NorthstarDLL/demofixes.cpp b/NorthstarDLL/demofixes.cpp new file mode 100644 index 00000000..ab092484 --- /dev/null +++ b/NorthstarDLL/demofixes.cpp @@ -0,0 +1,26 @@ +#include "pch.h" +#include "convar.h" + +ON_DLL_LOAD_CLIENT("engine.dll", EngineDemoFixes, (CModule module)) +{ + // allow demo recording on loopback + module.Offset(0x8E1B1).NOP(2); + module.Offset(0x56CC3).NOP(2); +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientDemoFixes, ConVar, (CModule module)) +{ + // change default values of demo cvars to enable them by default, but not autorecord + // this is before Host_Init, the setvalue calls here will get overwritten by custom cfgs/launch options + ConVar* Cvar_demo_enableDemos = R2::g_pCVar->FindVar("demo_enabledemos"); + Cvar_demo_enableDemos->m_pszDefaultValue = "1"; + Cvar_demo_enableDemos->SetValue(true); + + ConVar* Cvar_demo_writeLocalFile = R2::g_pCVar->FindVar("demo_writeLocalFile"); + Cvar_demo_writeLocalFile->m_pszDefaultValue = "1"; + Cvar_demo_writeLocalFile->SetValue(true); + + ConVar* Cvar_demo_autoRecord = R2::g_pCVar->FindVar("demo_autoRecord"); + Cvar_demo_autoRecord->m_pszDefaultValue = "0"; + Cvar_demo_autoRecord->SetValue(false); +} diff --git a/NorthstarDLL/dllmain.cpp b/NorthstarDLL/dllmain.cpp new file mode 100644 index 00000000..8d78ee2c --- /dev/null +++ b/NorthstarDLL/dllmain.cpp @@ -0,0 +1,168 @@ +#include "pch.h" +#include "main.h" +#include "logging.h" +#include "crashhandler.h" +#include "memalloc.h" +#include "nsprefix.h" +#include "plugin_abi.h" +#include "plugins.h" +#include "version.h" +#include "pch.h" + +#include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" +#include "rapidjson/error/en.h" + +#include <string.h> +#include <filesystem> + +typedef void (*initPluginFuncPtr)(void* (*getPluginObject)(PluginObject)); + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +void freeLibrary(HMODULE hLib) +{ + if (!FreeLibrary(hLib)) + { + spdlog::error("There was an error while trying to free library"); + } +} + +bool LoadPlugins() +{ + + std::vector<fs::path> paths; + + std::string pluginPath = GetNorthstarPrefix() + "/plugins"; + if (!fs::exists(pluginPath)) + { + spdlog::warn("Could not find a plugins directory. Skipped loading plugins"); + return false; + } + // ensure dirs exist + fs::recursive_directory_iterator iterator(pluginPath); + if (std::filesystem::begin(iterator) == std::filesystem::end(iterator)) + { + spdlog::warn("Could not find any plugins. Skipped loading plugins"); + return false; + } + for (auto const& entry : iterator) + { + if (fs::is_regular_file(entry) && entry.path().extension() == ".dll") + paths.emplace_back(entry.path().filename()); + } + initGameState(); + for (fs::path path : paths) + { + std::string pathstring = (pluginPath / path).string(); + std::wstring wpath = (pluginPath / path).wstring(); + + LPCWSTR wpptr = wpath.c_str(); + HMODULE datafile = + LoadLibraryExW(wpptr, 0, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); // Load the DLL as a data file + if (datafile == NULL) + { + spdlog::info("Failed to load library {}: ", std::system_category().message(GetLastError())); + continue; + } + HRSRC manifestResource = FindResourceW(datafile, MAKEINTRESOURCEW(101), MAKEINTRESOURCEW(RT_RCDATA)); + + if (manifestResource == NULL) + { + spdlog::info("Could not find manifest for library {}", pathstring); + freeLibrary(datafile); + continue; + } + spdlog::info("Loading resource from library"); + HGLOBAL myResourceData = LoadResource(datafile, manifestResource); + if (myResourceData == NULL) + { + spdlog::error("Failed to load resource from library"); + freeLibrary(datafile); + continue; + } + int manifestSize = SizeofResource(datafile, manifestResource); + std::string manifest = std::string((const char*)LockResource(myResourceData), 0, manifestSize); + freeLibrary(datafile); + + rapidjson_document manifestJSON; + manifestJSON.Parse(manifest.c_str()); + + if (manifestJSON.HasParseError()) + { + spdlog::error("Manifest for {} was invalid", pathstring); + continue; + } + if (!manifestJSON.HasMember("api_version")) + { + spdlog::error("{} does not have a version number in its manifest", pathstring); + continue; + // spdlog::info(manifestJSON["version"].GetString()); + } + if (strcmp(manifestJSON["api_version"].GetString(), std::to_string(ABI_VERSION).c_str())) + { + spdlog::error("{} has an incompatible API version number in its manifest", pathstring); + continue; + } + // Passed all checks, going to actually load it now + + HMODULE pluginLib = LoadLibraryW(wpptr); // Load the DLL as a data file + if (pluginLib == NULL) + { + spdlog::info("Failed to load library {}: ", std::system_category().message(GetLastError())); + continue; + } + initPluginFuncPtr initPlugin = (initPluginFuncPtr)GetProcAddress(pluginLib, "initializePlugin"); + if (initPlugin == NULL) + { + spdlog::info("Library {} has no function initializePlugin", pathstring); + continue; + } + spdlog::info("Succesfully loaded {}", pathstring); + initPlugin(&getPluginObject); + } + return true; +} + +bool InitialiseNorthstar() +{ + static bool bInitialised = false; + if (bInitialised) + return false; + + bInitialised = true; + + InitialiseNorthstarPrefix(); + InitialiseVersion(); + + // Fix some users' failure to connect to respawn datacenters + SetEnvironmentVariableA("OPENSSL_ia32cap", "~0x200000200000000"); + + curl_global_init_mem(CURL_GLOBAL_DEFAULT, _malloc_base, _free_base, _realloc_base, _strdup_base, _calloc_base); + + InitialiseCrashHandler(); + InitialiseLogging(); + InstallInitialHooks(); + CreateLogFiles(); + + // Write launcher version to log + spdlog::info("NorthstarLauncher version: {}", version); + + // run callbacks for any libraries that are already loaded by now + CallAllPendingDLLLoadCallbacks(); + + return true; +} diff --git a/NorthstarDLL/exploitfixes.cpp b/NorthstarDLL/exploitfixes.cpp new file mode 100644 index 00000000..de60a854 --- /dev/null +++ b/NorthstarDLL/exploitfixes.cpp @@ -0,0 +1,449 @@ +#include "pch.h" +#include "cvar.h" +#include "limits.h" +#include "dedicated.h" +#include "tier0.h" +#include "r2engine.h" +#include "r2client.h" +#include "vector.h" + +AUTOHOOK_INIT() + +ConVar* Cvar_ns_exploitfixes_log; +ConVar* Cvar_ns_should_log_all_clientcommands; + +ConVar* Cvar_sv_cheats; + +#define BLOCKED_INFO(s) \ + ( \ + [=]() -> bool \ + { \ + if (Cvar_ns_exploitfixes_log->GetBool()) \ + { \ + std::stringstream stream; \ + stream << "ExploitFixes.cpp: " << BLOCK_PREFIX << s; \ + spdlog::error(stream.str()); \ + } \ + return false; \ + }()) + +// block bad netmessages +// Servers can literally request a screenshot from any client, yeah no +// clang-format off +AUTOHOOK(CLC_Screenshot_WriteToBuffer, engine.dll + 0x22AF20, +bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 57 48 83 EC 20 8B 42 10 +// clang-format on +{ + return false; +} + +// clang-format off +AUTOHOOK(CLC_Screenshot_ReadFromBuffer, engine.dll + 0x221F00, +bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B DA 48 8B 52 38 +// clang-format on +{ + return false; +} + +// This is unused ingame and a big client=>server=>client exploit vector +// clang-format off +AUTOHOOK(Base_CmdKeyValues_ReadFromBuffer, engine.dll + 0x220040, +bool, __fastcall, (void* thisptr, void* buffer)) // 40 55 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 5D 70 +// clang-format on +{ + return false; +} + +// clang-format off +AUTOHOOK(CClient_ProcessSetConVar, engine.dll + 0x75CF0, +bool, __fastcall, (void* pMsg)) // 48 8B D1 48 8B 49 18 48 8B 01 48 FF 60 10 +// clang-format on +{ + + constexpr int ENTRY_STR_LEN = 260; + struct SetConVarEntry + { + char name[ENTRY_STR_LEN]; + char val[ENTRY_STR_LEN]; + }; + + struct NET_SetConVar + { + void* vtable; + void* unk1; + void* unk2; + void* m_pMessageHandler; + SetConVarEntry* m_ConVars; // convar entry array + void* unk5; // these 2 unks are just vector capacity or whatever + void* unk6; + int m_ConVars_count; // amount of cvar entries in array (this will not be out of bounds) + }; + + auto msg = (NET_SetConVar*)pMsg; + bool bIsServerFrame = Tier0::ThreadInServerFrameThread(); + + std::string BLOCK_PREFIX = + std::string {"NET_SetConVar ("} + (bIsServerFrame ? "server" : "client") + "): Blocked dangerous/invalid msg: "; + + if (bIsServerFrame) + { + constexpr int SETCONVAR_SANITY_AMOUNT_LIMIT = 69; + if (msg->m_ConVars_count < 1 || msg->m_ConVars_count > SETCONVAR_SANITY_AMOUNT_LIMIT) + { + return BLOCKED_INFO("Invalid m_ConVars_count (" << msg->m_ConVars_count << ")"); + } + } + + for (int i = 0; i < msg->m_ConVars_count; i++) + { + auto entry = msg->m_ConVars + i; + + // Safety check for memory access + if (MemoryAddress(entry).IsMemoryReadable(sizeof(*entry))) + { + // Find null terminators + bool nameValid = false, valValid = false; + for (int i = 0; i < ENTRY_STR_LEN; i++) + { + if (!entry->name[i]) + nameValid = true; + if (!entry->val[i]) + valValid = true; + } + + if (!nameValid || !valValid) + return BLOCKED_INFO("Missing null terminators"); + + auto realVar = R2::g_pCVar->FindVar(entry->name); + + if (realVar) + memcpy( + entry->name, + realVar->m_ConCommandBase.m_pszName, + strlen(realVar->m_ConCommandBase.m_pszName) + 1); // Force name to match case + + bool isValidFlags = true; + if (bIsServerFrame) + { + if (realVar) + isValidFlags = realVar->IsFlagSet(FCVAR_USERINFO); // ConVar MUST be userinfo var + } + else + { + // TODO: Should probably have some sanity checks, but can't find any that are consistent + } + + if (!isValidFlags) + { + if (!realVar) + { + return BLOCKED_INFO("Invalid flags on nonexistant cvar (how tho???)"); + } + else + { + return BLOCKED_INFO( + "Invalid flags (" << std::hex << "0x" << realVar->m_ConCommandBase.m_nFlags << "), var is " << entry->name); + } + } + } + else + { + return BLOCKED_INFO("Unreadable memory at " << (void*)entry); // Not risking that one, they all gotta be readable + } + } + + return CClient_ProcessSetConVar(msg); +} + +// prevent invalid user CMDs +// clang-format off +AUTOHOOK(CClient_ProcessUsercmds, engine.dll + 0x1040F0, +bool, __fastcall, (void* thisptr, void* pMsg)) // 40 55 56 48 83 EC 58 +// clang-format on +{ + struct CLC_Move + { + BYTE gap0[24]; + void* m_pMessageHandler; + int m_nBackupCommands; + int m_nNewCommands; + int m_nLength; + // bf_read m_DataIn; + // bf_write m_DataOut; + }; + + auto msg = (CLC_Move*)pMsg; + + const char* BLOCK_PREFIX = "ProcessUserCmds: "; + + if (msg->m_nBackupCommands < 0) + { + return BLOCKED_INFO("Invalid m_nBackupCommands (" << msg->m_nBackupCommands << ")"); + } + + if (msg->m_nNewCommands < 0) + { + return BLOCKED_INFO("Invalid m_nNewCommands (" << msg->m_nNewCommands << ")"); + } + + if (msg->m_nLength <= 0) + return BLOCKED_INFO("Invalid message length (" << msg->m_nLength << ")"); + + return CClient_ProcessUsercmds(thisptr, pMsg); +} + +// clang-format off +AUTOHOOK(ReadUsercmd, server.dll + 0x2603F0, +void, __fastcall, (void* buf, void* pCmd_move, void* pCmd_from)) // 4C 89 44 24 ? 53 55 56 57 +// clang-format on +{ + // Let normal usercmd read happen first, it's safe + ReadUsercmd(buf, pCmd_move, pCmd_from); + + // Now let's make sure the CMD we read isnt messed up to prevent numerous exploits (including server crashing) + struct alignas(4) SV_CUserCmd + { + DWORD command_number; + DWORD tick_count; + float command_time; + Vector3 worldViewAngles; + BYTE gap18[4]; + Vector3 localViewAngles; + Vector3 attackangles; + Vector3 move; + DWORD buttons; + BYTE impulse; + short weaponselect; + DWORD meleetarget; + BYTE gap4C[24]; + char headoffset; + BYTE gap65[11]; + Vector3 cameraPos; + Vector3 cameraAngles; + BYTE gap88[4]; + int tickSomething; + DWORD dword90; + DWORD predictedServerEventAck; + DWORD dword98; + float frameTime; + }; + + auto cmd = (SV_CUserCmd*)pCmd_move; + auto fromCmd = (SV_CUserCmd*)pCmd_from; + + std::string BLOCK_PREFIX = + "ReadUsercmd (command_number delta: " + std::to_string(cmd->command_number - fromCmd->command_number) + "): "; + + // fix invalid player angles + cmd->worldViewAngles.MakeValid(); + cmd->attackangles.MakeValid(); + cmd->localViewAngles.MakeValid(); + + // Fix invalid camera angles + cmd->cameraPos.MakeValid(); + cmd->cameraAngles.MakeValid(); + + // Fix invaid movement vector + cmd->move.MakeValid(); + + if (cmd->frameTime <= 0 || cmd->tick_count == 0 || cmd->command_time <= 0) + { + BLOCKED_INFO( + "Bogus cmd timing (tick_count: " << cmd->tick_count << ", frameTime: " << cmd->frameTime + << ", commandTime : " << cmd->command_time << ")"); + goto INVALID_CMD; // No simulation of bogus-timed cmds + } + + return; + +INVALID_CMD: + + // Fix any gameplay-affecting cmd properties + // NOTE: Currently tickcount/frametime is set to 0, this ~shouldn't~ cause any problems + cmd->worldViewAngles = cmd->localViewAngles = cmd->attackangles = cmd->cameraAngles = {0, 0, 0}; + cmd->tick_count = cmd->frameTime = 0; + cmd->move = cmd->cameraPos = {0, 0, 0}; + cmd->buttons = 0; + cmd->meleetarget = 0; +} + +// ensure that GetLocalBaseClient().m_bRestrictServerCommands is set correctly, which the return value of this function controls +// this is IsValveMod in source, but we're making it IsRespawnMod now since valve didn't make this one +// clang-format off +AUTOHOOK(IsRespawnMod, engine.dll + 0x1C6360, +bool, __fastcall, (const char* pModName)) // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? E8 ? ? ? ? 85 C0 74 63 +// clang-format on +{ + // somewhat temp, store the modname here, since we don't have a proper ptr in engine to it rn + int iSize = strlen(pModName); + R2::g_pModName = new char[iSize + 1]; + strcpy(R2::g_pModName, pModName); + + return (!strcmp("r2", pModName) || !strcmp("r1", pModName)) && !Tier0::CommandLine()->CheckParm("-norestrictservercommands"); +} + +// ratelimit stringcmds, and prevent remote clients from calling commands that they shouldn't +bool (*CCommand__Tokenize)(CCommand& self, const char* pCommandString, R2::cmd_source_t commandSource); + +// clang-format off +AUTOHOOK(CGameClient__ExecuteStringCommand, engine.dll + 0x1022E0, +bool, __fastcall, (R2::CBaseClient* self, uint32_t unknown, const char* pCommandString)) +// clang-format on +{ + if (Cvar_ns_should_log_all_clientcommands->GetBool()) + spdlog::info("player {} (UID: {}) sent command: \"{}\"", self->m_Name, self->m_UID, pCommandString); + + if (!g_pServerLimits->CheckStringCommandLimits(self)) + { + R2::CBaseClient__Disconnect(self, 1, "Sent too many stringcmd commands"); + return false; + } + + // verify the command we're trying to execute is FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS, if it's a concommand + char* commandBuf[1040]; // assumedly this is the size of CCommand since we don't have an actual constructor + memset(commandBuf, 0, sizeof(commandBuf)); + CCommand tempCommand = *(CCommand*)&commandBuf; + + if (!CCommand__Tokenize(tempCommand, pCommandString, R2::cmd_source_t::kCommandSrcCode) || !tempCommand.ArgC()) + return false; + + ConCommand* command = R2::g_pCVar->FindCommand(tempCommand.Arg(0)); + + // if the command doesn't exist pass it on to ExecuteStringCommand for script clientcommands and stuff + if (command && !command->IsFlagSet(FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS)) + { + // ensure FCVAR_GAMEDLL concommands without FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS can't be executed by remote clients + if (IsDedicatedServer()) + return false; + + if (strcmp(self->m_UID, R2::g_pLocalPlayerUserID)) + return false; + } + + // check for and block abusable legacy portal 2 commands + // these aren't actually concommands weirdly enough, they seem to just be hardcoded + if (!Cvar_sv_cheats->GetBool()) + { + constexpr const char* blockedCommands[] = { + "emit", // Sound-playing exploit (likely for Portal 2 coop devs testing splitscreen sound or something) + + // These both execute a command for every single entity for some reason, nice one valve + "pre_go_to_hub", + "pre_go_to_calibration", + + "end_movie", // Calls "__MovieFinished" script function, not sure exactly what this does but it certainly isn't needed + "load_recent_checkpoint" // This is the instant-respawn exploit, literally just calls RespawnPlayer() + }; + + int iCmdLength = strlen(tempCommand.Arg(0)); + + bool bIsBadCommand = false; + for (auto& blockedCommand : blockedCommands) + { + if (iCmdLength != strlen(blockedCommand)) + continue; + + for (int i = 0; tempCommand.Arg(0)[i]; i++) + if (tolower(tempCommand.Arg(0)[i]) != blockedCommand[i]) + goto NEXT_COMMAND; // break out of this loop, then go to next command + + // this is a command we need to block + return false; + NEXT_COMMAND:; + } + } + + return CGameClient__ExecuteStringCommand(self, unknown, pCommandString); +} + +// prevent clients from crashing servers through overflowing CNetworkStringTableContainer::WriteBaselines +bool bWasWritingStringTableSuccessful; + +// clang-format off +AUTOHOOK(CBaseClient__SendServerInfo, engine.dll + 0x104FB0, +void, __fastcall, (void* self)) +// clang-format on +{ + bWasWritingStringTableSuccessful = true; + CBaseClient__SendServerInfo(self); + if (!bWasWritingStringTableSuccessful) + R2::CBaseClient__Disconnect( + self, 1, "Overflowed CNetworkStringTableContainer::WriteBaselines, try restarting your client and reconnecting"); +} + +// return null when GetEntByIndex is passed an index >= 0x4000 +// this is called from exactly 1 script clientcommand that can be given an arbitrary index, and going above 0x4000 crashes +// clang-format off +AUTOHOOK(GetEntByIndex, server.dll + 0x2A8A50, +void*, __fastcall, (int i)) +// clang-format on +{ + const int MAX_ENT_IDX = 0x4000; + + if (i >= MAX_ENT_IDX) + { + spdlog::warn("GetEntByIndex {} is out of bounds (max {})", i, MAX_ENT_IDX); + return nullptr; + } + + return GetEntByIndex(i); +} + +ON_DLL_LOAD("engine.dll", EngineExploitFixes, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(engine.dll) + + CCommand__Tokenize = module.Offset(0x418380).As<bool (*)(CCommand&, const char*, R2::cmd_source_t)>(); + + // allow client/ui to run clientcommands despite restricting servercommands + module.Offset(0x4FB65).Patch("EB 11"); + module.Offset(0x4FBAC).Patch("EB 16"); + + // patch to set bWasWritingStringTableSuccessful in CNetworkStringTableContainer::WriteBaselines if it fails + { + MemoryAddress writeAddress(&bWasWritingStringTableSuccessful - module.Offset(0x234EDC).m_nAddress); + + MemoryAddress addr = module.Offset(0x234ED2); + addr.Patch("C7 05"); + addr.Offset(2).Patch((BYTE*)&writeAddress, sizeof(writeAddress)); + + addr.Offset(6).Patch("00 00 00 00"); + + addr.Offset(10).NOP(5); + } +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerExploitFixes, ConVar, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(server.dll) + + // ret at the start of CServerGameClients::ClientCommandKeyValues as it has no benefit and is forwarded to client (i.e. security issue) + // this prevents the attack vector of client=>server=>client, however server=>client also has clientside patches + module.Offset(0x153920).Patch("C3"); + + // Dumb ANTITAMPER patches (they negatively impact performance and security) + constexpr const char* ANTITAMPER_EXPORTS[] = { + "ANTITAMPER_SPOTCHECK_CODEMARKER", + "ANTITAMPER_TESTVALUE_CODEMARKER", + "ANTITAMPER_TRIGGER_CODEMARKER", + }; + + // Prevent these from actually doing anything + for (auto exportName : ANTITAMPER_EXPORTS) + { + MemoryAddress exportAddr = module.GetExport(exportName); + if (exportAddr) + { + // Just return, none of them have any args or are userpurge + exportAddr.Patch("C3"); + spdlog::info("Patched AntiTamper function export \"{}\"", exportName); + } + } + + Cvar_ns_exploitfixes_log = + new ConVar("ns_exploitfixes_log", "1", FCVAR_GAMEDLL, "Whether to log whenever ExploitFixes.cpp blocks/corrects something"); + Cvar_ns_should_log_all_clientcommands = + new ConVar("ns_should_log_all_clientcommands", "0", FCVAR_NONE, "Whether to log all clientcommands"); + + Cvar_sv_cheats = R2::g_pCVar->FindVar("sv_cheats"); +} diff --git a/NorthstarDLL/exploitfixes_lzss.cpp b/NorthstarDLL/exploitfixes_lzss.cpp new file mode 100644 index 00000000..4205133a --- /dev/null +++ b/NorthstarDLL/exploitfixes_lzss.cpp @@ -0,0 +1,79 @@ +#include "pch.h" + +AUTOHOOK_INIT() + +static constexpr int LZSS_LOOKSHIFT = 4; + +struct lzss_header_t +{ + unsigned int id; + unsigned int actualSize; +}; + +// Rewrite of CLZSS::SafeUncompress to fix a vulnerability where malicious compressed payloads could cause the decompressor to try to read +// out of the bounds of the output buffer. +// clang-format off +AUTOHOOK(CLZSS__SafeDecompress, engine.dll + 0x432A10, +unsigned int, __fastcall, (void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)) +// clang-format on +{ + unsigned int totalBytes = 0; + int getCmdByte = 0; + int cmdByte = 0; + + lzss_header_t header = *(lzss_header_t*)pInput; + + if (!pInput || !header.actualSize || header.id != 0x53535A4C || header.actualSize > unBufSize) + return 0; + + pInput += sizeof(lzss_header_t); + + for (;;) + { + if (!getCmdByte) + cmdByte = *pInput++; + + getCmdByte = (getCmdByte + 1) & 0x07; + + if (cmdByte & 0x01) + { + int position = *pInput++ << LZSS_LOOKSHIFT; + position |= (*pInput >> LZSS_LOOKSHIFT); + position += 1; + int count = (*pInput++ & 0x0F) + 1; + if (count == 1) + break; + + // Ensure reference chunk exists entirely within our buffer + if (position > totalBytes) + return 0; + + totalBytes += count; + if (totalBytes > unBufSize) + return 0; + + unsigned char* pSource = pOutput - position; + for (int i = 0; i < count; i++) + *pOutput++ = *pSource++; + } + else + { + totalBytes++; + if (totalBytes > unBufSize) + return 0; + + *pOutput++ = *pInput++; + } + cmdByte = cmdByte >> 1; + } + + if (totalBytes != header.actualSize) + return 0; + + return totalBytes; +} + +ON_DLL_LOAD("engine.dll", ExploitFixes_LZSS, (CModule module)) +{ + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDLL/exploitfixes_utf8parser.cpp b/NorthstarDLL/exploitfixes_utf8parser.cpp new file mode 100644 index 00000000..e2510765 --- /dev/null +++ b/NorthstarDLL/exploitfixes_utf8parser.cpp @@ -0,0 +1,200 @@ +#include "pch.h" + +AUTOHOOK_INIT() + +INT64(__fastcall* sub_F1320)(DWORD a1, char* a2); + +// Reimplementation of an exploitable UTF decoding function in titanfall +bool __fastcall CheckUTF8Valid(INT64* a1, DWORD* a2, char* strData) +{ + DWORD v3; // eax + char* v4; // rbx + char v5; // si + char* _strData; // rdi + char* v7; // rbp + char v11; // al + DWORD v12; // er9 + DWORD v13; // ecx + DWORD v14; // edx + DWORD v15; // er8 + int v16; // eax + DWORD v17; // er9 + int v18; // eax + DWORD v19; // er9 + DWORD v20; // ecx + int v21; // eax + int v22; // er9 + DWORD v23; // edx + int v24; // eax + int v25; // er9 + DWORD v26; // er9 + DWORD v27; // er10 + DWORD v28; // ecx + DWORD v29; // edx + DWORD v30; // er8 + int v31; // eax + DWORD v32; // er10 + int v33; // eax + DWORD v34; // er10 + DWORD v35; // ecx + int v36; // eax + int v37; // er10 + DWORD v38; // edx + int v39; // eax + int v40; // er10 + DWORD v41; // er10 + INT64 v43; // r8 + INT64 v44; // rdx + INT64 v45; // rcx + INT64 v46; // rax + INT64 v47; // rax + char v48; // al + INT64 v49; // r8 + INT64 v50; // rdx + INT64 v51; // rcx + INT64 v52; // rax + INT64 v53; // rax + + v3 = a2[2]; + v4 = (char*)(a1[1] + *a2); + v5 = 0; + _strData = strData; + v7 = &v4[*((UINT16*)a2 + 2)]; + if (v3 >= 2) + { + ++v4; + --v7; + if (v3 != 2) + { + while (1) + { + if (!MemoryAddress(v4).IsMemoryReadable(1)) + return false; // INVALID + + v11 = *v4++; // crash potential + if (v11 != 92) + goto LABEL_6; + v11 = *v4++; + if (v11 == 110) + break; + switch (v11) + { + case 't': + v11 = 9; + goto LABEL_6; + case 'r': + v11 = 13; + goto LABEL_6; + case 'b': + v11 = 8; + goto LABEL_6; + case 'f': + v11 = 12; + goto LABEL_6; + } + if (v11 != 117) + goto LABEL_6; + v12 = *v4 | 0x20; + v13 = v4[1] | 0x20; + v14 = v4[2] | 0x20; + v15 = v4[3] | 0x20; + v16 = 87; + if (v12 <= 0x39) + v16 = 48; + v17 = v12 - v16; + v18 = 87; + v19 = v17 << 12; + if (v13 <= 0x39) + v18 = 48; + v20 = v13 - v18; + v21 = 87; + v22 = (v20 << 8) | v19; + if (v14 <= 0x39) + v21 = 48; + v23 = v14 - v21; + v24 = 87; + v25 = (16 * v23) | v22; + if (v15 <= 0x39) + v24 = 48; + v4 += 4; + v26 = (v15 - v24) | v25; + if (v26 - 55296 <= 0x7FF) + { + if (v26 >= 0xDC00) + return true; + if (*v4 != 92 || v4[1] != 117) + return true; + + v27 = v4[2] | 0x20; + v28 = v4[3] | 0x20; + v29 = v4[4] | 0x20; + v30 = v4[5] | 0x20; + v31 = 87; + if (v27 <= 0x39) + v31 = 48; + v32 = v27 - v31; + v33 = 87; + v34 = v32 << 12; + if (v28 <= 0x39) + v33 = 48; + v35 = v28 - v33; + v36 = 87; + v37 = (v35 << 8) | v34; + if (v29 <= 0x39) + v36 = 48; + v38 = v29 - v36; + v39 = 87; + v40 = (16 * v38) | v37; + if (v30 <= 0x39) + v39 = 48; + v4 += 6; + v41 = ((v30 - v39) | v40) - 56320; + if (v41 > 0x3FF) + return true; + v26 = v41 | ((v26 - 55296) << 10); + } + _strData += (DWORD)sub_F1320(v26, _strData); + LABEL_7: + if (v4 == v7) + goto LABEL_48; + } + v11 = 10; + LABEL_6: + v5 |= v11; + *_strData++ = v11; + goto LABEL_7; + } + } +LABEL_48: + return true; +} + +// prevent utf8 parser from crashing when provided bad data, which can be sent through user-controlled openinvites +// clang-format off +AUTOHOOK(Rson_ParseUTF8, engine.dll + 0xEF670, +bool, __fastcall, (INT64* a1, DWORD* a2, char* strData)) // 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC 20 8B 1A +// clang-format on +{ + static void* targetRetAddr = CModule("engine.dll").FindPattern("84 C0 75 2C 49 8B 16"); + + // only call if we're parsing utf8 data from the network (i.e. communities), otherwise we get perf issues + void* pReturnAddress = +#ifdef _MSC_VER + _ReturnAddress() +#else + __builtin_return_address(0) +#endif + ; + + if (pReturnAddress == targetRetAddr && !CheckUTF8Valid(a1, a2, strData)) + return false; + + return Rson_ParseUTF8(a1, a2, strData); +} + +ON_DLL_LOAD("engine.dll", EngineExploitFixes_UTF8Parser, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + sub_F1320 = module.FindPattern("83 F9 7F 77 08 88 0A").As<INT64(__fastcall*)(DWORD, char*)>(); +} diff --git a/NorthstarDLL/filesystem.cpp b/NorthstarDLL/filesystem.cpp new file mode 100644 index 00000000..e6c6f49a --- /dev/null +++ b/NorthstarDLL/filesystem.cpp @@ -0,0 +1,186 @@ +#include "pch.h" +#include "filesystem.h" +#include "sourceinterface.h" +#include "modmanager.h" + +#include <iostream> +#include <sstream> + +AUTOHOOK_INIT() + +using namespace R2; + +bool bReadingOriginalFile = false; +std::string sCurrentModPath; + +ConVar* Cvar_ns_fs_log_reads; + +// use the R2 namespace for game funcs +namespace R2 +{ + SourceInterface<IFileSystem>* g_pFilesystem; + + std::string ReadVPKFile(const char* path) + { + // read scripts.rson file, todo: check if this can be overwritten + FileHandle_t fileHandle = (*g_pFilesystem)->m_vtable2->Open(&(*g_pFilesystem)->m_vtable2, path, "rb", "GAME", 0); + + std::stringstream fileStream; + int bytesRead = 0; + char data[4096]; + do + { + bytesRead = (*g_pFilesystem)->m_vtable2->Read(&(*g_pFilesystem)->m_vtable2, data, (int)std::size(data), fileHandle); + fileStream.write(data, bytesRead); + } while (bytesRead == std::size(data)); + + (*g_pFilesystem)->m_vtable2->Close(*g_pFilesystem, fileHandle); + + return fileStream.str(); + } + + std::string ReadVPKOriginalFile(const char* path) + { + // todo: should probably set search path to be g_pModName here also + + bReadingOriginalFile = true; + std::string ret = ReadVPKFile(path); + bReadingOriginalFile = false; + + return ret; + } +} // namespace R2 + +// clang-format off +HOOK(AddSearchPathHook, AddSearchPath, +void, __fastcall, (IFileSystem * fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType)) +// clang-format on +{ + AddSearchPath(fileSystem, pPath, pathID, addType); + + // make sure current mod paths are at head + if (!strcmp(pathID, "GAME") && sCurrentModPath.compare(pPath) && addType == PATH_ADD_TO_HEAD) + { + AddSearchPath(fileSystem, sCurrentModPath.c_str(), "GAME", PATH_ADD_TO_HEAD); + AddSearchPath(fileSystem, GetCompiledAssetsPath().string().c_str(), "GAME", PATH_ADD_TO_HEAD); + } +} + +void SetNewModSearchPaths(Mod* mod) +{ + // put our new path to the head if we need to read from a different mod path + // in the future we could also determine whether the file we're setting paths for needs a mod dir, or compiled assets + if (mod != nullptr) + { + if ((fs::absolute(mod->m_ModDirectory) / MOD_OVERRIDE_DIR).string().compare(sCurrentModPath)) + { + spdlog::info("changing mod search path from {} to {}", sCurrentModPath, mod->m_ModDirectory.string()); + + AddSearchPath( + &*(*g_pFilesystem), (fs::absolute(mod->m_ModDirectory) / MOD_OVERRIDE_DIR).string().c_str(), "GAME", PATH_ADD_TO_HEAD); + sCurrentModPath = (fs::absolute(mod->m_ModDirectory) / MOD_OVERRIDE_DIR).string(); + } + } + else // push compiled to head + AddSearchPath(&*(*g_pFilesystem), fs::absolute(GetCompiledAssetsPath()).string().c_str(), "GAME", PATH_ADD_TO_HEAD); +} + +bool TryReplaceFile(const char* pPath, bool shouldCompile) +{ + if (bReadingOriginalFile) + return false; + + if (shouldCompile) + g_pModManager->CompileAssetsForFile(pPath); + + // idk how efficient the lexically normal check is + // can't just set all /s in path to \, since some paths aren't in writeable memory + auto file = g_pModManager->m_ModFiles.find(g_pModManager->NormaliseModFilePath(fs::path(pPath))); + if (file != g_pModManager->m_ModFiles.end()) + { + SetNewModSearchPaths(file->second.m_pOwningMod); + return true; + } + + return false; +} + +// force modded files to be read from mods, not cache +// clang-format off +HOOK(ReadFromCacheHook, ReadFromCache, +bool, __fastcall, (IFileSystem * filesystem, char* pPath, void* result)) +// clang-format off +{ + if (TryReplaceFile(pPath, true)) + return false; + + return ReadFromCache(filesystem, pPath, result); +} + +// force modded files to be read from mods, not vpk +// clang-format off +AUTOHOOK(ReadFileFromVPK, filesystem_stdio.dll + 0x5CBA0, +FileHandle_t, __fastcall, (VPKData* vpkInfo, uint64_t* b, char* filename)) +// clang-format on +{ + // don't compile here because this is only ever called from OpenEx, which already compiles + if (TryReplaceFile(filename, false)) + { + *b = -1; + return b; + } + + return ReadFileFromVPK(vpkInfo, b, filename); +} + +// clang-format off +AUTOHOOK(CBaseFileSystem__OpenEx, filesystem_stdio.dll + 0x15F50, +FileHandle_t, __fastcall, (IFileSystem* filesystem, const char* pPath, const char* pOptions, uint32_t flags, const char* pPathID, char **ppszResolvedFilename)) +// clang-format on +{ + TryReplaceFile(pPath, true); + return CBaseFileSystem__OpenEx(filesystem, pPath, pOptions, flags, pPathID, ppszResolvedFilename); +} + +HOOK(MountVPKHook, MountVPK, VPKData*, , (IFileSystem * fileSystem, const char* pVpkPath)) +{ + spdlog::info("MountVPK {}", pVpkPath); + VPKData* ret = MountVPK(fileSystem, pVpkPath); + + for (Mod mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + for (ModVPKEntry& vpkEntry : mod.Vpks) + { + // if we're autoloading, just load no matter what + if (!vpkEntry.m_bAutoLoad) + { + // resolve vpk name and try to load one with the same name + // todo: we should be unloading these on map unload manually + std::string mapName(fs::path(pVpkPath).filename().string()); + std::string modMapName(fs::path(vpkEntry.m_sVpkPath.c_str()).filename().string()); + if (mapName.compare(modMapName)) + continue; + } + + VPKData* loaded = MountVPK(fileSystem, vpkEntry.m_sVpkPath.c_str()); + if (!ret) // this is primarily for map vpks and stuff, so the map's vpk is what gets returned from here + ret = loaded; + } + } + + return ret; +} + +ON_DLL_LOAD("filesystem_stdio.dll", Filesystem, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + R2::g_pFilesystem = new SourceInterface<IFileSystem>("filesystem_stdio.dll", "VFileSystem017"); + + AddSearchPathHook.Dispatch((*g_pFilesystem)->m_vtable->AddSearchPath); + ReadFromCacheHook.Dispatch((*g_pFilesystem)->m_vtable->ReadFromCache); + MountVPKHook.Dispatch((*g_pFilesystem)->m_vtable->MountVPK); +} diff --git a/NorthstarDedicatedTest/filesystem.h b/NorthstarDLL/filesystem.h index 960c2836..c326b419 100644 --- a/NorthstarDedicatedTest/filesystem.h +++ b/NorthstarDLL/filesystem.h @@ -59,7 +59,8 @@ class IFileSystem FileHandle_t (*Open)( IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pOptions, const char* pathID, int64_t unknown); void (*Close)(IFileSystem* fileSystem, FileHandle_t file); - void* unknown2[6]; + long long (*Seek)(IFileSystem::VTable2** fileSystem, FileHandle_t file, long long offset, long long whence); + void* unknown2[5]; bool (*FileExists)(IFileSystem::VTable2** fileSystem, const char* pFileName, const char* pPathID); }; @@ -67,8 +68,11 @@ class IFileSystem VTable2* m_vtable2; }; -std::string ReadVPKFile(const char* path); -std::string ReadVPKOriginalFile(const char* path); +// use the R2 namespace for game funcs +namespace R2 +{ + extern SourceInterface<IFileSystem>* g_pFilesystem; -void InitialiseFilesystem(HMODULE baseAddress); -extern SourceInterface<IFileSystem>* g_Filesystem;
\ No newline at end of file + std::string ReadVPKFile(const char* path); + std::string ReadVPKOriginalFile(const char* path); +} // namespace R2 diff --git a/NorthstarDLL/hooks.cpp b/NorthstarDLL/hooks.cpp new file mode 100644 index 00000000..4c068fe8 --- /dev/null +++ b/NorthstarDLL/hooks.cpp @@ -0,0 +1,398 @@ +#include "pch.h" +#include "dedicated.h" + +#include <iostream> +#include <wchar.h> +#include <iostream> +#include <vector> +#include <fstream> +#include <sstream> +#include <filesystem> +#include <Psapi.h> + +AUTOHOOK_INIT() + +// called from the ON_DLL_LOAD macros +__dllLoadCallback::__dllLoadCallback( + eDllLoadCallbackSide side, const std::string dllName, DllLoadCallbackFuncType callback, std::string uniqueStr, std::string reliesOn) +{ + // parse reliesOn array from string + std::vector<std::string> reliesOnArray; + + if (reliesOn.length() && reliesOn[0] != '(') + { + reliesOnArray.push_back(reliesOn); + } + else + { + // follows the format (tag, tag, tag) + std::string sCurrentTag; + for (int i = 1; i < reliesOn.length(); i++) + { + if (!isspace(reliesOn[i])) + { + if (reliesOn[i] == ',' || reliesOn[i] == ')') + { + reliesOnArray.push_back(sCurrentTag); + sCurrentTag = ""; + } + else + sCurrentTag += reliesOn[i]; + } + } + } + + switch (side) + { + case eDllLoadCallbackSide::UNSIDED: + { + AddDllLoadCallback(dllName, callback, uniqueStr, reliesOnArray); + break; + } + + case eDllLoadCallbackSide::CLIENT: + { + AddDllLoadCallbackForClient(dllName, callback, uniqueStr, reliesOnArray); + break; + } + + case eDllLoadCallbackSide::DEDICATED_SERVER: + { + AddDllLoadCallbackForDedicatedServer(dllName, callback, uniqueStr, reliesOnArray); + break; + } + } +} + +void __fileAutohook::Dispatch() +{ + for (__autohook* hook : hooks) + hook->Dispatch(); +} + +void __fileAutohook::DispatchForModule(const char* pModuleName) +{ + const int iModuleNameLen = strlen(pModuleName); + + for (__autohook* hook : hooks) + if ((hook->iAddressResolutionMode == __autohook::OFFSET_STRING && !strncmp(pModuleName, hook->pAddrString, iModuleNameLen)) || + (hook->iAddressResolutionMode == __autohook::PROCADDRESS && !strcmp(pModuleName, hook->pModuleName))) + hook->Dispatch(); +} + +ManualHook::ManualHook(const char* funcName, LPVOID func) : pHookFunc(func), ppOrigFunc(nullptr) +{ + const int iFuncNameStrlen = strlen(funcName); + pFuncName = new char[iFuncNameStrlen]; + memcpy(pFuncName, funcName, iFuncNameStrlen); +} + +ManualHook::ManualHook(const char* funcName, LPVOID* orig, LPVOID func) : pHookFunc(func), ppOrigFunc(orig) +{ + const int iFuncNameStrlen = strlen(funcName); + pFuncName = new char[iFuncNameStrlen]; + memcpy(pFuncName, funcName, iFuncNameStrlen); +} + +bool ManualHook::Dispatch(LPVOID addr, LPVOID* orig) +{ + if (orig) + ppOrigFunc = orig; + + if (MH_CreateHook(addr, pHookFunc, ppOrigFunc) == MH_OK) + { + if (MH_EnableHook(addr) == MH_OK) + { + spdlog::info("Enabling hook {}", pFuncName); + return true; + } + else + spdlog::error("MH_EnableHook failed for function {}", pFuncName); + } + else + spdlog::error("MH_CreateHook failed for function {}", pFuncName); + + return false; +} + +// dll load callback stuff +// this allows for code to register callbacks to be run as soon as a dll is loaded, mainly to allow for patches to be made on dll load +struct DllLoadCallback +{ + std::string dll; + DllLoadCallbackFuncType callback; + std::string tag; + std::vector<std::string> reliesOn; + bool called; +}; + +// HACK: declaring and initialising this vector at file scope crashes on debug builds due to static initialisation order +// using a static var like this ensures that the vector is initialised lazily when it's used +std::vector<DllLoadCallback>& GetDllLoadCallbacks() +{ + static std::vector<DllLoadCallback> vec = std::vector<DllLoadCallback>(); + return vec; +} + +void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn) +{ + DllLoadCallback& callbackStruct = GetDllLoadCallbacks().emplace_back(); + + callbackStruct.dll = dll; + callbackStruct.callback = callback; + callbackStruct.tag = tag; + callbackStruct.reliesOn = reliesOn; + callbackStruct.called = false; +} + +void AddDllLoadCallbackForDedicatedServer( + std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn) +{ + if (!IsDedicatedServer()) + return; + + AddDllLoadCallback(dll, callback, tag, reliesOn); +} + +void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn) +{ + if (IsDedicatedServer()) + return; + + AddDllLoadCallback(dll, callback, tag, reliesOn); +} + +void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName) +{ + char* pStrippedFuncName = (char*)pFuncName; + // strip & char from funcname + if (*pStrippedFuncName == '&') + pStrippedFuncName++; + + if (MH_CreateHook(pTarget, pDetour, (LPVOID*)ppOriginal) == MH_OK) + { + if (MH_EnableHook(pTarget) == MH_OK) + spdlog::info("Enabling hook {}", pStrippedFuncName); + else + spdlog::error("MH_EnableHook failed for function {}", pStrippedFuncName); + } + else + spdlog::error("MH_CreateHook failed for function {}", pStrippedFuncName); +} + +AUTOHOOK_ABSOLUTEADDR(_GetCommandLineA, GetCommandLineA, LPSTR, WINAPI, ()) +{ + static char* cmdlineModified; + static char* cmdlineOrg; + + if (cmdlineOrg == nullptr || cmdlineModified == nullptr) + { + cmdlineOrg = _GetCommandLineA(); + bool isDedi = strstr(cmdlineOrg, "-dedicated"); // well, this one has to be a real argument + bool ignoreStartupArgs = strstr(cmdlineOrg, "-nostartupargs"); + + std::string args; + std::ifstream cmdlineArgFile; + + // it looks like CommandLine() prioritizes parameters apprearing first, so we want the real commandline to take priority + // not to mention that cmdlineOrg starts with the EXE path + args.append(cmdlineOrg); + args.append(" "); + + // append those from the file + + if (!ignoreStartupArgs) + { + + cmdlineArgFile = std::ifstream(!isDedi ? "ns_startup_args.txt" : "ns_startup_args_dedi.txt"); + + if (cmdlineArgFile) + { + std::stringstream argBuffer; + argBuffer << cmdlineArgFile.rdbuf(); + cmdlineArgFile.close(); + + // if some other command line option includes "-northstar" in the future then you have to refactor this check to check with + // both either space after or ending with + if (!isDedi && argBuffer.str().find("-northstar") != std::string::npos) + MessageBoxA( + NULL, + "The \"-northstar\" command line option is NOT supposed to go into ns_startup_args.txt file!\n\nThis option is " + "supposed to go into Origin/Steam game launch options, and then you are supposed to launch the original " + "Titanfall2.exe " + "rather than NorthstarLauncher.exe to make use of it.", + "Northstar Warning", + MB_ICONWARNING); + + args.append(argBuffer.str()); + } + } + + auto len = args.length(); + cmdlineModified = new char[len + 1]; + if (!cmdlineModified) + { + spdlog::error("malloc failed for command line"); + return cmdlineOrg; + } + memcpy(cmdlineModified, args.c_str(), len + 1); + + spdlog::info("Command line: {}", cmdlineModified); + } + + return cmdlineModified; +} + +std::vector<std::string> calledTags; +void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress) +{ + CModule cModule(moduleAddress); + + while (true) + { + bool bDoneCalling = true; + + for (auto& callbackStruct : GetDllLoadCallbacks()) + { + if (!callbackStruct.called && fs::path(lpLibFileName).filename() == fs::path(callbackStruct.dll).filename()) + { + bool bShouldContinue = false; + + if (!callbackStruct.reliesOn.empty()) + { + for (std::string tag : callbackStruct.reliesOn) + { + if (std::find(calledTags.begin(), calledTags.end(), tag) == calledTags.end()) + { + bDoneCalling = false; + bShouldContinue = true; + break; + } + } + } + + if (bShouldContinue) + continue; + + callbackStruct.callback(moduleAddress); + calledTags.push_back(callbackStruct.tag); + callbackStruct.called = true; + } + } + + if (bDoneCalling) + break; + } +} + +void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress) +{ + CModule cModule(moduleAddress); + + while (true) + { + bool bDoneCalling = true; + + for (auto& callbackStruct : GetDllLoadCallbacks()) + { + if (!callbackStruct.called && fs::path(lpLibFileName).filename() == fs::path(callbackStruct.dll).filename()) + { + bool bShouldContinue = false; + + if (!callbackStruct.reliesOn.empty()) + { + for (std::string tag : callbackStruct.reliesOn) + { + if (std::find(calledTags.begin(), calledTags.end(), tag) == calledTags.end()) + { + bDoneCalling = false; + bShouldContinue = true; + break; + } + } + } + + if (bShouldContinue) + continue; + + callbackStruct.callback(moduleAddress); + calledTags.push_back(callbackStruct.tag); + callbackStruct.called = true; + } + } + + if (bDoneCalling) + break; + } +} + +void CallAllPendingDLLLoadCallbacks() +{ + HMODULE hMods[1024]; + HANDLE hProcess = GetCurrentProcess(); + DWORD cbNeeded; + unsigned int i; + + // Get a list of all the modules in this process. + if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) + { + for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) + { + wchar_t szModName[MAX_PATH]; + + // Get the full path to the module's file. + if (GetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) + { + CallLoadLibraryWCallbacks(szModName, hMods[i]); + } + } + } +} + +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, LoadLibraryExA, HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) +{ + HMODULE moduleAddress = _LoadLibraryExA(lpLibFileName, hFile, dwFlags); + + if (moduleAddress) + CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); + + return moduleAddress; +} + +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, LoadLibraryA, HMODULE, WINAPI, (LPCSTR lpLibFileName)) +{ + HMODULE moduleAddress = _LoadLibraryA(lpLibFileName); + + if (moduleAddress) + CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); + + return moduleAddress; +} + +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, LoadLibraryExW, HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)) +{ + HMODULE moduleAddress = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); + + if (moduleAddress) + CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); + + return moduleAddress; +} + +AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, LoadLibraryW, HMODULE, WINAPI, (LPCWSTR lpLibFileName)) +{ + HMODULE moduleAddress = _LoadLibraryW(lpLibFileName); + + if (moduleAddress) + CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); + + return moduleAddress; +} + +void InstallInitialHooks() +{ + if (MH_Initialize() != MH_OK) + spdlog::error("MH_Initialize (minhook initialization) failed"); + + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDLL/hooks.h b/NorthstarDLL/hooks.h new file mode 100644 index 00000000..f47791fb --- /dev/null +++ b/NorthstarDLL/hooks.h @@ -0,0 +1,311 @@ +#pragma once +#include "memory.h" + +#include <string> +#include <iostream> + +void InstallInitialHooks(); + +typedef void (*DllLoadCallbackFuncType)(CModule moduleAddress); +void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag = "", std::vector<std::string> reliesOn = {}); +void AddDllLoadCallbackForDedicatedServer( + std::string dll, DllLoadCallbackFuncType callback, std::string tag = "", std::vector<std::string> reliesOn = {}); +void AddDllLoadCallbackForClient( + std::string dll, DllLoadCallbackFuncType callback, std::string tag = "", std::vector<std::string> reliesOn = {}); + +void CallAllPendingDLLLoadCallbacks(); + +// new dll load callback stuff +enum class eDllLoadCallbackSide +{ + UNSIDED, + CLIENT, + DEDICATED_SERVER +}; + +class __dllLoadCallback +{ + public: + __dllLoadCallback() = delete; + __dllLoadCallback( + eDllLoadCallbackSide side, + const std::string dllName, + DllLoadCallbackFuncType callback, + std::string uniqueStr, + std::string reliesOn); +}; + +#define __CONCAT3(x, y, z) x##y##z +#define CONCAT3(x, y, z) __CONCAT3(x, y, z) +#define __CONCAT2(x, y) x##y +#define CONCAT2(x, y) __CONCAT2(x, y) +#define __STR(s) #s + +// adds a callback to be called when a given dll is loaded, for creating hooks and such +#define __ON_DLL_LOAD(dllName, side, uniquestr, reliesOn, args) \ + void CONCAT2(__dllLoadCallback, uniquestr) args; \ + namespace \ + { \ + __dllLoadCallback CONCAT2(__dllLoadCallbackInstance, __LINE__)( \ + side, dllName, CONCAT2(__dllLoadCallback, uniquestr), __STR(uniquestr), reliesOn); \ + } \ + void CONCAT2(__dllLoadCallback, uniquestr) args + +#define ON_DLL_LOAD(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, "", args) +#define ON_DLL_LOAD_RELIESON(dllName, uniquestr, reliesOn, args) \ + __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::UNSIDED, uniquestr, __STR(reliesOn), args) +#define ON_DLL_LOAD_CLIENT(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, "", args) +#define ON_DLL_LOAD_CLIENT_RELIESON(dllName, uniquestr, reliesOn, args) \ + __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::CLIENT, uniquestr, __STR(reliesOn), args) +#define ON_DLL_LOAD_DEDI(dllName, uniquestr, args) __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, "", args) +#define ON_DLL_LOAD_DEDI_RELIESON(dllName, uniquestr, reliesOn, args) \ + __ON_DLL_LOAD(dllName, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, __STR(reliesOn), args) + +// new macro hook stuff +class __autohook; + +class __fileAutohook +{ + public: + std::vector<__autohook*> hooks; + + void Dispatch(); + void DispatchForModule(const char* pModuleName); +}; + +// initialise autohooks for this file +#define AUTOHOOK_INIT() \ + namespace \ + { \ + __fileAutohook __FILEAUTOHOOK; \ + } + +// dispatch all autohooks in this file +#define AUTOHOOK_DISPATCH() __FILEAUTOHOOK.Dispatch(); + +#define AUTOHOOK_DISPATCH_MODULE(moduleName) __FILEAUTOHOOK.DispatchForModule(__STR(moduleName)); + +class __autohook +{ + public: + enum AddressResolutionMode + { + OFFSET_STRING, // we're using a string that of the format dllname.dll + offset + ABSOLUTE_ADDR, // we're using an absolute address, we don't need to process it at all + PROCADDRESS // resolve using GetModuleHandle and GetProcAddress + }; + + char* pFuncName; + + LPVOID pHookFunc; + LPVOID* ppOrigFunc; + + // address resolution props + AddressResolutionMode iAddressResolutionMode; + char* pAddrString = nullptr; // for OFFSET_STRING + LPVOID iAbsoluteAddress = nullptr; // for ABSOLUTE_ADDR + char* pModuleName; // for PROCADDRESS + char* pProcName; // for PROCADDRESS + + public: + __autohook() = delete; + + __autohook(__fileAutohook* autohook, const char* funcName, LPVOID absoluteAddress, LPVOID* orig, LPVOID func) + : pHookFunc(func), ppOrigFunc(orig), iAbsoluteAddress(absoluteAddress) + { + iAddressResolutionMode = ABSOLUTE_ADDR; + + const int iFuncNameStrlen = strlen(funcName) + 1; + pFuncName = new char[iFuncNameStrlen]; + memcpy(pFuncName, funcName, iFuncNameStrlen); + + autohook->hooks.push_back(this); + } + + __autohook(__fileAutohook* autohook, const char* funcName, const char* addrString, LPVOID* orig, LPVOID func) + : pHookFunc(func), ppOrigFunc(orig) + { + iAddressResolutionMode = OFFSET_STRING; + + const int iFuncNameStrlen = strlen(funcName) + 1; + pFuncName = new char[iFuncNameStrlen]; + memcpy(pFuncName, funcName, iFuncNameStrlen); + + const int iAddrStrlen = strlen(addrString) + 1; + pAddrString = new char[iAddrStrlen]; + memcpy(pAddrString, addrString, iAddrStrlen); + + autohook->hooks.push_back(this); + } + + __autohook(__fileAutohook* autohook, const char* funcName, const char* moduleName, const char* procName, LPVOID* orig, LPVOID func) + : pHookFunc(func), ppOrigFunc(orig) + { + iAddressResolutionMode = PROCADDRESS; + + const int iFuncNameStrlen = strlen(funcName) + 1; + pFuncName = new char[iFuncNameStrlen]; + memcpy(pFuncName, funcName, iFuncNameStrlen); + + const int iModuleNameStrlen = strlen(moduleName) + 1; + pModuleName = new char[iModuleNameStrlen]; + memcpy(pModuleName, moduleName, iModuleNameStrlen); + + const int iProcNameStrlen = strlen(procName) + 1; + pProcName = new char[iProcNameStrlen]; + memcpy(pProcName, procName, iProcNameStrlen); + + autohook->hooks.push_back(this); + } + + ~__autohook() + { + delete[] pFuncName; + + if (pAddrString) + delete[] pAddrString; + + if (pModuleName) + delete[] pModuleName; + + if (pProcName) + delete[] pProcName; + } + + void Dispatch() + { + LPVOID targetAddr = nullptr; + + // determine the address of the function we're hooking + switch (iAddressResolutionMode) + { + case ABSOLUTE_ADDR: + { + targetAddr = iAbsoluteAddress; + break; + } + + case OFFSET_STRING: + { + // in the format server.dll + 0xDEADBEEF + int iDllNameEnd = 0; + for (; !isspace(pAddrString[iDllNameEnd]) && pAddrString[iDllNameEnd] != '+'; iDllNameEnd++) + ; + + char* pModuleName = new char[iDllNameEnd + 1]; + memcpy(pModuleName, pAddrString, iDllNameEnd); + pModuleName[iDllNameEnd] = '\0'; + + // get the module address + const HMODULE pModuleAddr = GetModuleHandleA(pModuleName); + + if (!pModuleAddr) + break; + + // get the offset string + uintptr_t iOffset = 0; + + int iOffsetBegin = iDllNameEnd; + int iOffsetEnd = strlen(pAddrString); + + // seek until we hit the start of the number offset + for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++) + ; + + bool bIsHex = + pAddrString[iOffsetBegin] == '0' && (pAddrString[iOffsetBegin + 1] == 'X' || pAddrString[iOffsetBegin + 1] == 'x'); + if (bIsHex) + iOffset = std::stoi(pAddrString + iOffsetBegin + 2, 0, 16); + else + iOffset = std::stoi(pAddrString + iOffsetBegin); + + targetAddr = (LPVOID)((uintptr_t)pModuleAddr + iOffset); + break; + } + + case PROCADDRESS: + { + targetAddr = GetProcAddress(GetModuleHandleA(pModuleName), pProcName); + break; + } + } + + if (MH_CreateHook(targetAddr, pHookFunc, ppOrigFunc) == MH_OK) + { + if (MH_EnableHook(targetAddr) == MH_OK) + spdlog::info("Enabling hook {}", pFuncName); + else + spdlog::error("MH_EnableHook failed for function {}", pFuncName); + } + else + spdlog::error("MH_CreateHook failed for function {}", pFuncName); + } +}; + +// hook a function at a given offset from a dll to be dispatched with AUTOHOOK_DISPATCH() +#define AUTOHOOK(name, addrString, type, callingConvention, args) \ + type callingConvention CONCAT2(__autohookfunc, name) args; \ + namespace \ + { \ + type(*callingConvention name) args; \ + __autohook CONCAT2(__autohook, __LINE__)( \ + &__FILEAUTOHOOK, __STR(name), __STR(addrString), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ + } \ + type callingConvention CONCAT2(__autohookfunc, name) args + +// hook a function at a given absolute constant address to be dispatched with AUTOHOOK_DISPATCH() +#define AUTOHOOK_ABSOLUTEADDR(name, addr, type, callingConvention, args) \ + type callingConvention CONCAT2(__autohookfunc, name) args; \ + namespace \ + { \ + type(*callingConvention name) args; \ + __autohook \ + CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), addr, (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ + } \ + type callingConvention CONCAT2(__autohookfunc, name) args + +// hook a function at a given module and exported function to be dispatched with AUTOHOOK_DISPATCH() +#define AUTOHOOK_PROCADDRESS(name, moduleName, procName, type, callingConvention, args) \ + type callingConvention CONCAT2(__autohookfunc, name) args; \ + namespace \ + { \ + type(*callingConvention name) args; \ + __autohook CONCAT2(__autohook, __LINE__)( \ + &__FILEAUTOHOOK, __STR(name), __STR(moduleName), __STR(procName), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \ + } \ + type callingConvention CONCAT2(__autohookfunc, name) \ + args + +class ManualHook +{ + public: + char* pFuncName; + + LPVOID pHookFunc; + LPVOID* ppOrigFunc; + + public: + ManualHook() = delete; + ManualHook(const char* funcName, LPVOID func); + ManualHook(const char* funcName, LPVOID* orig, LPVOID func); + bool Dispatch(LPVOID addr, LPVOID* orig = nullptr); +}; + +// hook a function to be dispatched manually later +#define HOOK(varName, originalFunc, type, callingConvention, args) \ + namespace \ + { \ + type(*callingConvention originalFunc) args; \ + } \ + type callingConvention CONCAT2(__manualhookfunc, varName) args; \ + ManualHook varName = ManualHook(__STR(varName), (LPVOID*)&originalFunc, (LPVOID)CONCAT2(__manualhookfunc, varName)); \ + type callingConvention CONCAT2(__manualhookfunc, varName) args + +#define HOOK_NOORIG(varName, type, callingConvention, args) \ + type callingConvention CONCAT2(__manualhookfunc, varName) args; \ + ManualHook varName = ManualHook(__STR(varName), (LPVOID)CONCAT2(__manualhookfunc, varName)); \ + type callingConvention CONCAT2(__manualhookfunc, varName) \ + args + +void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName = ""); +#define MAKEHOOK(pTarget, pDetour, ppOriginal) MakeHook(pTarget, pDetour, ppOriginal, __STR(pDetour)) diff --git a/NorthstarDLL/host.cpp b/NorthstarDLL/host.cpp new file mode 100644 index 00000000..e8cb9bdc --- /dev/null +++ b/NorthstarDLL/host.cpp @@ -0,0 +1,73 @@ +#include "pch.h" +#include "convar.h" +#include "modmanager.h" +#include "printcommand.h" +#include "printmaps.h" +#include "r2engine.h" + +AUTOHOOK_INIT() + +// clang-format off +AUTOHOOK(Host_Init, engine.dll + 0x155EA0, +void, __fastcall, (bool bDedicated)) +// clang-format on +{ + spdlog::info("Host_Init()"); + Host_Init(bDedicated); + + // get all mod convars + std::vector<std::string> vModConvarNames; + for (auto& mod : g_pModManager->m_LoadedMods) + for (auto& cvar : mod.ConVars) + vModConvarNames.push_back(cvar->Name); + + // strip hidden and devonly cvar flags + int iNumCvarsAltered = 0; + for (auto& pair : R2::g_pCVar->DumpToMap()) + { + // don't remove from mod cvars + if (std::find(vModConvarNames.begin(), vModConvarNames.end(), pair.second->m_pszName) != vModConvarNames.end()) + continue; + + // strip flags + int flags = pair.second->GetFlags(); + if (flags & FCVAR_DEVELOPMENTONLY) + { + flags &= ~FCVAR_DEVELOPMENTONLY; + iNumCvarsAltered++; + } + + if (flags & FCVAR_HIDDEN) + { + flags &= ~FCVAR_HIDDEN; + iNumCvarsAltered++; + } + + pair.second->m_nFlags = flags; + } + + spdlog::info("Removed {} hidden/devonly cvar flags", iNumCvarsAltered); + + // make servers able to run disconnect on clients + R2::g_pCVar->FindCommand("disconnect")->m_nFlags |= FCVAR_SERVER_CAN_EXECUTE; + + // make clients able to run status and ping + R2::g_pCVar->FindCommand("status")->m_nFlags |= FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS; + R2::g_pCVar->FindCommand("ping")->m_nFlags |= FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS; + + // need to initialise these after host_init since they do stuff to preexisting concommands/convars without being client/server specific + InitialiseCommandPrint(); + InitialiseMapsPrint(); + + // client/server autoexecs on necessary platforms + // dedi needs autoexec_ns_server on boot, while non-dedi will run it on on listen server start + if (bDedicated) + R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", R2::cmd_source_t::kCommandSrcCode); + else + R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "exec autoexec_ns_client", R2::cmd_source_t::kCommandSrcCode); +} + +ON_DLL_LOAD("engine.dll", Host_Init, (CModule module)) +{ + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDLL/hoststate.cpp b/NorthstarDLL/hoststate.cpp new file mode 100644 index 00000000..adbcde3b --- /dev/null +++ b/NorthstarDLL/hoststate.cpp @@ -0,0 +1,116 @@ +#include "pch.h" +#include "hoststate.h" +#include "masterserver.h" +#include "serverauthentication.h" +#include "serverpresence.h" +#include "playlist.h" +#include "tier0.h" +#include "r2engine.h" +#include "limits.h" + +AUTOHOOK_INIT() + +using namespace R2; + +// use the R2 namespace for game funcs +namespace R2 +{ + CHostState* g_pHostState; +} // namespace R2 + +ConVar* Cvar_hostport; + +void ServerStartingOrChangingMap() +{ + // net_data_block_enabled is required for sp, force it if we're on an sp map + // sucks for security but just how it be + if (!strncmp(g_pHostState->m_levelName, "sp_", 3)) + g_pCVar->FindVar("net_data_block_enabled")->SetValue(true); +} + +// clang-format off +AUTOHOOK(CHostState__State_NewGame, engine.dll + 0x16E7D0, +void, __fastcall, (CHostState* self)) +// clang-format on +{ + spdlog::info("HostState: NewGame"); + + Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", cmd_source_t::kCommandSrcCode); + Cbuf_Execute(); + + // need to do this to ensure we don't go to private match + if (g_pServerAuthentication->m_bNeedLocalAuthForNewgame) + SetCurrentPlaylist("tdm"); + + // don't require authentication on singleplayer startup + g_pServerAuthentication->m_bRequireClientAuth = strncmp(g_pHostState->m_levelName, "sp_", 3); + + ServerStartingOrChangingMap(); + + double dStartTime = Tier0::Plat_FloatTime(); + CHostState__State_NewGame(self); + spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime); + + // setup server presence + g_pServerPresence->CreatePresence(); + g_pServerPresence->SetMap(g_pHostState->m_levelName, true); + g_pServerPresence->SetPlaylist(GetCurrentPlaylistName()); + g_pServerPresence->SetPort(Cvar_hostport->GetInt()); + + g_pServerAuthentication->StartPlayerAuthServer(); + g_pServerAuthentication->m_bNeedLocalAuthForNewgame = false; +} + +// clang-format off +AUTOHOOK(CHostState__State_ChangeLevelMP, engine.dll + 0x16E520, +void, __fastcall, (CHostState* self)) +// clang-format on +{ + spdlog::info("HostState: ChangeLevelMP"); + + ServerStartingOrChangingMap(); + + double dStartTime = Tier0::Plat_FloatTime(); + CHostState__State_ChangeLevelMP(self); + spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime); + + g_pServerPresence->SetMap(g_pHostState->m_levelName); +} + +// clang-format off +AUTOHOOK(CHostState__State_GameShutdown, engine.dll + 0x16E640, +void, __fastcall, (CHostState* self)) +// clang-format on +{ + spdlog::info("HostState: GameShutdown"); + + g_pServerPresence->DestroyPresence(); + g_pServerAuthentication->StopPlayerAuthServer(); + + CHostState__State_GameShutdown(self); +} + +// clang-format off +AUTOHOOK(CHostState__FrameUpdate, engine.dll + 0x16DB00, +void, __fastcall, (CHostState* self, double flCurrentTime, float flFrameTime)) +// clang-format on +{ + CHostState__FrameUpdate(self, flCurrentTime, flFrameTime); + + if (*R2::g_pServerState == R2::server_state_t::ss_active) + { + // update server presence + g_pServerPresence->RunFrame(flCurrentTime); + + // update limits for frame + g_pServerLimits->RunFrame(flCurrentTime, flFrameTime); + } +} + +ON_DLL_LOAD_RELIESON("engine.dll", HostState, ConVar, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + g_pHostState = module.Offset(0x7CF180).As<CHostState*>(); + Cvar_hostport = module.Offset(0x13FA6070).As<ConVar*>(); +} diff --git a/NorthstarDLL/hoststate.h b/NorthstarDLL/hoststate.h new file mode 100644 index 00000000..a77385ef --- /dev/null +++ b/NorthstarDLL/hoststate.h @@ -0,0 +1,45 @@ +#pragma once + +// use the R2 namespace for game funxcs +namespace R2 +{ + enum class HostState_t + { + HS_NEW_GAME = 0, + HS_LOAD_GAME, + HS_CHANGE_LEVEL_SP, + HS_CHANGE_LEVEL_MP, + HS_RUN, + HS_GAME_SHUTDOWN, + HS_SHUTDOWN, + HS_RESTART, + }; + + struct CHostState + { + public: + HostState_t m_iCurrentState; + HostState_t m_iNextState; + + float m_vecLocation[3]; + float m_angLocation[3]; + + char m_levelName[32]; + char m_mapGroupName[32]; + char m_landmarkName[32]; + char m_saveName[32]; + float m_flShortFrameTime; // run a few one-tick frames to avoid large timesteps while loading assets + + bool m_activeGame; + bool m_bRememberLocation; + bool m_bBackgroundLevel; + bool m_bWaitingForConnection; + bool m_bLetToolsOverrideLoadGameEnts; // During a load game, this tells Foundry to override ents that are selected in Hammer. + bool m_bSplitScreenConnect; + bool m_bGameHasShutDownAndFlushedMemory; // This is false once we load a map into memory, and set to true once the map is unloaded + // and all memory flushed + bool m_bWorkshopMapDownloadPending; + }; + + extern CHostState* g_pHostState; +} // namespace R2 diff --git a/NorthstarDedicatedTest/include/MinHook.h b/NorthstarDLL/include/MinHook.h index 15c0a875..15c0a875 100644 --- a/NorthstarDedicatedTest/include/MinHook.h +++ b/NorthstarDLL/include/MinHook.h diff --git a/NorthstarDedicatedTest/include/MinHook.x64.lib b/NorthstarDLL/include/MinHook.x64.lib Binary files differindex 213df08f..a346f386 100644 --- a/NorthstarDedicatedTest/include/MinHook.x64.lib +++ b/NorthstarDLL/include/MinHook.x64.lib diff --git a/NorthstarDedicatedTest/include/crypto/__DECC_INCLUDE_EPILOGUE.H b/NorthstarDLL/include/crypto/__DECC_INCLUDE_EPILOGUE.H index e57c0eab..e57c0eab 100644 --- a/NorthstarDedicatedTest/include/crypto/__DECC_INCLUDE_EPILOGUE.H +++ b/NorthstarDLL/include/crypto/__DECC_INCLUDE_EPILOGUE.H diff --git a/NorthstarDedicatedTest/include/crypto/__DECC_INCLUDE_PROLOGUE.H b/NorthstarDLL/include/crypto/__DECC_INCLUDE_PROLOGUE.H index a0139575..a0139575 100644 --- a/NorthstarDedicatedTest/include/crypto/__DECC_INCLUDE_PROLOGUE.H +++ b/NorthstarDLL/include/crypto/__DECC_INCLUDE_PROLOGUE.H diff --git a/NorthstarDedicatedTest/include/crypto/aes_platform.h b/NorthstarDLL/include/crypto/aes_platform.h index e95ad5aa..e95ad5aa 100644 --- a/NorthstarDedicatedTest/include/crypto/aes_platform.h +++ b/NorthstarDLL/include/crypto/aes_platform.h diff --git a/NorthstarDedicatedTest/include/crypto/aria.h b/NorthstarDLL/include/crypto/aria.h index 21a9932e..21a9932e 100644 --- a/NorthstarDedicatedTest/include/crypto/aria.h +++ b/NorthstarDLL/include/crypto/aria.h diff --git a/NorthstarDedicatedTest/include/crypto/asn1.h b/NorthstarDLL/include/crypto/asn1.h index ec76ae6f..ec76ae6f 100644 --- a/NorthstarDedicatedTest/include/crypto/asn1.h +++ b/NorthstarDLL/include/crypto/asn1.h diff --git a/NorthstarDedicatedTest/include/crypto/asn1_dsa.h b/NorthstarDLL/include/crypto/asn1_dsa.h index 3eadb9ec..3eadb9ec 100644 --- a/NorthstarDedicatedTest/include/crypto/asn1_dsa.h +++ b/NorthstarDLL/include/crypto/asn1_dsa.h diff --git a/NorthstarDedicatedTest/include/crypto/asn1err.h b/NorthstarDLL/include/crypto/asn1err.h index 6441386b..6441386b 100644 --- a/NorthstarDedicatedTest/include/crypto/asn1err.h +++ b/NorthstarDLL/include/crypto/asn1err.h diff --git a/NorthstarDedicatedTest/include/crypto/async.h b/NorthstarDLL/include/crypto/async.h index 7bc0dbb6..7bc0dbb6 100644 --- a/NorthstarDedicatedTest/include/crypto/async.h +++ b/NorthstarDLL/include/crypto/async.h diff --git a/NorthstarDedicatedTest/include/crypto/asyncerr.h b/NorthstarDLL/include/crypto/asyncerr.h index 574e0af7..574e0af7 100644 --- a/NorthstarDedicatedTest/include/crypto/asyncerr.h +++ b/NorthstarDLL/include/crypto/asyncerr.h diff --git a/NorthstarDedicatedTest/include/crypto/bioerr.h b/NorthstarDLL/include/crypto/bioerr.h index a0c06099..a0c06099 100644 --- a/NorthstarDedicatedTest/include/crypto/bioerr.h +++ b/NorthstarDLL/include/crypto/bioerr.h diff --git a/NorthstarDedicatedTest/include/crypto/bn.h b/NorthstarDLL/include/crypto/bn.h index cf69bea8..cf69bea8 100644 --- a/NorthstarDedicatedTest/include/crypto/bn.h +++ b/NorthstarDLL/include/crypto/bn.h diff --git a/NorthstarDedicatedTest/include/crypto/bn_conf.h b/NorthstarDLL/include/crypto/bn_conf.h index a6f73d4a..a6f73d4a 100644 --- a/NorthstarDedicatedTest/include/crypto/bn_conf.h +++ b/NorthstarDLL/include/crypto/bn_conf.h diff --git a/NorthstarDedicatedTest/include/crypto/bn_conf.h.in b/NorthstarDLL/include/crypto/bn_conf.h.in index dbc901b1..dbc901b1 100644 --- a/NorthstarDedicatedTest/include/crypto/bn_conf.h.in +++ b/NorthstarDLL/include/crypto/bn_conf.h.in diff --git a/NorthstarDedicatedTest/include/crypto/bn_dh.h b/NorthstarDLL/include/crypto/bn_dh.h index 6d12c20e..6d12c20e 100644 --- a/NorthstarDedicatedTest/include/crypto/bn_dh.h +++ b/NorthstarDLL/include/crypto/bn_dh.h diff --git a/NorthstarDedicatedTest/include/crypto/bn_srp.h b/NorthstarDLL/include/crypto/bn_srp.h index 00b160aa..00b160aa 100644 --- a/NorthstarDedicatedTest/include/crypto/bn_srp.h +++ b/NorthstarDLL/include/crypto/bn_srp.h diff --git a/NorthstarDedicatedTest/include/crypto/bnerr.h b/NorthstarDLL/include/crypto/bnerr.h index 7282c915..7282c915 100644 --- a/NorthstarDedicatedTest/include/crypto/bnerr.h +++ b/NorthstarDLL/include/crypto/bnerr.h diff --git a/NorthstarDedicatedTest/include/crypto/buffererr.h b/NorthstarDLL/include/crypto/buffererr.h index 54976d95..54976d95 100644 --- a/NorthstarDedicatedTest/include/crypto/buffererr.h +++ b/NorthstarDLL/include/crypto/buffererr.h diff --git a/NorthstarDedicatedTest/include/crypto/chacha.h b/NorthstarDLL/include/crypto/chacha.h index d29998ff..d29998ff 100644 --- a/NorthstarDedicatedTest/include/crypto/chacha.h +++ b/NorthstarDLL/include/crypto/chacha.h diff --git a/NorthstarDedicatedTest/include/crypto/cmll_platform.h b/NorthstarDLL/include/crypto/cmll_platform.h index 8cadadf6..8cadadf6 100644 --- a/NorthstarDedicatedTest/include/crypto/cmll_platform.h +++ b/NorthstarDLL/include/crypto/cmll_platform.h diff --git a/NorthstarDedicatedTest/include/crypto/cmperr.h b/NorthstarDLL/include/crypto/cmperr.h index ac61dd48..ac61dd48 100644 --- a/NorthstarDedicatedTest/include/crypto/cmperr.h +++ b/NorthstarDLL/include/crypto/cmperr.h diff --git a/NorthstarDedicatedTest/include/crypto/cmserr.h b/NorthstarDLL/include/crypto/cmserr.h index 1de2f9c7..1de2f9c7 100644 --- a/NorthstarDedicatedTest/include/crypto/cmserr.h +++ b/NorthstarDLL/include/crypto/cmserr.h diff --git a/NorthstarDedicatedTest/include/crypto/comperr.h b/NorthstarDLL/include/crypto/comperr.h index 0fd9c6de..0fd9c6de 100644 --- a/NorthstarDedicatedTest/include/crypto/comperr.h +++ b/NorthstarDLL/include/crypto/comperr.h diff --git a/NorthstarDedicatedTest/include/crypto/conferr.h b/NorthstarDLL/include/crypto/conferr.h index cb367e4f..cb367e4f 100644 --- a/NorthstarDedicatedTest/include/crypto/conferr.h +++ b/NorthstarDLL/include/crypto/conferr.h diff --git a/NorthstarDedicatedTest/include/crypto/crmferr.h b/NorthstarDLL/include/crypto/crmferr.h index f1a27e04..f1a27e04 100644 --- a/NorthstarDedicatedTest/include/crypto/crmferr.h +++ b/NorthstarDLL/include/crypto/crmferr.h diff --git a/NorthstarDedicatedTest/include/crypto/cryptlib.h b/NorthstarDLL/include/crypto/cryptlib.h index 39a956bf..39a956bf 100644 --- a/NorthstarDedicatedTest/include/crypto/cryptlib.h +++ b/NorthstarDLL/include/crypto/cryptlib.h diff --git a/NorthstarDedicatedTest/include/crypto/cryptoerr.h b/NorthstarDLL/include/crypto/cryptoerr.h index 288b87ac..288b87ac 100644 --- a/NorthstarDedicatedTest/include/crypto/cryptoerr.h +++ b/NorthstarDLL/include/crypto/cryptoerr.h diff --git a/NorthstarDedicatedTest/include/crypto/cterr.h b/NorthstarDLL/include/crypto/cterr.h index 760bc796..760bc796 100644 --- a/NorthstarDedicatedTest/include/crypto/cterr.h +++ b/NorthstarDLL/include/crypto/cterr.h diff --git a/NorthstarDedicatedTest/include/crypto/ctype.h b/NorthstarDLL/include/crypto/ctype.h index a35c137e..a35c137e 100644 --- a/NorthstarDedicatedTest/include/crypto/ctype.h +++ b/NorthstarDLL/include/crypto/ctype.h diff --git a/NorthstarDedicatedTest/include/crypto/decoder.h b/NorthstarDLL/include/crypto/decoder.h index cc06ef29..cc06ef29 100644 --- a/NorthstarDedicatedTest/include/crypto/decoder.h +++ b/NorthstarDLL/include/crypto/decoder.h diff --git a/NorthstarDedicatedTest/include/crypto/decodererr.h b/NorthstarDLL/include/crypto/decodererr.h index d7badc43..d7badc43 100644 --- a/NorthstarDedicatedTest/include/crypto/decodererr.h +++ b/NorthstarDLL/include/crypto/decodererr.h diff --git a/NorthstarDedicatedTest/include/crypto/des_platform.h b/NorthstarDLL/include/crypto/des_platform.h index 07ea1ddd..07ea1ddd 100644 --- a/NorthstarDedicatedTest/include/crypto/des_platform.h +++ b/NorthstarDLL/include/crypto/des_platform.h diff --git a/NorthstarDedicatedTest/include/crypto/dh.h b/NorthstarDLL/include/crypto/dh.h index f6be4ae0..f6be4ae0 100644 --- a/NorthstarDedicatedTest/include/crypto/dh.h +++ b/NorthstarDLL/include/crypto/dh.h diff --git a/NorthstarDedicatedTest/include/crypto/dherr.h b/NorthstarDLL/include/crypto/dherr.h index bb24d131..bb24d131 100644 --- a/NorthstarDedicatedTest/include/crypto/dherr.h +++ b/NorthstarDLL/include/crypto/dherr.h diff --git a/NorthstarDedicatedTest/include/crypto/dsa.h b/NorthstarDLL/include/crypto/dsa.h index eedbd8c7..eedbd8c7 100644 --- a/NorthstarDedicatedTest/include/crypto/dsa.h +++ b/NorthstarDLL/include/crypto/dsa.h diff --git a/NorthstarDedicatedTest/include/crypto/dsaerr.h b/NorthstarDLL/include/crypto/dsaerr.h index 9898097d..9898097d 100644 --- a/NorthstarDedicatedTest/include/crypto/dsaerr.h +++ b/NorthstarDLL/include/crypto/dsaerr.h diff --git a/NorthstarDedicatedTest/include/crypto/dso_conf.h b/NorthstarDLL/include/crypto/dso_conf.h index 99514321..99514321 100644 --- a/NorthstarDedicatedTest/include/crypto/dso_conf.h +++ b/NorthstarDLL/include/crypto/dso_conf.h diff --git a/NorthstarDedicatedTest/include/crypto/dso_conf.h.in b/NorthstarDLL/include/crypto/dso_conf.h.in index 12de11ad..12de11ad 100644 --- a/NorthstarDedicatedTest/include/crypto/dso_conf.h.in +++ b/NorthstarDLL/include/crypto/dso_conf.h.in diff --git a/NorthstarDedicatedTest/include/crypto/ec.h b/NorthstarDLL/include/crypto/ec.h index 62163b31..62163b31 100644 --- a/NorthstarDedicatedTest/include/crypto/ec.h +++ b/NorthstarDLL/include/crypto/ec.h diff --git a/NorthstarDedicatedTest/include/crypto/ecerr.h b/NorthstarDLL/include/crypto/ecerr.h index 07b6c7aa..07b6c7aa 100644 --- a/NorthstarDedicatedTest/include/crypto/ecerr.h +++ b/NorthstarDLL/include/crypto/ecerr.h diff --git a/NorthstarDedicatedTest/include/crypto/ecx.h b/NorthstarDLL/include/crypto/ecx.h index 48b95fa5..48b95fa5 100644 --- a/NorthstarDedicatedTest/include/crypto/ecx.h +++ b/NorthstarDLL/include/crypto/ecx.h diff --git a/NorthstarDedicatedTest/include/crypto/encoder.h b/NorthstarDLL/include/crypto/encoder.h index 09d445d2..09d445d2 100644 --- a/NorthstarDedicatedTest/include/crypto/encoder.h +++ b/NorthstarDLL/include/crypto/encoder.h diff --git a/NorthstarDedicatedTest/include/crypto/encodererr.h b/NorthstarDLL/include/crypto/encodererr.h index 56c45823..56c45823 100644 --- a/NorthstarDedicatedTest/include/crypto/encodererr.h +++ b/NorthstarDLL/include/crypto/encodererr.h diff --git a/NorthstarDedicatedTest/include/crypto/engine.h b/NorthstarDLL/include/crypto/engine.h index fac6ed09..fac6ed09 100644 --- a/NorthstarDedicatedTest/include/crypto/engine.h +++ b/NorthstarDLL/include/crypto/engine.h diff --git a/NorthstarDedicatedTest/include/crypto/engineerr.h b/NorthstarDLL/include/crypto/engineerr.h index 737c841d..737c841d 100644 --- a/NorthstarDedicatedTest/include/crypto/engineerr.h +++ b/NorthstarDLL/include/crypto/engineerr.h diff --git a/NorthstarDedicatedTest/include/crypto/err.h b/NorthstarDLL/include/crypto/err.h index 15ec6fd0..15ec6fd0 100644 --- a/NorthstarDedicatedTest/include/crypto/err.h +++ b/NorthstarDLL/include/crypto/err.h diff --git a/NorthstarDedicatedTest/include/crypto/ess.h b/NorthstarDLL/include/crypto/ess.h index 7acde5f8..7acde5f8 100644 --- a/NorthstarDedicatedTest/include/crypto/ess.h +++ b/NorthstarDLL/include/crypto/ess.h diff --git a/NorthstarDedicatedTest/include/crypto/esserr.h b/NorthstarDLL/include/crypto/esserr.h index 8df2df11..8df2df11 100644 --- a/NorthstarDedicatedTest/include/crypto/esserr.h +++ b/NorthstarDLL/include/crypto/esserr.h diff --git a/NorthstarDedicatedTest/include/crypto/evp.h b/NorthstarDLL/include/crypto/evp.h index c5d3a930..c5d3a930 100644 --- a/NorthstarDedicatedTest/include/crypto/evp.h +++ b/NorthstarDLL/include/crypto/evp.h diff --git a/NorthstarDedicatedTest/include/crypto/evperr.h b/NorthstarDLL/include/crypto/evperr.h index d90ba83f..d90ba83f 100644 --- a/NorthstarDedicatedTest/include/crypto/evperr.h +++ b/NorthstarDLL/include/crypto/evperr.h diff --git a/NorthstarDedicatedTest/include/crypto/httperr.h b/NorthstarDLL/include/crypto/httperr.h index 969df17b..969df17b 100644 --- a/NorthstarDedicatedTest/include/crypto/httperr.h +++ b/NorthstarDLL/include/crypto/httperr.h diff --git a/NorthstarDedicatedTest/include/crypto/lhash.h b/NorthstarDLL/include/crypto/lhash.h index 0f64869f..0f64869f 100644 --- a/NorthstarDedicatedTest/include/crypto/lhash.h +++ b/NorthstarDLL/include/crypto/lhash.h diff --git a/NorthstarDedicatedTest/include/crypto/md32_common.h b/NorthstarDLL/include/crypto/md32_common.h index 3b16f1b7..3b16f1b7 100644 --- a/NorthstarDedicatedTest/include/crypto/md32_common.h +++ b/NorthstarDLL/include/crypto/md32_common.h diff --git a/NorthstarDedicatedTest/include/crypto/modes.h b/NorthstarDLL/include/crypto/modes.h index 19f9d859..19f9d859 100644 --- a/NorthstarDedicatedTest/include/crypto/modes.h +++ b/NorthstarDLL/include/crypto/modes.h diff --git a/NorthstarDedicatedTest/include/crypto/objects.h b/NorthstarDLL/include/crypto/objects.h index f22e9287..f22e9287 100644 --- a/NorthstarDedicatedTest/include/crypto/objects.h +++ b/NorthstarDLL/include/crypto/objects.h diff --git a/NorthstarDedicatedTest/include/crypto/objectserr.h b/NorthstarDLL/include/crypto/objectserr.h index ec994824..ec994824 100644 --- a/NorthstarDedicatedTest/include/crypto/objectserr.h +++ b/NorthstarDLL/include/crypto/objectserr.h diff --git a/NorthstarDedicatedTest/include/crypto/ocsperr.h b/NorthstarDLL/include/crypto/ocsperr.h index f9529b2a..f9529b2a 100644 --- a/NorthstarDedicatedTest/include/crypto/ocsperr.h +++ b/NorthstarDLL/include/crypto/ocsperr.h diff --git a/NorthstarDedicatedTest/include/crypto/pem.h b/NorthstarDLL/include/crypto/pem.h index 840dc18f..840dc18f 100644 --- a/NorthstarDedicatedTest/include/crypto/pem.h +++ b/NorthstarDLL/include/crypto/pem.h diff --git a/NorthstarDedicatedTest/include/crypto/pemerr.h b/NorthstarDLL/include/crypto/pemerr.h index b255ff5c..b255ff5c 100644 --- a/NorthstarDedicatedTest/include/crypto/pemerr.h +++ b/NorthstarDLL/include/crypto/pemerr.h diff --git a/NorthstarDedicatedTest/include/crypto/pkcs12err.h b/NorthstarDLL/include/crypto/pkcs12err.h index 662f412e..662f412e 100644 --- a/NorthstarDedicatedTest/include/crypto/pkcs12err.h +++ b/NorthstarDLL/include/crypto/pkcs12err.h diff --git a/NorthstarDedicatedTest/include/crypto/pkcs7.h b/NorthstarDLL/include/crypto/pkcs7.h index 9caa9af4..9caa9af4 100644 --- a/NorthstarDedicatedTest/include/crypto/pkcs7.h +++ b/NorthstarDLL/include/crypto/pkcs7.h diff --git a/NorthstarDedicatedTest/include/crypto/pkcs7err.h b/NorthstarDLL/include/crypto/pkcs7err.h index c195190b..c195190b 100644 --- a/NorthstarDedicatedTest/include/crypto/pkcs7err.h +++ b/NorthstarDLL/include/crypto/pkcs7err.h diff --git a/NorthstarDedicatedTest/include/crypto/poly1305.h b/NorthstarDLL/include/crypto/poly1305.h index ba54f3bd..ba54f3bd 100644 --- a/NorthstarDedicatedTest/include/crypto/poly1305.h +++ b/NorthstarDLL/include/crypto/poly1305.h diff --git a/NorthstarDedicatedTest/include/crypto/ppc_arch.h b/NorthstarDLL/include/crypto/ppc_arch.h index 3b3ce4bf..3b3ce4bf 100644 --- a/NorthstarDedicatedTest/include/crypto/ppc_arch.h +++ b/NorthstarDLL/include/crypto/ppc_arch.h diff --git a/NorthstarDedicatedTest/include/crypto/punycode.h b/NorthstarDLL/include/crypto/punycode.h index 133826d8..133826d8 100644 --- a/NorthstarDedicatedTest/include/crypto/punycode.h +++ b/NorthstarDLL/include/crypto/punycode.h diff --git a/NorthstarDedicatedTest/include/crypto/rand.h b/NorthstarDLL/include/crypto/rand.h index fa3b5b2b..fa3b5b2b 100644 --- a/NorthstarDedicatedTest/include/crypto/rand.h +++ b/NorthstarDLL/include/crypto/rand.h diff --git a/NorthstarDedicatedTest/include/crypto/rand_pool.h b/NorthstarDLL/include/crypto/rand_pool.h index f4d1d954..f4d1d954 100644 --- a/NorthstarDedicatedTest/include/crypto/rand_pool.h +++ b/NorthstarDLL/include/crypto/rand_pool.h diff --git a/NorthstarDedicatedTest/include/crypto/randerr.h b/NorthstarDLL/include/crypto/randerr.h index 832a8b7d..832a8b7d 100644 --- a/NorthstarDedicatedTest/include/crypto/randerr.h +++ b/NorthstarDLL/include/crypto/randerr.h diff --git a/NorthstarDedicatedTest/include/crypto/rsa.h b/NorthstarDLL/include/crypto/rsa.h index 100e7ceb..100e7ceb 100644 --- a/NorthstarDedicatedTest/include/crypto/rsa.h +++ b/NorthstarDLL/include/crypto/rsa.h diff --git a/NorthstarDedicatedTest/include/crypto/rsaerr.h b/NorthstarDLL/include/crypto/rsaerr.h index 9b23500b..9b23500b 100644 --- a/NorthstarDedicatedTest/include/crypto/rsaerr.h +++ b/NorthstarDLL/include/crypto/rsaerr.h diff --git a/NorthstarDedicatedTest/include/crypto/security_bits.h b/NorthstarDLL/include/crypto/security_bits.h index 58f49681..58f49681 100644 --- a/NorthstarDedicatedTest/include/crypto/security_bits.h +++ b/NorthstarDLL/include/crypto/security_bits.h diff --git a/NorthstarDedicatedTest/include/crypto/sha.h b/NorthstarDLL/include/crypto/sha.h index 64305d17..64305d17 100644 --- a/NorthstarDedicatedTest/include/crypto/sha.h +++ b/NorthstarDLL/include/crypto/sha.h diff --git a/NorthstarDedicatedTest/include/crypto/siphash.h b/NorthstarDLL/include/crypto/siphash.h index 0d0767fc..0d0767fc 100644 --- a/NorthstarDedicatedTest/include/crypto/siphash.h +++ b/NorthstarDLL/include/crypto/siphash.h diff --git a/NorthstarDedicatedTest/include/crypto/siv.h b/NorthstarDLL/include/crypto/siv.h index 8dc58bd3..8dc58bd3 100644 --- a/NorthstarDedicatedTest/include/crypto/siv.h +++ b/NorthstarDLL/include/crypto/siv.h diff --git a/NorthstarDedicatedTest/include/crypto/sm2.h b/NorthstarDLL/include/crypto/sm2.h index 9ab6c0b7..9ab6c0b7 100644 --- a/NorthstarDedicatedTest/include/crypto/sm2.h +++ b/NorthstarDLL/include/crypto/sm2.h diff --git a/NorthstarDedicatedTest/include/crypto/sm2err.h b/NorthstarDLL/include/crypto/sm2err.h index 706f4d69..706f4d69 100644 --- a/NorthstarDedicatedTest/include/crypto/sm2err.h +++ b/NorthstarDLL/include/crypto/sm2err.h diff --git a/NorthstarDedicatedTest/include/crypto/sm4.h b/NorthstarDLL/include/crypto/sm4.h index e21ec81c..e21ec81c 100644 --- a/NorthstarDedicatedTest/include/crypto/sm4.h +++ b/NorthstarDLL/include/crypto/sm4.h diff --git a/NorthstarDedicatedTest/include/crypto/sparc_arch.h b/NorthstarDLL/include/crypto/sparc_arch.h index 447e715b..447e715b 100644 --- a/NorthstarDedicatedTest/include/crypto/sparc_arch.h +++ b/NorthstarDLL/include/crypto/sparc_arch.h diff --git a/NorthstarDedicatedTest/include/crypto/sparse_array.h b/NorthstarDLL/include/crypto/sparse_array.h index 7ef74283..7ef74283 100644 --- a/NorthstarDedicatedTest/include/crypto/sparse_array.h +++ b/NorthstarDLL/include/crypto/sparse_array.h diff --git a/NorthstarDedicatedTest/include/crypto/store.h b/NorthstarDLL/include/crypto/store.h index 13d2646b..13d2646b 100644 --- a/NorthstarDedicatedTest/include/crypto/store.h +++ b/NorthstarDLL/include/crypto/store.h diff --git a/NorthstarDedicatedTest/include/crypto/storeerr.h b/NorthstarDLL/include/crypto/storeerr.h index c46d845f..c46d845f 100644 --- a/NorthstarDedicatedTest/include/crypto/storeerr.h +++ b/NorthstarDLL/include/crypto/storeerr.h diff --git a/NorthstarDedicatedTest/include/crypto/tserr.h b/NorthstarDLL/include/crypto/tserr.h index 2f34ba31..2f34ba31 100644 --- a/NorthstarDedicatedTest/include/crypto/tserr.h +++ b/NorthstarDLL/include/crypto/tserr.h diff --git a/NorthstarDedicatedTest/include/crypto/types.h b/NorthstarDLL/include/crypto/types.h index 0d814040..0d814040 100644 --- a/NorthstarDedicatedTest/include/crypto/types.h +++ b/NorthstarDLL/include/crypto/types.h diff --git a/NorthstarDedicatedTest/include/crypto/uierr.h b/NorthstarDLL/include/crypto/uierr.h index 789077a8..789077a8 100644 --- a/NorthstarDedicatedTest/include/crypto/uierr.h +++ b/NorthstarDLL/include/crypto/uierr.h diff --git a/NorthstarDedicatedTest/include/crypto/x509.h b/NorthstarDLL/include/crypto/x509.h index 1f00178e..1f00178e 100644 --- a/NorthstarDedicatedTest/include/crypto/x509.h +++ b/NorthstarDLL/include/crypto/x509.h diff --git a/NorthstarDedicatedTest/include/crypto/x509err.h b/NorthstarDLL/include/crypto/x509err.h index 53f567d9..53f567d9 100644 --- a/NorthstarDedicatedTest/include/crypto/x509err.h +++ b/NorthstarDLL/include/crypto/x509err.h diff --git a/NorthstarDedicatedTest/include/crypto/x509v3err.h b/NorthstarDLL/include/crypto/x509v3err.h index 66d3ad92..66d3ad92 100644 --- a/NorthstarDedicatedTest/include/crypto/x509v3err.h +++ b/NorthstarDLL/include/crypto/x509v3err.h diff --git a/NorthstarDedicatedTest/include/httplib.h b/NorthstarDLL/include/httplib.h index 2b52f0fc..2b52f0fc 100644 --- a/NorthstarDedicatedTest/include/httplib.h +++ b/NorthstarDLL/include/httplib.h diff --git a/NorthstarDedicatedTest/include/internal/__DECC_INCLUDE_EPILOGUE.H b/NorthstarDLL/include/internal/__DECC_INCLUDE_EPILOGUE.H index e57c0eab..e57c0eab 100644 --- a/NorthstarDedicatedTest/include/internal/__DECC_INCLUDE_EPILOGUE.H +++ b/NorthstarDLL/include/internal/__DECC_INCLUDE_EPILOGUE.H diff --git a/NorthstarDedicatedTest/include/internal/__DECC_INCLUDE_PROLOGUE.H b/NorthstarDLL/include/internal/__DECC_INCLUDE_PROLOGUE.H index a0139575..a0139575 100644 --- a/NorthstarDedicatedTest/include/internal/__DECC_INCLUDE_PROLOGUE.H +++ b/NorthstarDLL/include/internal/__DECC_INCLUDE_PROLOGUE.H diff --git a/NorthstarDedicatedTest/include/internal/asn1.h b/NorthstarDLL/include/internal/asn1.h index 3143e340..3143e340 100644 --- a/NorthstarDedicatedTest/include/internal/asn1.h +++ b/NorthstarDLL/include/internal/asn1.h diff --git a/NorthstarDedicatedTest/include/internal/bio.h b/NorthstarDLL/include/internal/bio.h index 2d36a7b9..2d36a7b9 100644 --- a/NorthstarDedicatedTest/include/internal/bio.h +++ b/NorthstarDLL/include/internal/bio.h diff --git a/NorthstarDedicatedTest/include/internal/comp.h b/NorthstarDLL/include/internal/comp.h index 3ad86fc7..3ad86fc7 100644 --- a/NorthstarDedicatedTest/include/internal/comp.h +++ b/NorthstarDLL/include/internal/comp.h diff --git a/NorthstarDedicatedTest/include/internal/conf.h b/NorthstarDLL/include/internal/conf.h index 8c6c29cd..8c6c29cd 100644 --- a/NorthstarDedicatedTest/include/internal/conf.h +++ b/NorthstarDLL/include/internal/conf.h diff --git a/NorthstarDedicatedTest/include/internal/constant_time.h b/NorthstarDLL/include/internal/constant_time.h index 0ed6f823..0ed6f823 100644 --- a/NorthstarDedicatedTest/include/internal/constant_time.h +++ b/NorthstarDLL/include/internal/constant_time.h diff --git a/NorthstarDedicatedTest/include/internal/core.h b/NorthstarDLL/include/internal/core.h index d9dc4241..d9dc4241 100644 --- a/NorthstarDedicatedTest/include/internal/core.h +++ b/NorthstarDLL/include/internal/core.h diff --git a/NorthstarDedicatedTest/include/internal/cryptlib.h b/NorthstarDLL/include/internal/cryptlib.h index 1291299b..1291299b 100644 --- a/NorthstarDedicatedTest/include/internal/cryptlib.h +++ b/NorthstarDLL/include/internal/cryptlib.h diff --git a/NorthstarDedicatedTest/include/internal/dane.h b/NorthstarDLL/include/internal/dane.h index a3d78a7f..a3d78a7f 100644 --- a/NorthstarDedicatedTest/include/internal/dane.h +++ b/NorthstarDLL/include/internal/dane.h diff --git a/NorthstarDedicatedTest/include/internal/deprecated.h b/NorthstarDLL/include/internal/deprecated.h index a313a015..a313a015 100644 --- a/NorthstarDedicatedTest/include/internal/deprecated.h +++ b/NorthstarDLL/include/internal/deprecated.h diff --git a/NorthstarDedicatedTest/include/internal/der.h b/NorthstarDLL/include/internal/der.h index a3e56d0d..a3e56d0d 100644 --- a/NorthstarDedicatedTest/include/internal/der.h +++ b/NorthstarDLL/include/internal/der.h diff --git a/NorthstarDedicatedTest/include/internal/dso.h b/NorthstarDLL/include/internal/dso.h index 160ddb98..160ddb98 100644 --- a/NorthstarDedicatedTest/include/internal/dso.h +++ b/NorthstarDLL/include/internal/dso.h diff --git a/NorthstarDedicatedTest/include/internal/dsoerr.h b/NorthstarDLL/include/internal/dsoerr.h index b1719e83..b1719e83 100644 --- a/NorthstarDedicatedTest/include/internal/dsoerr.h +++ b/NorthstarDLL/include/internal/dsoerr.h diff --git a/NorthstarDedicatedTest/include/internal/endian.h b/NorthstarDLL/include/internal/endian.h index 8b34e03e..8b34e03e 100644 --- a/NorthstarDedicatedTest/include/internal/endian.h +++ b/NorthstarDLL/include/internal/endian.h diff --git a/NorthstarDedicatedTest/include/internal/err.h b/NorthstarDLL/include/internal/err.h index d8a308f0..d8a308f0 100644 --- a/NorthstarDedicatedTest/include/internal/err.h +++ b/NorthstarDLL/include/internal/err.h diff --git a/NorthstarDedicatedTest/include/internal/ffc.h b/NorthstarDLL/include/internal/ffc.h index 79cb06ab..79cb06ab 100644 --- a/NorthstarDedicatedTest/include/internal/ffc.h +++ b/NorthstarDLL/include/internal/ffc.h diff --git a/NorthstarDedicatedTest/include/internal/ktls.h b/NorthstarDLL/include/internal/ktls.h index 95492fd0..95492fd0 100644 --- a/NorthstarDedicatedTest/include/internal/ktls.h +++ b/NorthstarDLL/include/internal/ktls.h diff --git a/NorthstarDedicatedTest/include/internal/namemap.h b/NorthstarDLL/include/internal/namemap.h index a4c60ae6..a4c60ae6 100644 --- a/NorthstarDedicatedTest/include/internal/namemap.h +++ b/NorthstarDLL/include/internal/namemap.h diff --git a/NorthstarDedicatedTest/include/internal/nelem.h b/NorthstarDLL/include/internal/nelem.h index b758513b..b758513b 100644 --- a/NorthstarDedicatedTest/include/internal/nelem.h +++ b/NorthstarDLL/include/internal/nelem.h diff --git a/NorthstarDedicatedTest/include/internal/numbers.h b/NorthstarDLL/include/internal/numbers.h index 4f4d3306..4f4d3306 100644 --- a/NorthstarDedicatedTest/include/internal/numbers.h +++ b/NorthstarDLL/include/internal/numbers.h diff --git a/NorthstarDedicatedTest/include/internal/o_dir.h b/NorthstarDLL/include/internal/o_dir.h index add34d14..add34d14 100644 --- a/NorthstarDedicatedTest/include/internal/o_dir.h +++ b/NorthstarDLL/include/internal/o_dir.h diff --git a/NorthstarDedicatedTest/include/internal/packet.h b/NorthstarDLL/include/internal/packet.h index 170997db..170997db 100644 --- a/NorthstarDedicatedTest/include/internal/packet.h +++ b/NorthstarDLL/include/internal/packet.h diff --git a/NorthstarDedicatedTest/include/internal/param_build_set.h b/NorthstarDLL/include/internal/param_build_set.h index 126211b7..126211b7 100644 --- a/NorthstarDedicatedTest/include/internal/param_build_set.h +++ b/NorthstarDLL/include/internal/param_build_set.h diff --git a/NorthstarDedicatedTest/include/internal/passphrase.h b/NorthstarDLL/include/internal/passphrase.h index 54d997b0..54d997b0 100644 --- a/NorthstarDedicatedTest/include/internal/passphrase.h +++ b/NorthstarDLL/include/internal/passphrase.h diff --git a/NorthstarDedicatedTest/include/internal/property.h b/NorthstarDLL/include/internal/property.h index 82119745..82119745 100644 --- a/NorthstarDedicatedTest/include/internal/property.h +++ b/NorthstarDLL/include/internal/property.h diff --git a/NorthstarDedicatedTest/include/internal/propertyerr.h b/NorthstarDLL/include/internal/propertyerr.h index fbee53f1..fbee53f1 100644 --- a/NorthstarDedicatedTest/include/internal/propertyerr.h +++ b/NorthstarDLL/include/internal/propertyerr.h diff --git a/NorthstarDedicatedTest/include/internal/provider.h b/NorthstarDLL/include/internal/provider.h index d09829d0..d09829d0 100644 --- a/NorthstarDedicatedTest/include/internal/provider.h +++ b/NorthstarDLL/include/internal/provider.h diff --git a/NorthstarDedicatedTest/include/internal/refcount.h b/NorthstarDLL/include/internal/refcount.h index 7412d62f..7412d62f 100644 --- a/NorthstarDedicatedTest/include/internal/refcount.h +++ b/NorthstarDLL/include/internal/refcount.h diff --git a/NorthstarDedicatedTest/include/internal/sha3.h b/NorthstarDLL/include/internal/sha3.h index 80ad86e5..80ad86e5 100644 --- a/NorthstarDedicatedTest/include/internal/sha3.h +++ b/NorthstarDLL/include/internal/sha3.h diff --git a/NorthstarDedicatedTest/include/internal/sizes.h b/NorthstarDLL/include/internal/sizes.h index f6496c81..f6496c81 100644 --- a/NorthstarDedicatedTest/include/internal/sizes.h +++ b/NorthstarDLL/include/internal/sizes.h diff --git a/NorthstarDedicatedTest/include/internal/sm3.h b/NorthstarDLL/include/internal/sm3.h index db1d61f0..db1d61f0 100644 --- a/NorthstarDedicatedTest/include/internal/sm3.h +++ b/NorthstarDLL/include/internal/sm3.h diff --git a/NorthstarDedicatedTest/include/internal/sockets.h b/NorthstarDLL/include/internal/sockets.h index 6e882fa6..6e882fa6 100644 --- a/NorthstarDedicatedTest/include/internal/sockets.h +++ b/NorthstarDLL/include/internal/sockets.h diff --git a/NorthstarDedicatedTest/include/internal/sslconf.h b/NorthstarDLL/include/internal/sslconf.h index fd7f7e33..fd7f7e33 100644 --- a/NorthstarDedicatedTest/include/internal/sslconf.h +++ b/NorthstarDLL/include/internal/sslconf.h diff --git a/NorthstarDedicatedTest/include/internal/symhacks.h b/NorthstarDLL/include/internal/symhacks.h index 33bae51e..33bae51e 100644 --- a/NorthstarDedicatedTest/include/internal/symhacks.h +++ b/NorthstarDLL/include/internal/symhacks.h diff --git a/NorthstarDedicatedTest/include/internal/thread_once.h b/NorthstarDLL/include/internal/thread_once.h index d6cb2eee..d6cb2eee 100644 --- a/NorthstarDedicatedTest/include/internal/thread_once.h +++ b/NorthstarDLL/include/internal/thread_once.h diff --git a/NorthstarDedicatedTest/include/internal/tlsgroups.h b/NorthstarDLL/include/internal/tlsgroups.h index 8a35ced1..8a35ced1 100644 --- a/NorthstarDedicatedTest/include/internal/tlsgroups.h +++ b/NorthstarDLL/include/internal/tlsgroups.h diff --git a/NorthstarDedicatedTest/include/internal/tsan_assist.h b/NorthstarDLL/include/internal/tsan_assist.h index f8285b1d..f8285b1d 100644 --- a/NorthstarDedicatedTest/include/internal/tsan_assist.h +++ b/NorthstarDLL/include/internal/tsan_assist.h diff --git a/NorthstarDedicatedTest/include/internal/unicode.h b/NorthstarDLL/include/internal/unicode.h index a6de8352..a6de8352 100644 --- a/NorthstarDedicatedTest/include/internal/unicode.h +++ b/NorthstarDLL/include/internal/unicode.h diff --git a/NorthstarDedicatedTest/include/libcrypto_static.lib b/NorthstarDLL/include/libcrypto_static.lib Binary files differindex 26c68964..0ddd830c 100644 --- a/NorthstarDedicatedTest/include/libcrypto_static.lib +++ b/NorthstarDLL/include/libcrypto_static.lib diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/curl.h b/NorthstarDLL/include/libcurl/include/curl/curl.h index 7b69ce2d..7b69ce2d 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/curl.h +++ b/NorthstarDLL/include/libcurl/include/curl/curl.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/curlver.h b/NorthstarDLL/include/libcurl/include/curl/curlver.h index fe57e430..fe57e430 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/curlver.h +++ b/NorthstarDLL/include/libcurl/include/curl/curlver.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/easy.h b/NorthstarDLL/include/libcurl/include/curl/easy.h index 2dbfb26b..2dbfb26b 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/easy.h +++ b/NorthstarDLL/include/libcurl/include/curl/easy.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/mprintf.h b/NorthstarDLL/include/libcurl/include/curl/mprintf.h index 3549552d..3549552d 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/mprintf.h +++ b/NorthstarDLL/include/libcurl/include/curl/mprintf.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/multi.h b/NorthstarDLL/include/libcurl/include/curl/multi.h index 91cd95d3..91cd95d3 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/multi.h +++ b/NorthstarDLL/include/libcurl/include/curl/multi.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/options.h b/NorthstarDLL/include/libcurl/include/curl/options.h index 14373b55..14373b55 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/options.h +++ b/NorthstarDLL/include/libcurl/include/curl/options.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/stdcheaders.h b/NorthstarDLL/include/libcurl/include/curl/stdcheaders.h index 60596c75..60596c75 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/stdcheaders.h +++ b/NorthstarDLL/include/libcurl/include/curl/stdcheaders.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/system.h b/NorthstarDLL/include/libcurl/include/curl/system.h index faf8fcf8..faf8fcf8 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/system.h +++ b/NorthstarDLL/include/libcurl/include/curl/system.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/typecheck-gcc.h b/NorthstarDLL/include/libcurl/include/curl/typecheck-gcc.h index 9e14d8a3..9e14d8a3 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/typecheck-gcc.h +++ b/NorthstarDLL/include/libcurl/include/curl/typecheck-gcc.h diff --git a/NorthstarDedicatedTest/include/libcurl/include/curl/urlapi.h b/NorthstarDLL/include/libcurl/include/curl/urlapi.h index a475f91b..a475f91b 100644 --- a/NorthstarDedicatedTest/include/libcurl/include/curl/urlapi.h +++ b/NorthstarDLL/include/libcurl/include/curl/urlapi.h diff --git a/NorthstarDedicatedTest/include/libcurl/lib/libcurl_a.lib b/NorthstarDLL/include/libcurl/lib/libcurl_a.lib Binary files differindex f0fa49f2..32b917c9 100644 --- a/NorthstarDedicatedTest/include/libcurl/lib/libcurl_a.lib +++ b/NorthstarDLL/include/libcurl/lib/libcurl_a.lib diff --git a/NorthstarDedicatedTest/include/libssl_static.lib b/NorthstarDLL/include/libssl_static.lib Binary files differindex 3411cb57..f7916421 100644 --- a/NorthstarDedicatedTest/include/libssl_static.lib +++ b/NorthstarDLL/include/libssl_static.lib diff --git a/NorthstarDedicatedTest/include/openssl/__DECC_INCLUDE_EPILOGUE.H b/NorthstarDLL/include/openssl/__DECC_INCLUDE_EPILOGUE.H index d251d0a0..d251d0a0 100644 --- a/NorthstarDedicatedTest/include/openssl/__DECC_INCLUDE_EPILOGUE.H +++ b/NorthstarDLL/include/openssl/__DECC_INCLUDE_EPILOGUE.H diff --git a/NorthstarDedicatedTest/include/openssl/__DECC_INCLUDE_PROLOGUE.H b/NorthstarDLL/include/openssl/__DECC_INCLUDE_PROLOGUE.H index 91ac6b33..91ac6b33 100644 --- a/NorthstarDedicatedTest/include/openssl/__DECC_INCLUDE_PROLOGUE.H +++ b/NorthstarDLL/include/openssl/__DECC_INCLUDE_PROLOGUE.H diff --git a/NorthstarDedicatedTest/include/openssl/aes.h b/NorthstarDLL/include/openssl/aes.h index d0f9dfc6..d0f9dfc6 100644 --- a/NorthstarDedicatedTest/include/openssl/aes.h +++ b/NorthstarDLL/include/openssl/aes.h diff --git a/NorthstarDedicatedTest/include/openssl/asn1.h b/NorthstarDLL/include/openssl/asn1.h index aada23dc..aada23dc 100644 --- a/NorthstarDedicatedTest/include/openssl/asn1.h +++ b/NorthstarDLL/include/openssl/asn1.h diff --git a/NorthstarDedicatedTest/include/openssl/asn1.h.in b/NorthstarDLL/include/openssl/asn1.h.in index 6d5094a3..6d5094a3 100644 --- a/NorthstarDedicatedTest/include/openssl/asn1.h.in +++ b/NorthstarDLL/include/openssl/asn1.h.in diff --git a/NorthstarDedicatedTest/include/openssl/asn1_mac.h b/NorthstarDLL/include/openssl/asn1_mac.h index fdcb9836..fdcb9836 100644 --- a/NorthstarDedicatedTest/include/openssl/asn1_mac.h +++ b/NorthstarDLL/include/openssl/asn1_mac.h diff --git a/NorthstarDedicatedTest/include/openssl/asn1err.h b/NorthstarDLL/include/openssl/asn1err.h index d4276220..d4276220 100644 --- a/NorthstarDedicatedTest/include/openssl/asn1err.h +++ b/NorthstarDLL/include/openssl/asn1err.h diff --git a/NorthstarDedicatedTest/include/openssl/asn1t.h b/NorthstarDLL/include/openssl/asn1t.h index a725c532..a725c532 100644 --- a/NorthstarDedicatedTest/include/openssl/asn1t.h +++ b/NorthstarDLL/include/openssl/asn1t.h diff --git a/NorthstarDedicatedTest/include/openssl/asn1t.h.in b/NorthstarDLL/include/openssl/asn1t.h.in index b536fe51..b536fe51 100644 --- a/NorthstarDedicatedTest/include/openssl/asn1t.h.in +++ b/NorthstarDLL/include/openssl/asn1t.h.in diff --git a/NorthstarDedicatedTest/include/openssl/async.h b/NorthstarDLL/include/openssl/async.h index bc27d5db..bc27d5db 100644 --- a/NorthstarDedicatedTest/include/openssl/async.h +++ b/NorthstarDLL/include/openssl/async.h diff --git a/NorthstarDedicatedTest/include/openssl/asyncerr.h b/NorthstarDLL/include/openssl/asyncerr.h index c093f7be..c093f7be 100644 --- a/NorthstarDedicatedTest/include/openssl/asyncerr.h +++ b/NorthstarDLL/include/openssl/asyncerr.h diff --git a/NorthstarDedicatedTest/include/openssl/bio.h b/NorthstarDLL/include/openssl/bio.h index 3ef0cafb..3ef0cafb 100644 --- a/NorthstarDedicatedTest/include/openssl/bio.h +++ b/NorthstarDLL/include/openssl/bio.h diff --git a/NorthstarDedicatedTest/include/openssl/bio.h.in b/NorthstarDLL/include/openssl/bio.h.in index 2c65b7e1..2c65b7e1 100644 --- a/NorthstarDedicatedTest/include/openssl/bio.h.in +++ b/NorthstarDLL/include/openssl/bio.h.in diff --git a/NorthstarDedicatedTest/include/openssl/bioerr.h b/NorthstarDLL/include/openssl/bioerr.h index 787b30af..787b30af 100644 --- a/NorthstarDedicatedTest/include/openssl/bioerr.h +++ b/NorthstarDLL/include/openssl/bioerr.h diff --git a/NorthstarDedicatedTest/include/openssl/blowfish.h b/NorthstarDLL/include/openssl/blowfish.h index 667d6423..667d6423 100644 --- a/NorthstarDedicatedTest/include/openssl/blowfish.h +++ b/NorthstarDLL/include/openssl/blowfish.h diff --git a/NorthstarDedicatedTest/include/openssl/bn.h b/NorthstarDLL/include/openssl/bn.h index ecd7f01b..ecd7f01b 100644 --- a/NorthstarDedicatedTest/include/openssl/bn.h +++ b/NorthstarDLL/include/openssl/bn.h diff --git a/NorthstarDedicatedTest/include/openssl/bnerr.h b/NorthstarDLL/include/openssl/bnerr.h index 847d326b..847d326b 100644 --- a/NorthstarDedicatedTest/include/openssl/bnerr.h +++ b/NorthstarDLL/include/openssl/bnerr.h diff --git a/NorthstarDedicatedTest/include/openssl/buffer.h b/NorthstarDLL/include/openssl/buffer.h index 5773b986..5773b986 100644 --- a/NorthstarDedicatedTest/include/openssl/buffer.h +++ b/NorthstarDLL/include/openssl/buffer.h diff --git a/NorthstarDedicatedTest/include/openssl/buffererr.h b/NorthstarDLL/include/openssl/buffererr.h index d18b1f8f..d18b1f8f 100644 --- a/NorthstarDedicatedTest/include/openssl/buffererr.h +++ b/NorthstarDLL/include/openssl/buffererr.h diff --git a/NorthstarDedicatedTest/include/openssl/camellia.h b/NorthstarDLL/include/openssl/camellia.h index 88c2279e..88c2279e 100644 --- a/NorthstarDedicatedTest/include/openssl/camellia.h +++ b/NorthstarDLL/include/openssl/camellia.h diff --git a/NorthstarDedicatedTest/include/openssl/cast.h b/NorthstarDLL/include/openssl/cast.h index 0bf217be..0bf217be 100644 --- a/NorthstarDedicatedTest/include/openssl/cast.h +++ b/NorthstarDLL/include/openssl/cast.h diff --git a/NorthstarDedicatedTest/include/openssl/cmac.h b/NorthstarDLL/include/openssl/cmac.h index f5086183..f5086183 100644 --- a/NorthstarDedicatedTest/include/openssl/cmac.h +++ b/NorthstarDLL/include/openssl/cmac.h diff --git a/NorthstarDedicatedTest/include/openssl/cmp.h b/NorthstarDLL/include/openssl/cmp.h index 7f258dc9..7f258dc9 100644 --- a/NorthstarDedicatedTest/include/openssl/cmp.h +++ b/NorthstarDLL/include/openssl/cmp.h diff --git a/NorthstarDedicatedTest/include/openssl/cmp.h.in b/NorthstarDLL/include/openssl/cmp.h.in index b4734421..b4734421 100644 --- a/NorthstarDedicatedTest/include/openssl/cmp.h.in +++ b/NorthstarDLL/include/openssl/cmp.h.in diff --git a/NorthstarDedicatedTest/include/openssl/cmp_util.h b/NorthstarDLL/include/openssl/cmp_util.h index 9a168922..9a168922 100644 --- a/NorthstarDedicatedTest/include/openssl/cmp_util.h +++ b/NorthstarDLL/include/openssl/cmp_util.h diff --git a/NorthstarDedicatedTest/include/openssl/cmperr.h b/NorthstarDLL/include/openssl/cmperr.h index 3a26fd0b..3a26fd0b 100644 --- a/NorthstarDedicatedTest/include/openssl/cmperr.h +++ b/NorthstarDLL/include/openssl/cmperr.h diff --git a/NorthstarDedicatedTest/include/openssl/cms.h b/NorthstarDLL/include/openssl/cms.h index 5b907f2c..5b907f2c 100644 --- a/NorthstarDedicatedTest/include/openssl/cms.h +++ b/NorthstarDLL/include/openssl/cms.h diff --git a/NorthstarDedicatedTest/include/openssl/cms.h.in b/NorthstarDLL/include/openssl/cms.h.in index da20ddf2..da20ddf2 100644 --- a/NorthstarDedicatedTest/include/openssl/cms.h.in +++ b/NorthstarDLL/include/openssl/cms.h.in diff --git a/NorthstarDedicatedTest/include/openssl/cmserr.h b/NorthstarDLL/include/openssl/cmserr.h index 1c4f4c79..1c4f4c79 100644 --- a/NorthstarDedicatedTest/include/openssl/cmserr.h +++ b/NorthstarDLL/include/openssl/cmserr.h diff --git a/NorthstarDedicatedTest/include/openssl/comp.h b/NorthstarDLL/include/openssl/comp.h index 06ff5810..06ff5810 100644 --- a/NorthstarDedicatedTest/include/openssl/comp.h +++ b/NorthstarDLL/include/openssl/comp.h diff --git a/NorthstarDedicatedTest/include/openssl/comperr.h b/NorthstarDLL/include/openssl/comperr.h index 01dd3e6b..01dd3e6b 100644 --- a/NorthstarDedicatedTest/include/openssl/comperr.h +++ b/NorthstarDLL/include/openssl/comperr.h diff --git a/NorthstarDedicatedTest/include/openssl/conf.h b/NorthstarDLL/include/openssl/conf.h index 07793f17..07793f17 100644 --- a/NorthstarDedicatedTest/include/openssl/conf.h +++ b/NorthstarDLL/include/openssl/conf.h diff --git a/NorthstarDedicatedTest/include/openssl/conf.h.in b/NorthstarDLL/include/openssl/conf.h.in index b0bd579a..b0bd579a 100644 --- a/NorthstarDedicatedTest/include/openssl/conf.h.in +++ b/NorthstarDLL/include/openssl/conf.h.in diff --git a/NorthstarDedicatedTest/include/openssl/conf_api.h b/NorthstarDLL/include/openssl/conf_api.h index ed67d577..ed67d577 100644 --- a/NorthstarDedicatedTest/include/openssl/conf_api.h +++ b/NorthstarDLL/include/openssl/conf_api.h diff --git a/NorthstarDedicatedTest/include/openssl/conferr.h b/NorthstarDLL/include/openssl/conferr.h index 496e2e1e..496e2e1e 100644 --- a/NorthstarDedicatedTest/include/openssl/conferr.h +++ b/NorthstarDLL/include/openssl/conferr.h diff --git a/NorthstarDedicatedTest/include/openssl/configuration.h b/NorthstarDLL/include/openssl/configuration.h index d9662edd..d9662edd 100644 --- a/NorthstarDedicatedTest/include/openssl/configuration.h +++ b/NorthstarDLL/include/openssl/configuration.h diff --git a/NorthstarDedicatedTest/include/openssl/configuration.h.in b/NorthstarDLL/include/openssl/configuration.h.in index b84dc1df..b84dc1df 100644 --- a/NorthstarDedicatedTest/include/openssl/configuration.h.in +++ b/NorthstarDLL/include/openssl/configuration.h.in diff --git a/NorthstarDedicatedTest/include/openssl/conftypes.h b/NorthstarDLL/include/openssl/conftypes.h index 17cefaa4..17cefaa4 100644 --- a/NorthstarDedicatedTest/include/openssl/conftypes.h +++ b/NorthstarDLL/include/openssl/conftypes.h diff --git a/NorthstarDedicatedTest/include/openssl/core.h b/NorthstarDLL/include/openssl/core.h index 9683ac70..9683ac70 100644 --- a/NorthstarDedicatedTest/include/openssl/core.h +++ b/NorthstarDLL/include/openssl/core.h diff --git a/NorthstarDedicatedTest/include/openssl/core_dispatch.h b/NorthstarDLL/include/openssl/core_dispatch.h index 99fcda00..99fcda00 100644 --- a/NorthstarDedicatedTest/include/openssl/core_dispatch.h +++ b/NorthstarDLL/include/openssl/core_dispatch.h diff --git a/NorthstarDedicatedTest/include/openssl/core_names.h b/NorthstarDLL/include/openssl/core_names.h index b549dae9..b549dae9 100644 --- a/NorthstarDedicatedTest/include/openssl/core_names.h +++ b/NorthstarDLL/include/openssl/core_names.h diff --git a/NorthstarDedicatedTest/include/openssl/core_object.h b/NorthstarDLL/include/openssl/core_object.h index 62ccf39d..62ccf39d 100644 --- a/NorthstarDedicatedTest/include/openssl/core_object.h +++ b/NorthstarDLL/include/openssl/core_object.h diff --git a/NorthstarDedicatedTest/include/openssl/crmf.h b/NorthstarDLL/include/openssl/crmf.h index b2a82edb..b2a82edb 100644 --- a/NorthstarDedicatedTest/include/openssl/crmf.h +++ b/NorthstarDLL/include/openssl/crmf.h diff --git a/NorthstarDedicatedTest/include/openssl/crmf.h.in b/NorthstarDLL/include/openssl/crmf.h.in index 4d37ea6d..4d37ea6d 100644 --- a/NorthstarDedicatedTest/include/openssl/crmf.h.in +++ b/NorthstarDLL/include/openssl/crmf.h.in diff --git a/NorthstarDedicatedTest/include/openssl/crmferr.h b/NorthstarDLL/include/openssl/crmferr.h index b242b922..b242b922 100644 --- a/NorthstarDedicatedTest/include/openssl/crmferr.h +++ b/NorthstarDLL/include/openssl/crmferr.h diff --git a/NorthstarDedicatedTest/include/openssl/crypto.h b/NorthstarDLL/include/openssl/crypto.h index ef327f20..ef327f20 100644 --- a/NorthstarDedicatedTest/include/openssl/crypto.h +++ b/NorthstarDLL/include/openssl/crypto.h diff --git a/NorthstarDedicatedTest/include/openssl/crypto.h.in b/NorthstarDLL/include/openssl/crypto.h.in index 724e2ca5..724e2ca5 100644 --- a/NorthstarDedicatedTest/include/openssl/crypto.h.in +++ b/NorthstarDLL/include/openssl/crypto.h.in diff --git a/NorthstarDedicatedTest/include/openssl/cryptoerr.h b/NorthstarDLL/include/openssl/cryptoerr.h index c6a04d9b..c6a04d9b 100644 --- a/NorthstarDedicatedTest/include/openssl/cryptoerr.h +++ b/NorthstarDLL/include/openssl/cryptoerr.h diff --git a/NorthstarDedicatedTest/include/openssl/cryptoerr_legacy.h b/NorthstarDLL/include/openssl/cryptoerr_legacy.h index ccab33a5..ccab33a5 100644 --- a/NorthstarDedicatedTest/include/openssl/cryptoerr_legacy.h +++ b/NorthstarDLL/include/openssl/cryptoerr_legacy.h diff --git a/NorthstarDedicatedTest/include/openssl/ct.h b/NorthstarDLL/include/openssl/ct.h index 06c41b70..06c41b70 100644 --- a/NorthstarDedicatedTest/include/openssl/ct.h +++ b/NorthstarDLL/include/openssl/ct.h diff --git a/NorthstarDedicatedTest/include/openssl/ct.h.in b/NorthstarDLL/include/openssl/ct.h.in index 16086b33..16086b33 100644 --- a/NorthstarDedicatedTest/include/openssl/ct.h.in +++ b/NorthstarDLL/include/openssl/ct.h.in diff --git a/NorthstarDedicatedTest/include/openssl/cterr.h b/NorthstarDLL/include/openssl/cterr.h index 935d32d8..935d32d8 100644 --- a/NorthstarDedicatedTest/include/openssl/cterr.h +++ b/NorthstarDLL/include/openssl/cterr.h diff --git a/NorthstarDedicatedTest/include/openssl/decoder.h b/NorthstarDLL/include/openssl/decoder.h index d4ee2cf4..d4ee2cf4 100644 --- a/NorthstarDedicatedTest/include/openssl/decoder.h +++ b/NorthstarDLL/include/openssl/decoder.h diff --git a/NorthstarDedicatedTest/include/openssl/decodererr.h b/NorthstarDLL/include/openssl/decodererr.h index 4212a38b..4212a38b 100644 --- a/NorthstarDedicatedTest/include/openssl/decodererr.h +++ b/NorthstarDLL/include/openssl/decodererr.h diff --git a/NorthstarDedicatedTest/include/openssl/des.h b/NorthstarDLL/include/openssl/des.h index 09798a61..09798a61 100644 --- a/NorthstarDedicatedTest/include/openssl/des.h +++ b/NorthstarDLL/include/openssl/des.h diff --git a/NorthstarDedicatedTest/include/openssl/dh.h b/NorthstarDLL/include/openssl/dh.h index b97871ec..b97871ec 100644 --- a/NorthstarDedicatedTest/include/openssl/dh.h +++ b/NorthstarDLL/include/openssl/dh.h diff --git a/NorthstarDedicatedTest/include/openssl/dherr.h b/NorthstarDLL/include/openssl/dherr.h index 5d2a762a..5d2a762a 100644 --- a/NorthstarDedicatedTest/include/openssl/dherr.h +++ b/NorthstarDLL/include/openssl/dherr.h diff --git a/NorthstarDedicatedTest/include/openssl/dsa.h b/NorthstarDLL/include/openssl/dsa.h index 5c0e4cdd..5c0e4cdd 100644 --- a/NorthstarDedicatedTest/include/openssl/dsa.h +++ b/NorthstarDLL/include/openssl/dsa.h diff --git a/NorthstarDedicatedTest/include/openssl/dsaerr.h b/NorthstarDLL/include/openssl/dsaerr.h index 5f0ca8d1..5f0ca8d1 100644 --- a/NorthstarDedicatedTest/include/openssl/dsaerr.h +++ b/NorthstarDLL/include/openssl/dsaerr.h diff --git a/NorthstarDedicatedTest/include/openssl/dtls1.h b/NorthstarDLL/include/openssl/dtls1.h index 5dc6b541..5dc6b541 100644 --- a/NorthstarDedicatedTest/include/openssl/dtls1.h +++ b/NorthstarDLL/include/openssl/dtls1.h diff --git a/NorthstarDedicatedTest/include/openssl/e_os2.h b/NorthstarDLL/include/openssl/e_os2.h index 67289092..67289092 100644 --- a/NorthstarDedicatedTest/include/openssl/e_os2.h +++ b/NorthstarDLL/include/openssl/e_os2.h diff --git a/NorthstarDedicatedTest/include/openssl/ebcdic.h b/NorthstarDLL/include/openssl/ebcdic.h index e0ae1aa8..e0ae1aa8 100644 --- a/NorthstarDedicatedTest/include/openssl/ebcdic.h +++ b/NorthstarDLL/include/openssl/ebcdic.h diff --git a/NorthstarDedicatedTest/include/openssl/ec.h b/NorthstarDLL/include/openssl/ec.h index f59b4f92..f59b4f92 100644 --- a/NorthstarDedicatedTest/include/openssl/ec.h +++ b/NorthstarDLL/include/openssl/ec.h diff --git a/NorthstarDedicatedTest/include/openssl/ecdh.h b/NorthstarDLL/include/openssl/ecdh.h index 56bd4cc2..56bd4cc2 100644 --- a/NorthstarDedicatedTest/include/openssl/ecdh.h +++ b/NorthstarDLL/include/openssl/ecdh.h diff --git a/NorthstarDedicatedTest/include/openssl/ecdsa.h b/NorthstarDLL/include/openssl/ecdsa.h index 56bd4cc2..56bd4cc2 100644 --- a/NorthstarDedicatedTest/include/openssl/ecdsa.h +++ b/NorthstarDLL/include/openssl/ecdsa.h diff --git a/NorthstarDedicatedTest/include/openssl/ecerr.h b/NorthstarDLL/include/openssl/ecerr.h index 49088d20..49088d20 100644 --- a/NorthstarDedicatedTest/include/openssl/ecerr.h +++ b/NorthstarDLL/include/openssl/ecerr.h diff --git a/NorthstarDedicatedTest/include/openssl/encoder.h b/NorthstarDLL/include/openssl/encoder.h index c37a6f16..c37a6f16 100644 --- a/NorthstarDedicatedTest/include/openssl/encoder.h +++ b/NorthstarDLL/include/openssl/encoder.h diff --git a/NorthstarDedicatedTest/include/openssl/encodererr.h b/NorthstarDLL/include/openssl/encodererr.h index 5e318b14..5e318b14 100644 --- a/NorthstarDedicatedTest/include/openssl/encodererr.h +++ b/NorthstarDLL/include/openssl/encodererr.h diff --git a/NorthstarDedicatedTest/include/openssl/engine.h b/NorthstarDLL/include/openssl/engine.h index 25c3cf7c..25c3cf7c 100644 --- a/NorthstarDedicatedTest/include/openssl/engine.h +++ b/NorthstarDLL/include/openssl/engine.h diff --git a/NorthstarDedicatedTest/include/openssl/engineerr.h b/NorthstarDLL/include/openssl/engineerr.h index d439b682..d439b682 100644 --- a/NorthstarDedicatedTest/include/openssl/engineerr.h +++ b/NorthstarDLL/include/openssl/engineerr.h diff --git a/NorthstarDedicatedTest/include/openssl/err.h b/NorthstarDLL/include/openssl/err.h index 3c7299db..3c7299db 100644 --- a/NorthstarDedicatedTest/include/openssl/err.h +++ b/NorthstarDLL/include/openssl/err.h diff --git a/NorthstarDedicatedTest/include/openssl/err.h.in b/NorthstarDLL/include/openssl/err.h.in index 7ca0b970..7ca0b970 100644 --- a/NorthstarDedicatedTest/include/openssl/err.h.in +++ b/NorthstarDLL/include/openssl/err.h.in diff --git a/NorthstarDedicatedTest/include/openssl/ess.h b/NorthstarDLL/include/openssl/ess.h index dad596a6..dad596a6 100644 --- a/NorthstarDedicatedTest/include/openssl/ess.h +++ b/NorthstarDLL/include/openssl/ess.h diff --git a/NorthstarDedicatedTest/include/openssl/ess.h.in b/NorthstarDLL/include/openssl/ess.h.in index d1a685b9..d1a685b9 100644 --- a/NorthstarDedicatedTest/include/openssl/ess.h.in +++ b/NorthstarDLL/include/openssl/ess.h.in diff --git a/NorthstarDedicatedTest/include/openssl/esserr.h b/NorthstarDLL/include/openssl/esserr.h index 165ce7c4..165ce7c4 100644 --- a/NorthstarDedicatedTest/include/openssl/esserr.h +++ b/NorthstarDLL/include/openssl/esserr.h diff --git a/NorthstarDedicatedTest/include/openssl/evp.h b/NorthstarDLL/include/openssl/evp.h index 18503817..18503817 100644 --- a/NorthstarDedicatedTest/include/openssl/evp.h +++ b/NorthstarDLL/include/openssl/evp.h diff --git a/NorthstarDedicatedTest/include/openssl/evperr.h b/NorthstarDLL/include/openssl/evperr.h index a5053f6c..a5053f6c 100644 --- a/NorthstarDedicatedTest/include/openssl/evperr.h +++ b/NorthstarDLL/include/openssl/evperr.h diff --git a/NorthstarDedicatedTest/include/openssl/fips_names.h b/NorthstarDLL/include/openssl/fips_names.h index 0fdf5440..0fdf5440 100644 --- a/NorthstarDedicatedTest/include/openssl/fips_names.h +++ b/NorthstarDLL/include/openssl/fips_names.h diff --git a/NorthstarDedicatedTest/include/openssl/fipskey.h b/NorthstarDLL/include/openssl/fipskey.h index ccc1d2f4..ccc1d2f4 100644 --- a/NorthstarDedicatedTest/include/openssl/fipskey.h +++ b/NorthstarDLL/include/openssl/fipskey.h diff --git a/NorthstarDedicatedTest/include/openssl/fipskey.h.in b/NorthstarDLL/include/openssl/fipskey.h.in index 56b947e8..56b947e8 100644 --- a/NorthstarDedicatedTest/include/openssl/fipskey.h.in +++ b/NorthstarDLL/include/openssl/fipskey.h.in diff --git a/NorthstarDedicatedTest/include/openssl/hmac.h b/NorthstarDLL/include/openssl/hmac.h index f9e1bff3..f9e1bff3 100644 --- a/NorthstarDedicatedTest/include/openssl/hmac.h +++ b/NorthstarDLL/include/openssl/hmac.h diff --git a/NorthstarDedicatedTest/include/openssl/http.h b/NorthstarDLL/include/openssl/http.h index f7ab2142..f7ab2142 100644 --- a/NorthstarDedicatedTest/include/openssl/http.h +++ b/NorthstarDLL/include/openssl/http.h diff --git a/NorthstarDedicatedTest/include/openssl/httperr.h b/NorthstarDLL/include/openssl/httperr.h index ee089592..ee089592 100644 --- a/NorthstarDedicatedTest/include/openssl/httperr.h +++ b/NorthstarDLL/include/openssl/httperr.h diff --git a/NorthstarDedicatedTest/include/openssl/idea.h b/NorthstarDLL/include/openssl/idea.h index 1f9bb3b3..1f9bb3b3 100644 --- a/NorthstarDedicatedTest/include/openssl/idea.h +++ b/NorthstarDLL/include/openssl/idea.h diff --git a/NorthstarDedicatedTest/include/openssl/kdf.h b/NorthstarDLL/include/openssl/kdf.h index 0983230a..0983230a 100644 --- a/NorthstarDedicatedTest/include/openssl/kdf.h +++ b/NorthstarDLL/include/openssl/kdf.h diff --git a/NorthstarDedicatedTest/include/openssl/kdferr.h b/NorthstarDLL/include/openssl/kdferr.h index 963d766d..963d766d 100644 --- a/NorthstarDedicatedTest/include/openssl/kdferr.h +++ b/NorthstarDLL/include/openssl/kdferr.h diff --git a/NorthstarDedicatedTest/include/openssl/lhash.h b/NorthstarDLL/include/openssl/lhash.h index 39dd6254..39dd6254 100644 --- a/NorthstarDedicatedTest/include/openssl/lhash.h +++ b/NorthstarDLL/include/openssl/lhash.h diff --git a/NorthstarDedicatedTest/include/openssl/lhash.h.in b/NorthstarDLL/include/openssl/lhash.h.in index febefa3c..febefa3c 100644 --- a/NorthstarDedicatedTest/include/openssl/lhash.h.in +++ b/NorthstarDLL/include/openssl/lhash.h.in diff --git a/NorthstarDedicatedTest/include/openssl/macros.h b/NorthstarDLL/include/openssl/macros.h index a6bc3f1f..a6bc3f1f 100644 --- a/NorthstarDedicatedTest/include/openssl/macros.h +++ b/NorthstarDLL/include/openssl/macros.h diff --git a/NorthstarDedicatedTest/include/openssl/md2.h b/NorthstarDLL/include/openssl/md2.h index 5d4cb77e..5d4cb77e 100644 --- a/NorthstarDedicatedTest/include/openssl/md2.h +++ b/NorthstarDLL/include/openssl/md2.h diff --git a/NorthstarDedicatedTest/include/openssl/md4.h b/NorthstarDLL/include/openssl/md4.h index 6c150a6c..6c150a6c 100644 --- a/NorthstarDedicatedTest/include/openssl/md4.h +++ b/NorthstarDLL/include/openssl/md4.h diff --git a/NorthstarDedicatedTest/include/openssl/md5.h b/NorthstarDLL/include/openssl/md5.h index 77a57734..77a57734 100644 --- a/NorthstarDedicatedTest/include/openssl/md5.h +++ b/NorthstarDLL/include/openssl/md5.h diff --git a/NorthstarDedicatedTest/include/openssl/mdc2.h b/NorthstarDLL/include/openssl/mdc2.h index 5a7ee289..5a7ee289 100644 --- a/NorthstarDedicatedTest/include/openssl/mdc2.h +++ b/NorthstarDLL/include/openssl/mdc2.h diff --git a/NorthstarDedicatedTest/include/openssl/modes.h b/NorthstarDLL/include/openssl/modes.h index e1907991..e1907991 100644 --- a/NorthstarDedicatedTest/include/openssl/modes.h +++ b/NorthstarDLL/include/openssl/modes.h diff --git a/NorthstarDedicatedTest/include/openssl/obj_mac.h b/NorthstarDLL/include/openssl/obj_mac.h index 0e860276..0e860276 100644 --- a/NorthstarDedicatedTest/include/openssl/obj_mac.h +++ b/NorthstarDLL/include/openssl/obj_mac.h diff --git a/NorthstarDedicatedTest/include/openssl/objects.h b/NorthstarDLL/include/openssl/objects.h index 9ea91c27..9ea91c27 100644 --- a/NorthstarDedicatedTest/include/openssl/objects.h +++ b/NorthstarDLL/include/openssl/objects.h diff --git a/NorthstarDedicatedTest/include/openssl/objectserr.h b/NorthstarDLL/include/openssl/objectserr.h index 585217f6..585217f6 100644 --- a/NorthstarDedicatedTest/include/openssl/objectserr.h +++ b/NorthstarDLL/include/openssl/objectserr.h diff --git a/NorthstarDedicatedTest/include/openssl/ocsp.h b/NorthstarDLL/include/openssl/ocsp.h index 5688381e..5688381e 100644 --- a/NorthstarDedicatedTest/include/openssl/ocsp.h +++ b/NorthstarDLL/include/openssl/ocsp.h diff --git a/NorthstarDedicatedTest/include/openssl/ocsp.h.in b/NorthstarDLL/include/openssl/ocsp.h.in index e2cc2716..e2cc2716 100644 --- a/NorthstarDedicatedTest/include/openssl/ocsp.h.in +++ b/NorthstarDLL/include/openssl/ocsp.h.in diff --git a/NorthstarDedicatedTest/include/openssl/ocsperr.h b/NorthstarDLL/include/openssl/ocsperr.h index 46a0523c..46a0523c 100644 --- a/NorthstarDedicatedTest/include/openssl/ocsperr.h +++ b/NorthstarDLL/include/openssl/ocsperr.h diff --git a/NorthstarDedicatedTest/include/openssl/opensslconf.h b/NorthstarDLL/include/openssl/opensslconf.h index 1e83371f..1e83371f 100644 --- a/NorthstarDedicatedTest/include/openssl/opensslconf.h +++ b/NorthstarDLL/include/openssl/opensslconf.h diff --git a/NorthstarDedicatedTest/include/openssl/opensslv.h b/NorthstarDLL/include/openssl/opensslv.h index 612d5aec..612d5aec 100644 --- a/NorthstarDedicatedTest/include/openssl/opensslv.h +++ b/NorthstarDLL/include/openssl/opensslv.h diff --git a/NorthstarDedicatedTest/include/openssl/opensslv.h.in b/NorthstarDLL/include/openssl/opensslv.h.in index 3f47a2ac..3f47a2ac 100644 --- a/NorthstarDedicatedTest/include/openssl/opensslv.h.in +++ b/NorthstarDLL/include/openssl/opensslv.h.in diff --git a/NorthstarDedicatedTest/include/openssl/ossl_typ.h b/NorthstarDLL/include/openssl/ossl_typ.h index 82a58988..82a58988 100644 --- a/NorthstarDedicatedTest/include/openssl/ossl_typ.h +++ b/NorthstarDLL/include/openssl/ossl_typ.h diff --git a/NorthstarDedicatedTest/include/openssl/param_build.h b/NorthstarDLL/include/openssl/param_build.h index f29fdb29..f29fdb29 100644 --- a/NorthstarDedicatedTest/include/openssl/param_build.h +++ b/NorthstarDLL/include/openssl/param_build.h diff --git a/NorthstarDedicatedTest/include/openssl/params.h b/NorthstarDLL/include/openssl/params.h index d75eab07..d75eab07 100644 --- a/NorthstarDedicatedTest/include/openssl/params.h +++ b/NorthstarDLL/include/openssl/params.h diff --git a/NorthstarDedicatedTest/include/openssl/pem.h b/NorthstarDLL/include/openssl/pem.h index 80940dfa..80940dfa 100644 --- a/NorthstarDedicatedTest/include/openssl/pem.h +++ b/NorthstarDLL/include/openssl/pem.h diff --git a/NorthstarDedicatedTest/include/openssl/pem2.h b/NorthstarDLL/include/openssl/pem2.h index a8a5325b..a8a5325b 100644 --- a/NorthstarDedicatedTest/include/openssl/pem2.h +++ b/NorthstarDLL/include/openssl/pem2.h diff --git a/NorthstarDedicatedTest/include/openssl/pemerr.h b/NorthstarDLL/include/openssl/pemerr.h index 18f6d9ef..18f6d9ef 100644 --- a/NorthstarDedicatedTest/include/openssl/pemerr.h +++ b/NorthstarDLL/include/openssl/pemerr.h diff --git a/NorthstarDedicatedTest/include/openssl/pkcs12.h b/NorthstarDLL/include/openssl/pkcs12.h index f0da0867..f0da0867 100644 --- a/NorthstarDedicatedTest/include/openssl/pkcs12.h +++ b/NorthstarDLL/include/openssl/pkcs12.h diff --git a/NorthstarDedicatedTest/include/openssl/pkcs12.h.in b/NorthstarDLL/include/openssl/pkcs12.h.in index c98eebfb..c98eebfb 100644 --- a/NorthstarDedicatedTest/include/openssl/pkcs12.h.in +++ b/NorthstarDLL/include/openssl/pkcs12.h.in diff --git a/NorthstarDedicatedTest/include/openssl/pkcs12err.h b/NorthstarDLL/include/openssl/pkcs12err.h index 933c8329..933c8329 100644 --- a/NorthstarDedicatedTest/include/openssl/pkcs12err.h +++ b/NorthstarDLL/include/openssl/pkcs12err.h diff --git a/NorthstarDedicatedTest/include/openssl/pkcs7.h b/NorthstarDLL/include/openssl/pkcs7.h index 097d2dbb..097d2dbb 100644 --- a/NorthstarDedicatedTest/include/openssl/pkcs7.h +++ b/NorthstarDLL/include/openssl/pkcs7.h diff --git a/NorthstarDedicatedTest/include/openssl/pkcs7.h.in b/NorthstarDLL/include/openssl/pkcs7.h.in index f5c55a3f..f5c55a3f 100644 --- a/NorthstarDedicatedTest/include/openssl/pkcs7.h.in +++ b/NorthstarDLL/include/openssl/pkcs7.h.in diff --git a/NorthstarDedicatedTest/include/openssl/pkcs7err.h b/NorthstarDLL/include/openssl/pkcs7err.h index ceb1a501..ceb1a501 100644 --- a/NorthstarDedicatedTest/include/openssl/pkcs7err.h +++ b/NorthstarDLL/include/openssl/pkcs7err.h diff --git a/NorthstarDedicatedTest/include/openssl/prov_ssl.h b/NorthstarDLL/include/openssl/prov_ssl.h index d3e0896c..d3e0896c 100644 --- a/NorthstarDedicatedTest/include/openssl/prov_ssl.h +++ b/NorthstarDLL/include/openssl/prov_ssl.h diff --git a/NorthstarDedicatedTest/include/openssl/proverr.h b/NorthstarDLL/include/openssl/proverr.h index ad67a8f8..ad67a8f8 100644 --- a/NorthstarDedicatedTest/include/openssl/proverr.h +++ b/NorthstarDLL/include/openssl/proverr.h diff --git a/NorthstarDedicatedTest/include/openssl/provider.h b/NorthstarDLL/include/openssl/provider.h index dc86ff58..dc86ff58 100644 --- a/NorthstarDedicatedTest/include/openssl/provider.h +++ b/NorthstarDLL/include/openssl/provider.h diff --git a/NorthstarDedicatedTest/include/openssl/rand.h b/NorthstarDLL/include/openssl/rand.h index ad3054fd..ad3054fd 100644 --- a/NorthstarDedicatedTest/include/openssl/rand.h +++ b/NorthstarDLL/include/openssl/rand.h diff --git a/NorthstarDedicatedTest/include/openssl/randerr.h b/NorthstarDLL/include/openssl/randerr.h index b5e08e43..b5e08e43 100644 --- a/NorthstarDedicatedTest/include/openssl/randerr.h +++ b/NorthstarDLL/include/openssl/randerr.h diff --git a/NorthstarDedicatedTest/include/openssl/rc2.h b/NorthstarDLL/include/openssl/rc2.h index ff633fd8..ff633fd8 100644 --- a/NorthstarDedicatedTest/include/openssl/rc2.h +++ b/NorthstarDLL/include/openssl/rc2.h diff --git a/NorthstarDedicatedTest/include/openssl/rc4.h b/NorthstarDLL/include/openssl/rc4.h index 600b2885..600b2885 100644 --- a/NorthstarDedicatedTest/include/openssl/rc4.h +++ b/NorthstarDLL/include/openssl/rc4.h diff --git a/NorthstarDedicatedTest/include/openssl/rc5.h b/NorthstarDLL/include/openssl/rc5.h index de833523..de833523 100644 --- a/NorthstarDedicatedTest/include/openssl/rc5.h +++ b/NorthstarDLL/include/openssl/rc5.h diff --git a/NorthstarDedicatedTest/include/openssl/ripemd.h b/NorthstarDLL/include/openssl/ripemd.h index 900ee317..900ee317 100644 --- a/NorthstarDedicatedTest/include/openssl/ripemd.h +++ b/NorthstarDLL/include/openssl/ripemd.h diff --git a/NorthstarDedicatedTest/include/openssl/rsa.h b/NorthstarDLL/include/openssl/rsa.h index a55c9727..a55c9727 100644 --- a/NorthstarDedicatedTest/include/openssl/rsa.h +++ b/NorthstarDLL/include/openssl/rsa.h diff --git a/NorthstarDedicatedTest/include/openssl/rsaerr.h b/NorthstarDLL/include/openssl/rsaerr.h index c58463c7..c58463c7 100644 --- a/NorthstarDedicatedTest/include/openssl/rsaerr.h +++ b/NorthstarDLL/include/openssl/rsaerr.h diff --git a/NorthstarDedicatedTest/include/openssl/safestack.h b/NorthstarDLL/include/openssl/safestack.h index 159ccf2a..159ccf2a 100644 --- a/NorthstarDedicatedTest/include/openssl/safestack.h +++ b/NorthstarDLL/include/openssl/safestack.h diff --git a/NorthstarDedicatedTest/include/openssl/safestack.h.in b/NorthstarDLL/include/openssl/safestack.h.in index 6b366079..6b366079 100644 --- a/NorthstarDedicatedTest/include/openssl/safestack.h.in +++ b/NorthstarDLL/include/openssl/safestack.h.in diff --git a/NorthstarDedicatedTest/include/openssl/seed.h b/NorthstarDLL/include/openssl/seed.h index edb218ae..edb218ae 100644 --- a/NorthstarDedicatedTest/include/openssl/seed.h +++ b/NorthstarDLL/include/openssl/seed.h diff --git a/NorthstarDedicatedTest/include/openssl/self_test.h b/NorthstarDLL/include/openssl/self_test.h index 77c600a0..77c600a0 100644 --- a/NorthstarDedicatedTest/include/openssl/self_test.h +++ b/NorthstarDLL/include/openssl/self_test.h diff --git a/NorthstarDedicatedTest/include/openssl/sha.h b/NorthstarDLL/include/openssl/sha.h index 6e65a040..6e65a040 100644 --- a/NorthstarDedicatedTest/include/openssl/sha.h +++ b/NorthstarDLL/include/openssl/sha.h diff --git a/NorthstarDedicatedTest/include/openssl/srp.h b/NorthstarDLL/include/openssl/srp.h index a86fa5d2..a86fa5d2 100644 --- a/NorthstarDedicatedTest/include/openssl/srp.h +++ b/NorthstarDLL/include/openssl/srp.h diff --git a/NorthstarDedicatedTest/include/openssl/srp.h.in b/NorthstarDLL/include/openssl/srp.h.in index dfbe845b..dfbe845b 100644 --- a/NorthstarDedicatedTest/include/openssl/srp.h.in +++ b/NorthstarDLL/include/openssl/srp.h.in diff --git a/NorthstarDedicatedTest/include/openssl/srtp.h b/NorthstarDLL/include/openssl/srtp.h index d64606e5..d64606e5 100644 --- a/NorthstarDedicatedTest/include/openssl/srtp.h +++ b/NorthstarDLL/include/openssl/srtp.h diff --git a/NorthstarDedicatedTest/include/openssl/ssl.h b/NorthstarDLL/include/openssl/ssl.h index 0763a33c..0763a33c 100644 --- a/NorthstarDedicatedTest/include/openssl/ssl.h +++ b/NorthstarDLL/include/openssl/ssl.h diff --git a/NorthstarDedicatedTest/include/openssl/ssl.h.in b/NorthstarDLL/include/openssl/ssl.h.in index 9c00eb3d..9c00eb3d 100644 --- a/NorthstarDedicatedTest/include/openssl/ssl.h.in +++ b/NorthstarDLL/include/openssl/ssl.h.in diff --git a/NorthstarDedicatedTest/include/openssl/ssl2.h b/NorthstarDLL/include/openssl/ssl2.h index 428ead05..428ead05 100644 --- a/NorthstarDedicatedTest/include/openssl/ssl2.h +++ b/NorthstarDLL/include/openssl/ssl2.h diff --git a/NorthstarDedicatedTest/include/openssl/ssl3.h b/NorthstarDLL/include/openssl/ssl3.h index 49bd51f2..49bd51f2 100644 --- a/NorthstarDedicatedTest/include/openssl/ssl3.h +++ b/NorthstarDLL/include/openssl/ssl3.h diff --git a/NorthstarDedicatedTest/include/openssl/sslerr.h b/NorthstarDLL/include/openssl/sslerr.h index a4746d70..a4746d70 100644 --- a/NorthstarDedicatedTest/include/openssl/sslerr.h +++ b/NorthstarDLL/include/openssl/sslerr.h diff --git a/NorthstarDedicatedTest/include/openssl/sslerr_legacy.h b/NorthstarDLL/include/openssl/sslerr_legacy.h index ccf6d3b3..ccf6d3b3 100644 --- a/NorthstarDedicatedTest/include/openssl/sslerr_legacy.h +++ b/NorthstarDLL/include/openssl/sslerr_legacy.h diff --git a/NorthstarDedicatedTest/include/openssl/stack.h b/NorthstarDLL/include/openssl/stack.h index f0c5c547..f0c5c547 100644 --- a/NorthstarDedicatedTest/include/openssl/stack.h +++ b/NorthstarDLL/include/openssl/stack.h diff --git a/NorthstarDedicatedTest/include/openssl/store.h b/NorthstarDLL/include/openssl/store.h index 3c1445e0..3c1445e0 100644 --- a/NorthstarDedicatedTest/include/openssl/store.h +++ b/NorthstarDLL/include/openssl/store.h diff --git a/NorthstarDedicatedTest/include/openssl/storeerr.h b/NorthstarDLL/include/openssl/storeerr.h index 00529c88..00529c88 100644 --- a/NorthstarDedicatedTest/include/openssl/storeerr.h +++ b/NorthstarDLL/include/openssl/storeerr.h diff --git a/NorthstarDedicatedTest/include/openssl/symhacks.h b/NorthstarDLL/include/openssl/symhacks.h index 816f8f99..816f8f99 100644 --- a/NorthstarDedicatedTest/include/openssl/symhacks.h +++ b/NorthstarDLL/include/openssl/symhacks.h diff --git a/NorthstarDedicatedTest/include/openssl/tls1.h b/NorthstarDLL/include/openssl/tls1.h index d6e9331f..d6e9331f 100644 --- a/NorthstarDedicatedTest/include/openssl/tls1.h +++ b/NorthstarDLL/include/openssl/tls1.h diff --git a/NorthstarDedicatedTest/include/openssl/trace.h b/NorthstarDLL/include/openssl/trace.h index 28200133..28200133 100644 --- a/NorthstarDedicatedTest/include/openssl/trace.h +++ b/NorthstarDLL/include/openssl/trace.h diff --git a/NorthstarDedicatedTest/include/openssl/ts.h b/NorthstarDLL/include/openssl/ts.h index 5136e4e9..5136e4e9 100644 --- a/NorthstarDedicatedTest/include/openssl/ts.h +++ b/NorthstarDLL/include/openssl/ts.h diff --git a/NorthstarDedicatedTest/include/openssl/tserr.h b/NorthstarDLL/include/openssl/tserr.h index e1b943e4..e1b943e4 100644 --- a/NorthstarDedicatedTest/include/openssl/tserr.h +++ b/NorthstarDLL/include/openssl/tserr.h diff --git a/NorthstarDedicatedTest/include/openssl/txt_db.h b/NorthstarDLL/include/openssl/txt_db.h index af169a30..af169a30 100644 --- a/NorthstarDedicatedTest/include/openssl/txt_db.h +++ b/NorthstarDLL/include/openssl/txt_db.h diff --git a/NorthstarDedicatedTest/include/openssl/types.h b/NorthstarDLL/include/openssl/types.h index de9f1665..de9f1665 100644 --- a/NorthstarDedicatedTest/include/openssl/types.h +++ b/NorthstarDLL/include/openssl/types.h diff --git a/NorthstarDedicatedTest/include/openssl/ui.h b/NorthstarDLL/include/openssl/ui.h index 835b0eba..835b0eba 100644 --- a/NorthstarDedicatedTest/include/openssl/ui.h +++ b/NorthstarDLL/include/openssl/ui.h diff --git a/NorthstarDedicatedTest/include/openssl/ui.h.in b/NorthstarDLL/include/openssl/ui.h.in index eb9a580f..eb9a580f 100644 --- a/NorthstarDedicatedTest/include/openssl/ui.h.in +++ b/NorthstarDLL/include/openssl/ui.h.in diff --git a/NorthstarDedicatedTest/include/openssl/uierr.h b/NorthstarDLL/include/openssl/uierr.h index 473b04ed..473b04ed 100644 --- a/NorthstarDedicatedTest/include/openssl/uierr.h +++ b/NorthstarDLL/include/openssl/uierr.h diff --git a/NorthstarDedicatedTest/include/openssl/whrlpool.h b/NorthstarDLL/include/openssl/whrlpool.h index 05ba4632..05ba4632 100644 --- a/NorthstarDedicatedTest/include/openssl/whrlpool.h +++ b/NorthstarDLL/include/openssl/whrlpool.h diff --git a/NorthstarDedicatedTest/include/openssl/x509.h b/NorthstarDLL/include/openssl/x509.h index db57a9bf..db57a9bf 100644 --- a/NorthstarDedicatedTest/include/openssl/x509.h +++ b/NorthstarDLL/include/openssl/x509.h diff --git a/NorthstarDedicatedTest/include/openssl/x509.h.in b/NorthstarDLL/include/openssl/x509.h.in index b4efbb55..b4efbb55 100644 --- a/NorthstarDedicatedTest/include/openssl/x509.h.in +++ b/NorthstarDLL/include/openssl/x509.h.in diff --git a/NorthstarDedicatedTest/include/openssl/x509_vfy.h b/NorthstarDLL/include/openssl/x509_vfy.h index e04df0d3..e04df0d3 100644 --- a/NorthstarDedicatedTest/include/openssl/x509_vfy.h +++ b/NorthstarDLL/include/openssl/x509_vfy.h diff --git a/NorthstarDedicatedTest/include/openssl/x509_vfy.h.in b/NorthstarDLL/include/openssl/x509_vfy.h.in index 80f18bd7..80f18bd7 100644 --- a/NorthstarDedicatedTest/include/openssl/x509_vfy.h.in +++ b/NorthstarDLL/include/openssl/x509_vfy.h.in diff --git a/NorthstarDedicatedTest/include/openssl/x509err.h b/NorthstarDLL/include/openssl/x509err.h index a56facd4..a56facd4 100644 --- a/NorthstarDedicatedTest/include/openssl/x509err.h +++ b/NorthstarDLL/include/openssl/x509err.h diff --git a/NorthstarDedicatedTest/include/openssl/x509v3.h b/NorthstarDLL/include/openssl/x509v3.h index 78c390b3..78c390b3 100644 --- a/NorthstarDedicatedTest/include/openssl/x509v3.h +++ b/NorthstarDLL/include/openssl/x509v3.h diff --git a/NorthstarDedicatedTest/include/openssl/x509v3.h.in b/NorthstarDLL/include/openssl/x509v3.h.in index d00a66a3..d00a66a3 100644 --- a/NorthstarDedicatedTest/include/openssl/x509v3.h.in +++ b/NorthstarDLL/include/openssl/x509v3.h.in diff --git a/NorthstarDedicatedTest/include/openssl/x509v3err.h b/NorthstarDLL/include/openssl/x509v3err.h index 1ae3a562..1ae3a562 100644 --- a/NorthstarDedicatedTest/include/openssl/x509v3err.h +++ b/NorthstarDLL/include/openssl/x509v3err.h diff --git a/NorthstarDedicatedTest/include/rapidjson/allocators.h b/NorthstarDLL/include/rapidjson/allocators.h index 98affe03..98affe03 100644 --- a/NorthstarDedicatedTest/include/rapidjson/allocators.h +++ b/NorthstarDLL/include/rapidjson/allocators.h diff --git a/NorthstarDedicatedTest/include/rapidjson/document.h b/NorthstarDLL/include/rapidjson/document.h index e3e20dfb..e3e20dfb 100644 --- a/NorthstarDedicatedTest/include/rapidjson/document.h +++ b/NorthstarDLL/include/rapidjson/document.h diff --git a/NorthstarDedicatedTest/include/rapidjson/encodedstream.h b/NorthstarDLL/include/rapidjson/encodedstream.h index 14506838..14506838 100644 --- a/NorthstarDedicatedTest/include/rapidjson/encodedstream.h +++ b/NorthstarDLL/include/rapidjson/encodedstream.h diff --git a/NorthstarDedicatedTest/include/rapidjson/encodings.h b/NorthstarDLL/include/rapidjson/encodings.h index baa7c2b1..baa7c2b1 100644 --- a/NorthstarDedicatedTest/include/rapidjson/encodings.h +++ b/NorthstarDLL/include/rapidjson/encodings.h diff --git a/NorthstarDedicatedTest/include/rapidjson/error/en.h b/NorthstarDLL/include/rapidjson/error/en.h index 2db838bf..2db838bf 100644 --- a/NorthstarDedicatedTest/include/rapidjson/error/en.h +++ b/NorthstarDLL/include/rapidjson/error/en.h diff --git a/NorthstarDedicatedTest/include/rapidjson/error/error.h b/NorthstarDLL/include/rapidjson/error/error.h index 95cb31a7..95cb31a7 100644 --- a/NorthstarDedicatedTest/include/rapidjson/error/error.h +++ b/NorthstarDLL/include/rapidjson/error/error.h diff --git a/NorthstarDedicatedTest/include/rapidjson/filereadstream.h b/NorthstarDLL/include/rapidjson/filereadstream.h index b56ea13b..b56ea13b 100644 --- a/NorthstarDedicatedTest/include/rapidjson/filereadstream.h +++ b/NorthstarDLL/include/rapidjson/filereadstream.h diff --git a/NorthstarDedicatedTest/include/rapidjson/filewritestream.h b/NorthstarDLL/include/rapidjson/filewritestream.h index 6378dd60..6378dd60 100644 --- a/NorthstarDedicatedTest/include/rapidjson/filewritestream.h +++ b/NorthstarDLL/include/rapidjson/filewritestream.h diff --git a/NorthstarDedicatedTest/include/rapidjson/fwd.h b/NorthstarDLL/include/rapidjson/fwd.h index e8104e84..e8104e84 100644 --- a/NorthstarDedicatedTest/include/rapidjson/fwd.h +++ b/NorthstarDLL/include/rapidjson/fwd.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/biginteger.h b/NorthstarDLL/include/rapidjson/internal/biginteger.h index 9d3e88c9..9d3e88c9 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/biginteger.h +++ b/NorthstarDLL/include/rapidjson/internal/biginteger.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/diyfp.h b/NorthstarDLL/include/rapidjson/internal/diyfp.h index c9fefdc6..c9fefdc6 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/diyfp.h +++ b/NorthstarDLL/include/rapidjson/internal/diyfp.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/dtoa.h b/NorthstarDLL/include/rapidjson/internal/dtoa.h index 8d6350e6..8d6350e6 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/dtoa.h +++ b/NorthstarDLL/include/rapidjson/internal/dtoa.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/ieee754.h b/NorthstarDLL/include/rapidjson/internal/ieee754.h index 82bb0b99..82bb0b99 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/ieee754.h +++ b/NorthstarDLL/include/rapidjson/internal/ieee754.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/itoa.h b/NorthstarDLL/include/rapidjson/internal/itoa.h index 01a4e7e7..01a4e7e7 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/itoa.h +++ b/NorthstarDLL/include/rapidjson/internal/itoa.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/meta.h b/NorthstarDLL/include/rapidjson/internal/meta.h index 5a9aaa42..5a9aaa42 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/meta.h +++ b/NorthstarDLL/include/rapidjson/internal/meta.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/pow10.h b/NorthstarDLL/include/rapidjson/internal/pow10.h index 02f475d7..02f475d7 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/pow10.h +++ b/NorthstarDLL/include/rapidjson/internal/pow10.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/regex.h b/NorthstarDLL/include/rapidjson/internal/regex.h index 422a5240..422a5240 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/regex.h +++ b/NorthstarDLL/include/rapidjson/internal/regex.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/stack.h b/NorthstarDLL/include/rapidjson/internal/stack.h index 022c9aab..022c9aab 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/stack.h +++ b/NorthstarDLL/include/rapidjson/internal/stack.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/strfunc.h b/NorthstarDLL/include/rapidjson/internal/strfunc.h index 2edfae52..2edfae52 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/strfunc.h +++ b/NorthstarDLL/include/rapidjson/internal/strfunc.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/strtod.h b/NorthstarDLL/include/rapidjson/internal/strtod.h index 289c413b..289c413b 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/strtod.h +++ b/NorthstarDLL/include/rapidjson/internal/strtod.h diff --git a/NorthstarDedicatedTest/include/rapidjson/internal/swap.h b/NorthstarDLL/include/rapidjson/internal/swap.h index 666e49f9..666e49f9 100644 --- a/NorthstarDedicatedTest/include/rapidjson/internal/swap.h +++ b/NorthstarDLL/include/rapidjson/internal/swap.h diff --git a/NorthstarDedicatedTest/include/rapidjson/istreamwrapper.h b/NorthstarDLL/include/rapidjson/istreamwrapper.h index f5fe2897..f5fe2897 100644 --- a/NorthstarDedicatedTest/include/rapidjson/istreamwrapper.h +++ b/NorthstarDLL/include/rapidjson/istreamwrapper.h diff --git a/NorthstarDedicatedTest/include/rapidjson/memorybuffer.h b/NorthstarDLL/include/rapidjson/memorybuffer.h index 39bee1de..39bee1de 100644 --- a/NorthstarDedicatedTest/include/rapidjson/memorybuffer.h +++ b/NorthstarDLL/include/rapidjson/memorybuffer.h diff --git a/NorthstarDedicatedTest/include/rapidjson/memorystream.h b/NorthstarDLL/include/rapidjson/memorystream.h index 1d71d8a4..1d71d8a4 100644 --- a/NorthstarDedicatedTest/include/rapidjson/memorystream.h +++ b/NorthstarDLL/include/rapidjson/memorystream.h diff --git a/NorthstarDedicatedTest/include/rapidjson/msinttypes/inttypes.h b/NorthstarDLL/include/rapidjson/msinttypes/inttypes.h index 18111286..18111286 100644 --- a/NorthstarDedicatedTest/include/rapidjson/msinttypes/inttypes.h +++ b/NorthstarDLL/include/rapidjson/msinttypes/inttypes.h diff --git a/NorthstarDedicatedTest/include/rapidjson/msinttypes/stdint.h b/NorthstarDLL/include/rapidjson/msinttypes/stdint.h index 3d4477b9..3d4477b9 100644 --- a/NorthstarDedicatedTest/include/rapidjson/msinttypes/stdint.h +++ b/NorthstarDLL/include/rapidjson/msinttypes/stdint.h diff --git a/NorthstarDedicatedTest/include/rapidjson/ostreamwrapper.h b/NorthstarDLL/include/rapidjson/ostreamwrapper.h index 6f4667c0..6f4667c0 100644 --- a/NorthstarDedicatedTest/include/rapidjson/ostreamwrapper.h +++ b/NorthstarDLL/include/rapidjson/ostreamwrapper.h diff --git a/NorthstarDedicatedTest/include/rapidjson/pointer.h b/NorthstarDLL/include/rapidjson/pointer.h index 0206ac1c..0206ac1c 100644 --- a/NorthstarDedicatedTest/include/rapidjson/pointer.h +++ b/NorthstarDLL/include/rapidjson/pointer.h diff --git a/NorthstarDedicatedTest/include/rapidjson/prettywriter.h b/NorthstarDLL/include/rapidjson/prettywriter.h index 0dcb0fee..0dcb0fee 100644 --- a/NorthstarDedicatedTest/include/rapidjson/prettywriter.h +++ b/NorthstarDLL/include/rapidjson/prettywriter.h diff --git a/NorthstarDedicatedTest/include/rapidjson/rapidjson.h b/NorthstarDLL/include/rapidjson/rapidjson.h index 053b2ce4..053b2ce4 100644 --- a/NorthstarDedicatedTest/include/rapidjson/rapidjson.h +++ b/NorthstarDLL/include/rapidjson/rapidjson.h diff --git a/NorthstarDedicatedTest/include/rapidjson/reader.h b/NorthstarDLL/include/rapidjson/reader.h index 19f8849b..19f8849b 100644 --- a/NorthstarDedicatedTest/include/rapidjson/reader.h +++ b/NorthstarDLL/include/rapidjson/reader.h diff --git a/NorthstarDedicatedTest/include/rapidjson/schema.h b/NorthstarDLL/include/rapidjson/schema.h index b182aa27..b182aa27 100644 --- a/NorthstarDedicatedTest/include/rapidjson/schema.h +++ b/NorthstarDLL/include/rapidjson/schema.h diff --git a/NorthstarDedicatedTest/include/rapidjson/stream.h b/NorthstarDLL/include/rapidjson/stream.h index fef82c25..fef82c25 100644 --- a/NorthstarDedicatedTest/include/rapidjson/stream.h +++ b/NorthstarDLL/include/rapidjson/stream.h diff --git a/NorthstarDedicatedTest/include/rapidjson/stringbuffer.h b/NorthstarDLL/include/rapidjson/stringbuffer.h index 78f34d20..78f34d20 100644 --- a/NorthstarDedicatedTest/include/rapidjson/stringbuffer.h +++ b/NorthstarDLL/include/rapidjson/stringbuffer.h diff --git a/NorthstarDedicatedTest/include/rapidjson/writer.h b/NorthstarDLL/include/rapidjson/writer.h index 94f22dd5..94f22dd5 100644 --- a/NorthstarDedicatedTest/include/rapidjson/writer.h +++ b/NorthstarDLL/include/rapidjson/writer.h diff --git a/NorthstarDedicatedTest/include/spdlog/async.h b/NorthstarDLL/include/spdlog/async.h index f7956305..f7956305 100644 --- a/NorthstarDedicatedTest/include/spdlog/async.h +++ b/NorthstarDLL/include/spdlog/async.h diff --git a/NorthstarDedicatedTest/include/spdlog/async_logger-inl.h b/NorthstarDLL/include/spdlog/async_logger-inl.h index f8c9694c..f8c9694c 100644 --- a/NorthstarDedicatedTest/include/spdlog/async_logger-inl.h +++ b/NorthstarDLL/include/spdlog/async_logger-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/async_logger.h b/NorthstarDLL/include/spdlog/async_logger.h index 6f299672..6f299672 100644 --- a/NorthstarDedicatedTest/include/spdlog/async_logger.h +++ b/NorthstarDLL/include/spdlog/async_logger.h diff --git a/NorthstarDedicatedTest/include/spdlog/cfg/argv.h b/NorthstarDLL/include/spdlog/cfg/argv.h index 36d9f1c4..36d9f1c4 100644 --- a/NorthstarDedicatedTest/include/spdlog/cfg/argv.h +++ b/NorthstarDLL/include/spdlog/cfg/argv.h diff --git a/NorthstarDedicatedTest/include/spdlog/cfg/env.h b/NorthstarDLL/include/spdlog/cfg/env.h index 1f39ebbb..1f39ebbb 100644 --- a/NorthstarDedicatedTest/include/spdlog/cfg/env.h +++ b/NorthstarDLL/include/spdlog/cfg/env.h diff --git a/NorthstarDedicatedTest/include/spdlog/cfg/helpers-inl.h b/NorthstarDLL/include/spdlog/cfg/helpers-inl.h index 9e4daede..9e4daede 100644 --- a/NorthstarDedicatedTest/include/spdlog/cfg/helpers-inl.h +++ b/NorthstarDLL/include/spdlog/cfg/helpers-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/cfg/helpers.h b/NorthstarDLL/include/spdlog/cfg/helpers.h index a795f39a..a795f39a 100644 --- a/NorthstarDedicatedTest/include/spdlog/cfg/helpers.h +++ b/NorthstarDLL/include/spdlog/cfg/helpers.h diff --git a/NorthstarDedicatedTest/include/spdlog/common-inl.h b/NorthstarDLL/include/spdlog/common-inl.h index 378efe60..378efe60 100644 --- a/NorthstarDedicatedTest/include/spdlog/common-inl.h +++ b/NorthstarDLL/include/spdlog/common-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/common.h b/NorthstarDLL/include/spdlog/common.h index fb9a3660..fb9a3660 100644 --- a/NorthstarDedicatedTest/include/spdlog/common.h +++ b/NorthstarDLL/include/spdlog/common.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/backtracer-inl.h b/NorthstarDLL/include/spdlog/details/backtracer-inl.h index 21553c26..21553c26 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/backtracer-inl.h +++ b/NorthstarDLL/include/spdlog/details/backtracer-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/backtracer.h b/NorthstarDLL/include/spdlog/details/backtracer.h index b7476bc9..1da5d4c7 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/backtracer.h +++ b/NorthstarDLL/include/spdlog/details/backtracer.h @@ -42,4 +42,4 @@ public: #ifdef SPDLOG_HEADER_ONLY #include "backtracer-inl.h" -#endif
\ No newline at end of file +#endif diff --git a/NorthstarDedicatedTest/include/spdlog/details/circular_q.h b/NorthstarDLL/include/spdlog/details/circular_q.h index 1f2712e7..1f2712e7 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/circular_q.h +++ b/NorthstarDLL/include/spdlog/details/circular_q.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/console_globals.h b/NorthstarDLL/include/spdlog/details/console_globals.h index 665201dd..665201dd 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/console_globals.h +++ b/NorthstarDLL/include/spdlog/details/console_globals.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/file_helper-inl.h b/NorthstarDLL/include/spdlog/details/file_helper-inl.h index 30f3cf55..30f3cf55 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/file_helper-inl.h +++ b/NorthstarDLL/include/spdlog/details/file_helper-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/file_helper.h b/NorthstarDLL/include/spdlog/details/file_helper.h index 5395d9cb..5395d9cb 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/file_helper.h +++ b/NorthstarDLL/include/spdlog/details/file_helper.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/fmt_helper.h b/NorthstarDLL/include/spdlog/details/fmt_helper.h index 5dc311a0..5dc311a0 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/fmt_helper.h +++ b/NorthstarDLL/include/spdlog/details/fmt_helper.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/log_msg-inl.h b/NorthstarDLL/include/spdlog/details/log_msg-inl.h index af11e0da..af11e0da 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/log_msg-inl.h +++ b/NorthstarDLL/include/spdlog/details/log_msg-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/log_msg.h b/NorthstarDLL/include/spdlog/details/log_msg.h index 834ca4df..834ca4df 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/log_msg.h +++ b/NorthstarDLL/include/spdlog/details/log_msg.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/log_msg_buffer-inl.h b/NorthstarDLL/include/spdlog/details/log_msg_buffer-inl.h index ca9429bb..ca9429bb 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/log_msg_buffer-inl.h +++ b/NorthstarDLL/include/spdlog/details/log_msg_buffer-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/log_msg_buffer.h b/NorthstarDLL/include/spdlog/details/log_msg_buffer.h index 4410110f..4410110f 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/log_msg_buffer.h +++ b/NorthstarDLL/include/spdlog/details/log_msg_buffer.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/mpmc_blocking_q.h b/NorthstarDLL/include/spdlog/details/mpmc_blocking_q.h index 5c3cca76..5c3cca76 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/mpmc_blocking_q.h +++ b/NorthstarDLL/include/spdlog/details/mpmc_blocking_q.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/null_mutex.h b/NorthstarDLL/include/spdlog/details/null_mutex.h index 83533d4f..83533d4f 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/null_mutex.h +++ b/NorthstarDLL/include/spdlog/details/null_mutex.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/os-inl.h b/NorthstarDLL/include/spdlog/details/os-inl.h index a701e13f..a701e13f 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/os-inl.h +++ b/NorthstarDLL/include/spdlog/details/os-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/os.h b/NorthstarDLL/include/spdlog/details/os.h index 9fda1447..9fda1447 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/os.h +++ b/NorthstarDLL/include/spdlog/details/os.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/periodic_worker-inl.h b/NorthstarDLL/include/spdlog/details/periodic_worker-inl.h index 1d794994..1d794994 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/periodic_worker-inl.h +++ b/NorthstarDLL/include/spdlog/details/periodic_worker-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/periodic_worker.h b/NorthstarDLL/include/spdlog/details/periodic_worker.h index 42373665..42373665 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/periodic_worker.h +++ b/NorthstarDLL/include/spdlog/details/periodic_worker.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/registry-inl.h b/NorthstarDLL/include/spdlog/details/registry-inl.h index a60faabc..a60faabc 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/registry-inl.h +++ b/NorthstarDLL/include/spdlog/details/registry-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/registry.h b/NorthstarDLL/include/spdlog/details/registry.h index b069c3f5..b069c3f5 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/registry.h +++ b/NorthstarDLL/include/spdlog/details/registry.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/synchronous_factory.h b/NorthstarDLL/include/spdlog/details/synchronous_factory.h index b48f5932..e1e42268 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/synchronous_factory.h +++ b/NorthstarDLL/include/spdlog/details/synchronous_factory.h @@ -21,4 +21,4 @@ struct synchronous_factory return new_logger; } }; -} // namespace spdlog
\ No newline at end of file +} // namespace spdlog diff --git a/NorthstarDedicatedTest/include/spdlog/details/tcp_client-windows.h b/NorthstarDLL/include/spdlog/details/tcp_client-windows.h index 7ee72927..7ee72927 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/tcp_client-windows.h +++ b/NorthstarDLL/include/spdlog/details/tcp_client-windows.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/tcp_client.h b/NorthstarDLL/include/spdlog/details/tcp_client.h index 9f3bb99e..9f3bb99e 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/tcp_client.h +++ b/NorthstarDLL/include/spdlog/details/tcp_client.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/thread_pool-inl.h b/NorthstarDLL/include/spdlog/details/thread_pool-inl.h index c1df4361..c1df4361 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/thread_pool-inl.h +++ b/NorthstarDLL/include/spdlog/details/thread_pool-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/thread_pool.h b/NorthstarDLL/include/spdlog/details/thread_pool.h index 61e25252..61e25252 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/thread_pool.h +++ b/NorthstarDLL/include/spdlog/details/thread_pool.h diff --git a/NorthstarDedicatedTest/include/spdlog/details/windows_include.h b/NorthstarDLL/include/spdlog/details/windows_include.h index 6a2f14f9..6a2f14f9 100644 --- a/NorthstarDedicatedTest/include/spdlog/details/windows_include.h +++ b/NorthstarDLL/include/spdlog/details/windows_include.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bin_to_hex.h b/NorthstarDLL/include/spdlog/fmt/bin_to_hex.h index 1e2b054b..1e2b054b 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bin_to_hex.h +++ b/NorthstarDLL/include/spdlog/fmt/bin_to_hex.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/LICENSE.rst b/NorthstarDLL/include/spdlog/fmt/bundled/LICENSE.rst index f0ec3db4..f0ec3db4 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/LICENSE.rst +++ b/NorthstarDLL/include/spdlog/fmt/bundled/LICENSE.rst diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/chrono.h b/NorthstarDLL/include/spdlog/fmt/bundled/chrono.h index bdfe2aa0..bdfe2aa0 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/chrono.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/chrono.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/color.h b/NorthstarDLL/include/spdlog/fmt/bundled/color.h index 94e3419d..94e3419d 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/color.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/color.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/compile.h b/NorthstarDLL/include/spdlog/fmt/bundled/compile.h index 3a33b020..3a33b020 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/compile.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/compile.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/core.h b/NorthstarDLL/include/spdlog/fmt/bundled/core.h index 0a81e0cc..0a81e0cc 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/core.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/core.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/format-inl.h b/NorthstarDLL/include/spdlog/fmt/bundled/format-inl.h index 8f2fe735..8f2fe735 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/format-inl.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/format-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/format.h b/NorthstarDLL/include/spdlog/fmt/bundled/format.h index 1a037b02..1a037b02 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/format.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/format.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/locale.h b/NorthstarDLL/include/spdlog/fmt/bundled/locale.h index 7301bf92..7301bf92 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/locale.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/locale.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/os.h b/NorthstarDLL/include/spdlog/fmt/bundled/os.h index d44ea0c9..d44ea0c9 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/os.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/os.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/ostream.h b/NorthstarDLL/include/spdlog/fmt/bundled/ostream.h index 29c58ec1..29c58ec1 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/ostream.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/ostream.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/posix.h b/NorthstarDLL/include/spdlog/fmt/bundled/posix.h index da19e9d5..da19e9d5 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/posix.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/posix.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/printf.h b/NorthstarDLL/include/spdlog/fmt/bundled/printf.h index 8c28ac23..8c28ac23 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/printf.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/printf.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/ranges.h b/NorthstarDLL/include/spdlog/fmt/bundled/ranges.h index 632f0494..632f0494 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/bundled/ranges.h +++ b/NorthstarDLL/include/spdlog/fmt/bundled/ranges.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/chrono.h b/NorthstarDLL/include/spdlog/fmt/chrono.h index e1fb7a06..e1fb7a06 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/chrono.h +++ b/NorthstarDLL/include/spdlog/fmt/chrono.h diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/fmt.h b/NorthstarDLL/include/spdlog/fmt/fmt.h index 746d2f2c..ec10ac33 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/fmt.h +++ b/NorthstarDLL/include/spdlog/fmt/fmt.h @@ -24,4 +24,4 @@ #else // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib #include <fmt/core.h> #include <fmt/format.h> -#endif
\ No newline at end of file +#endif diff --git a/NorthstarDedicatedTest/include/spdlog/fmt/ostr.h b/NorthstarDLL/include/spdlog/fmt/ostr.h index f82eb679..f82eb679 100644 --- a/NorthstarDedicatedTest/include/spdlog/fmt/ostr.h +++ b/NorthstarDLL/include/spdlog/fmt/ostr.h diff --git a/NorthstarDedicatedTest/include/spdlog/formatter.h b/NorthstarDLL/include/spdlog/formatter.h index 5086fb21..5086fb21 100644 --- a/NorthstarDedicatedTest/include/spdlog/formatter.h +++ b/NorthstarDLL/include/spdlog/formatter.h diff --git a/NorthstarDedicatedTest/include/spdlog/fwd.h b/NorthstarDLL/include/spdlog/fwd.h index cc05ddd4..cc05ddd4 100644 --- a/NorthstarDedicatedTest/include/spdlog/fwd.h +++ b/NorthstarDLL/include/spdlog/fwd.h diff --git a/NorthstarDedicatedTest/include/spdlog/logger-inl.h b/NorthstarDLL/include/spdlog/logger-inl.h index d01c08da..d01c08da 100644 --- a/NorthstarDedicatedTest/include/spdlog/logger-inl.h +++ b/NorthstarDLL/include/spdlog/logger-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/logger.h b/NorthstarDLL/include/spdlog/logger.h index a34c5221..a34c5221 100644 --- a/NorthstarDedicatedTest/include/spdlog/logger.h +++ b/NorthstarDLL/include/spdlog/logger.h diff --git a/NorthstarDedicatedTest/include/spdlog/pattern_formatter-inl.h b/NorthstarDLL/include/spdlog/pattern_formatter-inl.h index 54346e1e..54346e1e 100644 --- a/NorthstarDedicatedTest/include/spdlog/pattern_formatter-inl.h +++ b/NorthstarDLL/include/spdlog/pattern_formatter-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/pattern_formatter.h b/NorthstarDLL/include/spdlog/pattern_formatter.h index bc13ae10..bc13ae10 100644 --- a/NorthstarDedicatedTest/include/spdlog/pattern_formatter.h +++ b/NorthstarDLL/include/spdlog/pattern_formatter.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/android_sink.h b/NorthstarDLL/include/spdlog/sinks/android_sink.h index 9686adff..659beabb 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/android_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/android_sink.h @@ -116,4 +116,4 @@ inline std::shared_ptr<logger> android_logger_st(const std::string &logger_name, } // namespace spdlog -#endif // __ANDROID__
\ No newline at end of file +#endif // __ANDROID__ diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/ansicolor_sink-inl.h b/NorthstarDLL/include/spdlog/sinks/ansicolor_sink-inl.h index 61c0a719..61c0a719 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/ansicolor_sink-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/ansicolor_sink-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/ansicolor_sink.h b/NorthstarDLL/include/spdlog/sinks/ansicolor_sink.h index 4438f706..4438f706 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/ansicolor_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/ansicolor_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/base_sink-inl.h b/NorthstarDLL/include/spdlog/sinks/base_sink-inl.h index b15fb0e6..b15fb0e6 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/base_sink-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/base_sink-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/base_sink.h b/NorthstarDLL/include/spdlog/sinks/base_sink.h index bf5072f8..bf5072f8 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/base_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/base_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/basic_file_sink-inl.h b/NorthstarDLL/include/spdlog/sinks/basic_file_sink-inl.h index 1260d15c..1260d15c 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/basic_file_sink-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/basic_file_sink-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/basic_file_sink.h b/NorthstarDLL/include/spdlog/sinks/basic_file_sink.h index 0ab9a4a1..4a742624 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/basic_file_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/basic_file_sink.h @@ -55,4 +55,4 @@ inline std::shared_ptr<logger> basic_logger_st(const std::string &logger_name, c #ifdef SPDLOG_HEADER_ONLY #include "basic_file_sink-inl.h" -#endif
\ No newline at end of file +#endif diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/daily_file_sink.h b/NorthstarDLL/include/spdlog/sinks/daily_file_sink.h index 16be821a..16be821a 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/daily_file_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/daily_file_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/dist_sink.h b/NorthstarDLL/include/spdlog/sinks/dist_sink.h index 8fccb4ee..8fccb4ee 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/dist_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/dist_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/dup_filter_sink.h b/NorthstarDLL/include/spdlog/sinks/dup_filter_sink.h index c9a08d68..c9a08d68 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/dup_filter_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/dup_filter_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/hourly_file_sink.h b/NorthstarDLL/include/spdlog/sinks/hourly_file_sink.h index f5e34366..f5e34366 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/hourly_file_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/hourly_file_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/msvc_sink.h b/NorthstarDLL/include/spdlog/sinks/msvc_sink.h index 8fec428d..8fec428d 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/msvc_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/msvc_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/null_sink.h b/NorthstarDLL/include/spdlog/sinks/null_sink.h index eb832801..eb832801 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/null_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/null_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/ostream_sink.h b/NorthstarDLL/include/spdlog/sinks/ostream_sink.h index 95c1e962..95c1e962 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/ostream_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/ostream_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/ringbuffer_sink.h b/NorthstarDLL/include/spdlog/sinks/ringbuffer_sink.h index 1ee3f691..1ee3f691 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/ringbuffer_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/ringbuffer_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/rotating_file_sink-inl.h b/NorthstarDLL/include/spdlog/sinks/rotating_file_sink-inl.h index d715ebf3..d715ebf3 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/rotating_file_sink-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/rotating_file_sink.h b/NorthstarDLL/include/spdlog/sinks/rotating_file_sink.h index e1e85a7d..e1e85a7d 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/rotating_file_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/rotating_file_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/sink-inl.h b/NorthstarDLL/include/spdlog/sinks/sink-inl.h index a8dd6a6c..a8dd6a6c 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/sink-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/sink-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/sink.h b/NorthstarDLL/include/spdlog/sinks/sink.h index be99744d..be99744d 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/sink.h +++ b/NorthstarDLL/include/spdlog/sinks/sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_color_sinks-inl.h b/NorthstarDLL/include/spdlog/sinks/stdout_color_sinks-inl.h index 653aca80..935f1ccc 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_color_sinks-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/stdout_color_sinks-inl.h @@ -35,4 +35,4 @@ SPDLOG_INLINE std::shared_ptr<logger> stderr_color_st(const std::string &logger_ { return Factory::template create<sinks::stderr_color_sink_st>(logger_name, mode); } -} // namespace spdlog
\ No newline at end of file +} // namespace spdlog diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_color_sinks.h b/NorthstarDLL/include/spdlog/sinks/stdout_color_sinks.h index e67aa91b..e67aa91b 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_color_sinks.h +++ b/NorthstarDLL/include/spdlog/sinks/stdout_color_sinks.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_sinks-inl.h b/NorthstarDLL/include/spdlog/sinks/stdout_sinks-inl.h index 25192607..25192607 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_sinks-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/stdout_sinks-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_sinks.h b/NorthstarDLL/include/spdlog/sinks/stdout_sinks.h index 40688a46..40688a46 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/stdout_sinks.h +++ b/NorthstarDLL/include/spdlog/sinks/stdout_sinks.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/syslog_sink.h b/NorthstarDLL/include/spdlog/sinks/syslog_sink.h index 7c38fcb5..7c38fcb5 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/syslog_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/syslog_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/systemd_sink.h b/NorthstarDLL/include/spdlog/sinks/systemd_sink.h index d23824b8..d23824b8 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/systemd_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/systemd_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/tcp_sink.h b/NorthstarDLL/include/spdlog/sinks/tcp_sink.h index 9dd9e51d..9dd9e51d 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/tcp_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/tcp_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/win_eventlog_sink.h b/NorthstarDLL/include/spdlog/sinks/win_eventlog_sink.h index 68170dd9..68170dd9 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/win_eventlog_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/win_eventlog_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/wincolor_sink-inl.h b/NorthstarDLL/include/spdlog/sinks/wincolor_sink-inl.h index e2676d3c..e2676d3c 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/wincolor_sink-inl.h +++ b/NorthstarDLL/include/spdlog/sinks/wincolor_sink-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/sinks/wincolor_sink.h b/NorthstarDLL/include/spdlog/sinks/wincolor_sink.h index a82f1b24..a82f1b24 100644 --- a/NorthstarDedicatedTest/include/spdlog/sinks/wincolor_sink.h +++ b/NorthstarDLL/include/spdlog/sinks/wincolor_sink.h diff --git a/NorthstarDedicatedTest/include/spdlog/spdlog-inl.h b/NorthstarDLL/include/spdlog/spdlog-inl.h index 96e09f59..96e09f59 100644 --- a/NorthstarDedicatedTest/include/spdlog/spdlog-inl.h +++ b/NorthstarDLL/include/spdlog/spdlog-inl.h diff --git a/NorthstarDedicatedTest/include/spdlog/spdlog.h b/NorthstarDLL/include/spdlog/spdlog.h index bb130d94..bb130d94 100644 --- a/NorthstarDedicatedTest/include/spdlog/spdlog.h +++ b/NorthstarDLL/include/spdlog/spdlog.h diff --git a/NorthstarDedicatedTest/include/spdlog/stopwatch.h b/NorthstarDLL/include/spdlog/stopwatch.h index bb976b19..bb976b19 100644 --- a/NorthstarDedicatedTest/include/spdlog/stopwatch.h +++ b/NorthstarDLL/include/spdlog/stopwatch.h diff --git a/NorthstarDedicatedTest/include/spdlog/tweakme.h b/NorthstarDLL/include/spdlog/tweakme.h index 31e417ab..31e417ab 100644 --- a/NorthstarDedicatedTest/include/spdlog/tweakme.h +++ b/NorthstarDLL/include/spdlog/tweakme.h diff --git a/NorthstarDedicatedTest/include/spdlog/version.h b/NorthstarDLL/include/spdlog/version.h index 828f78cb..828f78cb 100644 --- a/NorthstarDedicatedTest/include/spdlog/version.h +++ b/NorthstarDLL/include/spdlog/version.h diff --git a/NorthstarDedicatedTest/keyvalues.cpp b/NorthstarDLL/keyvalues.cpp index 2063be62..98a9ce66 100644 --- a/NorthstarDedicatedTest/keyvalues.cpp +++ b/NorthstarDLL/keyvalues.cpp @@ -1,45 +1,16 @@ #include "pch.h" -#include "keyvalues.h" #include "modmanager.h" #include "filesystem.h" -#include "hookutils.h" #include <fstream> -// hook forward defs -typedef char (*KeyValues__LoadFromBufferType)( - void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7); -KeyValues__LoadFromBufferType KeyValues__LoadFromBuffer; -char KeyValues__LoadFromBufferHook( - void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7); - -void InitialiseKeyValues(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x426C30, &KeyValues__LoadFromBufferHook, reinterpret_cast<LPVOID*>(&KeyValues__LoadFromBuffer)); -} - -void* savedFilesystemPtr; - -char KeyValues__LoadFromBufferHook(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7) -{ - // this is just to allow playlists to get a valid pFileSystem ptr for kv building, other functions that call this particular overload of - // LoadFromBuffer seem to get called on network stuff exclusively not exactly sure what the address wanted here is, so just taking it - // from a function call that always happens before playlists is loaded - if (pFileSystem != nullptr) - savedFilesystemPtr = pFileSystem; - if (!pFileSystem && !strcmp(resourceName, "playlists")) - pFileSystem = savedFilesystemPtr; - - return KeyValues__LoadFromBuffer(self, resourceName, pBuffer, pFileSystem, a5, a6, a7); -} +AUTOHOOK_INIT() void ModManager::TryBuildKeyValues(const char* filename) { spdlog::info("Building KeyValues for file {}", filename); - std::string normalisedPath = fs::path(filename).lexically_normal().string(); + std::string normalisedPath = g_pModManager->NormaliseModFilePath(fs::path(filename)); fs::path compiledPath = GetCompiledAssetsPath() / filename; fs::path compiledDir = compiledPath.parent_path(); fs::create_directories(compiledDir); @@ -54,14 +25,14 @@ void ModManager::TryBuildKeyValues(const char* filename) // copy over patch kv files, and add #bases to new file, last mods' patches should be applied first // note: #include should be identical but it's actually just broken, thanks respawn - for (int64_t i = m_loadedMods.size() - 1; i > -1; i--) + for (int64_t i = m_LoadedMods.size() - 1; i > -1; i--) { - if (!m_loadedMods[i].Enabled) + if (!m_LoadedMods[i].m_bEnabled) continue; size_t fileHash = STR_HASH(normalisedPath); - auto modKv = m_loadedMods[i].KeyValues.find(fileHash); - if (modKv != m_loadedMods[i].KeyValues.end()) + auto modKv = m_LoadedMods[i].KeyValues.find(fileHash); + if (modKv != m_LoadedMods[i].KeyValues.end()) { // should result in smth along the lines of #include "mod_patch_5_mp_weapon_car.txt" @@ -76,7 +47,7 @@ void ModManager::TryBuildKeyValues(const char* filename) fs::remove(compiledDir / patchFilePath); - fs::copy_file(m_loadedMods[i].ModDirectory / "keyvalues" / filename, compiledDir / patchFilePath); + fs::copy_file(m_LoadedMods[i].m_ModDirectory / "keyvalues" / filename, compiledDir / patchFilePath); } } @@ -86,7 +57,7 @@ void ModManager::TryBuildKeyValues(const char* filename) newKvs += "\"\n"; // load original file, so we can parse out the name of the root obj (e.g. WeaponData for weapons) - std::string originalFile = ReadVPKOriginalFile(filename); + std::string originalFile = R2::ReadVPKOriginalFile(filename); if (!originalFile.length()) { @@ -96,7 +67,6 @@ void ModManager::TryBuildKeyValues(const char* filename) char rootName[64]; memset(rootName, 0, sizeof(rootName)); - rootName[63] = '\0'; // iterate until we hit an ascii char that isn't in a # command or comment to get root obj name int i = 0; @@ -127,11 +97,36 @@ void ModManager::TryBuildKeyValues(const char* filename) writeStream.close(); ModOverrideFile overrideFile; - overrideFile.owningMod = nullptr; - overrideFile.path = normalisedPath; + overrideFile.m_pOwningMod = nullptr; + overrideFile.m_Path = normalisedPath; - if (m_modFiles.find(normalisedPath) == m_modFiles.end()) - m_modFiles.insert(std::make_pair(normalisedPath, overrideFile)); + if (m_ModFiles.find(normalisedPath) == m_ModFiles.end()) + m_ModFiles.insert(std::make_pair(normalisedPath, overrideFile)); else - m_modFiles[normalisedPath] = overrideFile; -}
\ No newline at end of file + m_ModFiles[normalisedPath] = overrideFile; +} + +// clang-format off +AUTOHOOK(KeyValues__LoadFromBuffer, engine.dll + 0x426C30, +char, __fastcall, (void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7)) +// clang-format on +{ + static void* pSavedFilesystemPtr = nullptr; + + // this is just to allow playlists to get a valid pFileSystem ptr for kv building, other functions that call this particular overload of + // LoadFromBuffer seem to get called on network stuff exclusively not exactly sure what the address wanted here is, so just taking it + // from a function call that always happens before playlists is loaded + + // note: would be better if we could serialize this to disk for playlists, as this method breaks saving playlists in demos + if (pFileSystem != nullptr) + pSavedFilesystemPtr = pFileSystem; + if (!pFileSystem && !strcmp(resourceName, "playlists")) + pFileSystem = pSavedFilesystemPtr; + + return KeyValues__LoadFromBuffer(self, resourceName, pBuffer, pFileSystem, a5, a6, a7); +} + +ON_DLL_LOAD("engine.dll", KeyValues, (CModule module)) +{ + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDedicatedTest/languagehooks.cpp b/NorthstarDLL/languagehooks.cpp index c8d43901..d00beb68 100644 --- a/NorthstarDedicatedTest/languagehooks.cpp +++ b/NorthstarDLL/languagehooks.cpp @@ -1,18 +1,13 @@ #include "pch.h" -#include "languagehooks.h" -#include "gameutils.h" +#include "tier0.h" + #include <filesystem> #include <regex> -namespace fs = std::filesystem; - -typedef char* (*GetGameLanguageType)(); -char* GetGameLanguage(); +AUTOHOOK_INIT() typedef LANGID (*Tier0_DetectDefaultLanguageType)(); -GetGameLanguageType GetGameLanguageOriginal; - bool CheckLangAudioExists(char* lang) { std::string path {"r2\\sound\\general_"}; @@ -52,7 +47,10 @@ std::string GetAnyInstalledAudioLanguage() return "NO LANGUAGE DETECTED"; } -char* GetGameLanguageHook() +// clang-format off +AUTOHOOK(GetGameLanguage, tier0.dll + 0xF560, +char*, __fastcall, ()) +// clang-format on { auto tier0Handle = GetModuleHandleA("tier0.dll"); auto Tier0_DetectDefaultLanguageType = GetProcAddress(tier0Handle, "Tier0_DetectDefaultLanguage"); @@ -60,7 +58,7 @@ char* GetGameLanguageHook() bool& canOriginDictateLang = *(bool*)((char*)tier0Handle + 0xA9A90); const char* forcedLanguage; - if (CommandLine()->CheckParm("-language", &forcedLanguage)) + if (Tier0::CommandLine()->CheckParm("-language", &forcedLanguage)) { if (!CheckLangAudioExists((char*)forcedLanguage)) { @@ -79,7 +77,7 @@ char* GetGameLanguageHook() canOriginDictateLang = true; // let it try { - auto lang = GetGameLanguageOriginal(); + auto lang = GetGameLanguage(); if (!CheckLangAudioExists(lang)) { if (strcmp(lang, "russian") != @@ -97,7 +95,7 @@ char* GetGameLanguageHook() Tier0_DetectDefaultLanguageType(); // force the global in tier0 to be populated with language inferred from user's system rather than // defaulting to Russian canOriginDictateLang = false; // Origin has no say anymore, we will fallback to user's system setup language - auto lang = GetGameLanguageOriginal(); + auto lang = GetGameLanguage(); spdlog::info("Detected system language: {}", lang); if (!CheckLangAudioExists(lang)) { @@ -112,8 +110,7 @@ char* GetGameLanguageHook() return lang; } -void InitialiseTier0LanguageHooks(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT("tier0.dll", LanguageHooks, (CModule module)) { - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xF560, &GetGameLanguageHook, reinterpret_cast<LPVOID*>(&GetGameLanguageOriginal)); -}
\ No newline at end of file + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDLL/latencyflex.cpp b/NorthstarDLL/latencyflex.cpp new file mode 100644 index 00000000..620e031a --- /dev/null +++ b/NorthstarDLL/latencyflex.cpp @@ -0,0 +1,44 @@ +#include "pch.h" +#include "convar.h" + +AUTOHOOK_INIT() + +ConVar* Cvar_r_latencyflex; + +void (*m_winelfx_WaitAndBeginFrame)(); + +// clang-format off +AUTOHOOK(OnRenderStart, client.dll + 0x1952C0, +void, __fastcall, ()) +// clang-format on +{ + if (Cvar_r_latencyflex->GetBool() && m_winelfx_WaitAndBeginFrame) + m_winelfx_WaitAndBeginFrame(); + + OnRenderStart(); +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", LatencyFlex, ConVar, (CModule module)) +{ + // Connect to the LatencyFleX service + // LatencyFleX is an open source vendor agnostic replacement for Nvidia Reflex input latency reduction technology. + // https://ishitatsuyuki.github.io/post/latencyflex/ + HMODULE pLfxModule; + + if (pLfxModule = LoadLibraryA("latencyflex_layer.dll")) + m_winelfx_WaitAndBeginFrame = + reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "lfx_WaitAndBeginFrame"))); + else if (pLfxModule = LoadLibraryA("latencyflex_wine.dll")) + m_winelfx_WaitAndBeginFrame = + reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "winelfx_WaitAndBeginFrame"))); + else + { + spdlog::info("Unable to load LatencyFleX library, LatencyFleX disabled."); + return; + } + + AUTOHOOK_DISPATCH() + + spdlog::info("LatencyFleX initialized."); + Cvar_r_latencyflex = new ConVar("r_latencyflex", "1", FCVAR_ARCHIVE, "Whether or not to use LatencyFleX input latency reduction."); +} diff --git a/NorthstarDLL/limits.cpp b/NorthstarDLL/limits.cpp new file mode 100644 index 00000000..fd635136 --- /dev/null +++ b/NorthstarDLL/limits.cpp @@ -0,0 +1,299 @@ +#include "pch.h" +#include "limits.h" +#include "hoststate.h" +#include "r2client.h" +#include "r2engine.h" +#include "r2server.h" +#include "maxplayers.h" +#include "tier0.h" +#include "vector.h" +#include "serverauthentication.h" + +AUTOHOOK_INIT() + +ServerLimitsManager* g_pServerLimits; + +ConVar* Cvar_net_datablock_enabled; + +// todo: make this work on higher timescales, also possibly disable when sv_cheats is set +void ServerLimitsManager::RunFrame(double flCurrentTime, float flFrameTime) +{ + if (Cvar_sv_antispeedhack_enable->GetBool()) + { + // for each player, set their usercmd processing budget for the frame to the last frametime for the server + for (int i = 0; i < R2::GetMaxPlayers(); i++) + { + R2::CBaseClient* player = &R2::g_pClientArray[i]; + + if (m_PlayerLimitData.find(player) != m_PlayerLimitData.end()) + { + PlayerLimitData* pLimitData = &g_pServerLimits->m_PlayerLimitData[player]; + if (pLimitData->flFrameUserCmdBudget < 0.016666667 * Cvar_sv_antispeedhack_maxtickbudget->GetFloat()) + pLimitData->flFrameUserCmdBudget += + fmax(flFrameTime, 0.016666667) * g_pServerLimits->Cvar_sv_antispeedhack_budgetincreasemultiplier->GetFloat(); + } + } + } +} + +void ServerLimitsManager::AddPlayer(R2::CBaseClient* player) +{ + PlayerLimitData limitData; + limitData.flFrameUserCmdBudget = 0.016666667 * Cvar_sv_antispeedhack_maxtickbudget->GetFloat(); + + m_PlayerLimitData.insert(std::make_pair(player, limitData)); +} + +void ServerLimitsManager::RemovePlayer(R2::CBaseClient* player) +{ + if (m_PlayerLimitData.find(player) != m_PlayerLimitData.end()) + m_PlayerLimitData.erase(player); +} + +bool ServerLimitsManager::CheckStringCommandLimits(R2::CBaseClient* player) +{ + if (CVar_sv_quota_stringcmdspersecond->GetInt() != -1) + { + // note: this isn't super perfect, legit clients can trigger it in lobby if they try, mostly good enough tho imo + if (Tier0::Plat_FloatTime() - m_PlayerLimitData[player].lastClientCommandQuotaStart >= 1.0) + { + // reset quota + m_PlayerLimitData[player].lastClientCommandQuotaStart = Tier0::Plat_FloatTime(); + m_PlayerLimitData[player].numClientCommandsInQuota = 0; + } + + m_PlayerLimitData[player].numClientCommandsInQuota++; + if (m_PlayerLimitData[player].numClientCommandsInQuota > CVar_sv_quota_stringcmdspersecond->GetInt()) + { + // too many stringcmds, dc player + return false; + } + } + + return true; +} + +bool ServerLimitsManager::CheckChatLimits(R2::CBaseClient* player) +{ + if (Tier0::Plat_FloatTime() - m_PlayerLimitData[player].lastSayTextLimitStart >= 1.0) + { + m_PlayerLimitData[player].lastSayTextLimitStart = Tier0::Plat_FloatTime(); + m_PlayerLimitData[player].sayTextLimitCount = 0; + } + + if (m_PlayerLimitData[player].sayTextLimitCount >= Cvar_sv_max_chat_messages_per_sec->GetInt()) + return false; + + m_PlayerLimitData[player].sayTextLimitCount++; + return true; +} + +// clang-format off +AUTOHOOK(CNetChan__ProcessMessages, engine.dll + 0x2140A0, +char, __fastcall, (void* self, void* buf)) +// clang-format on +{ + enum eNetChanLimitMode + { + NETCHANLIMIT_WARN, + NETCHANLIMIT_KICK + }; + + double startTime = Tier0::Plat_FloatTime(); + char ret = CNetChan__ProcessMessages(self, buf); + + // check processing limits, unless we're in a level transition + if (R2::g_pHostState->m_iCurrentState == R2::HostState_t::HS_RUN && Tier0::ThreadInServerFrameThread()) + { + // player that sent the message + R2::CBaseClient* sender = *(R2::CBaseClient**)((char*)self + 368); + + // if no sender, return + // relatively certain this is fine? + if (!sender || !g_pServerLimits->m_PlayerLimitData.count(sender)) + return ret; + + // reset every second + if (startTime - g_pServerLimits->m_PlayerLimitData[sender].lastNetChanProcessingLimitStart >= 1.0 || + g_pServerLimits->m_PlayerLimitData[sender].lastNetChanProcessingLimitStart == -1.0) + { + g_pServerLimits->m_PlayerLimitData[sender].lastNetChanProcessingLimitStart = startTime; + g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime = 0.0; + } + g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime += (Tier0::Plat_FloatTime() * 1000) - (startTime * 1000); + + if (g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime >= + g_pServerLimits->Cvar_net_chan_limit_msec_per_sec->GetInt()) + { + spdlog::warn( + "Client {} hit netchan processing limit with {}ms of processing time this second (max is {})", + (char*)sender + 0x16, + g_pServerLimits->m_PlayerLimitData[sender].netChanProcessingLimitTime, + g_pServerLimits->Cvar_net_chan_limit_msec_per_sec->GetInt()); + + // never kick local player + if (g_pServerLimits->Cvar_net_chan_limit_mode->GetInt() != NETCHANLIMIT_WARN && strcmp(R2::g_pLocalPlayerUserID, sender->m_UID)) + { + R2::CBaseClient__Disconnect(sender, 1, "Exceeded net channel processing limit"); + return false; + } + } + } + + return ret; +} + +// clang-format off +AUTOHOOK(ProcessConnectionlessPacket, engine.dll + 0x117800, +bool, , (void* a1, R2::netpacket_t* packet)) +// clang-format on +{ + if (packet->adr.type == R2::NA_IP && + (!(packet->data[4] == 'N' && Cvar_net_datablock_enabled->GetBool()) || !Cvar_net_datablock_enabled->GetBool())) + { + // bad lookup: optimise later tm + UnconnectedPlayerLimitData* sendData = nullptr; + for (UnconnectedPlayerLimitData& foundSendData : g_pServerLimits->m_UnconnectedPlayerLimitData) + { + if (!memcmp(packet->adr.ip, foundSendData.ip, 16)) + { + sendData = &foundSendData; + break; + } + } + + if (!sendData) + { + sendData = &g_pServerLimits->m_UnconnectedPlayerLimitData.emplace_back(); + memcpy(sendData->ip, packet->adr.ip, 16); + } + + if (Tier0::Plat_FloatTime() < sendData->timeoutEnd) + return false; + + if (Tier0::Plat_FloatTime() - sendData->lastQuotaStart >= 1.0) + { + sendData->lastQuotaStart = Tier0::Plat_FloatTime(); + sendData->packetCount = 0; + } + + sendData->packetCount++; + + if (sendData->packetCount >= g_pServerLimits->Cvar_sv_querylimit_per_sec->GetInt()) + { + spdlog::warn( + "Client went over connectionless ratelimit of {} per sec with packet of type {}", + g_pServerLimits->Cvar_sv_querylimit_per_sec->GetInt(), + packet->data[4]); + + // timeout for a minute + sendData->timeoutEnd = Tier0::Plat_FloatTime() + 60.0; + return false; + } + } + + return ProcessConnectionlessPacket(a1, packet); +} + +// this is weird and i'm not sure if it's correct, so not using for now +/*AUTOHOOK(CBasePlayer__PhysicsSimulate, server.dll + 0x5A6E50, bool, __fastcall, (void* self, int a2, char a3)) +{ + spdlog::info("CBasePlayer::PhysicsSimulate"); + return CBasePlayer__PhysicsSimulate(self, a2, a3); +}*/ + +struct alignas(4) SV_CUserCmd +{ + DWORD command_number; + DWORD tick_count; + float command_time; + Vector3 worldViewAngles; + BYTE gap18[4]; + Vector3 localViewAngles; + Vector3 attackangles; + Vector3 move; + DWORD buttons; + BYTE impulse; + short weaponselect; + DWORD meleetarget; + BYTE gap4C[24]; + char headoffset; + BYTE gap65[11]; + Vector3 cameraPos; + Vector3 cameraAngles; + BYTE gap88[4]; + int tickSomething; + DWORD dword90; + DWORD predictedServerEventAck; + DWORD dword98; + float frameTime; +}; + +// clang-format off +AUTOHOOK(CPlayerMove__RunCommand, server.dll + 0x5B8100, +void, __fastcall, (void* self, R2::CBasePlayer* player, SV_CUserCmd* pUserCmd, uint64_t a4)) +// clang-format on +{ + if (g_pServerLimits->Cvar_sv_antispeedhack_enable->GetBool()) + { + R2::CBaseClient* pClient = &R2::g_pClientArray[player->m_nPlayerIndex - 1]; + + if (g_pServerLimits->m_PlayerLimitData.find(pClient) != g_pServerLimits->m_PlayerLimitData.end()) + { + PlayerLimitData* pLimitData = &g_pServerLimits->m_PlayerLimitData[pClient]; + + pLimitData->flFrameUserCmdBudget = fmax(0.0, pLimitData->flFrameUserCmdBudget - pUserCmd->frameTime); + + if (pLimitData->flFrameUserCmdBudget <= 0.0) + { + spdlog::warn("player {} went over usercmd budget ({})", pClient->m_Name, pLimitData->flFrameUserCmdBudget); + return; + } + // else + // spdlog::info("{}: {}", pClient->m_Name, pLimitData->flFrameUserCmdBudget); + } + } + + CPlayerMove__RunCommand(self, player, pUserCmd, a4); +} + +ON_DLL_LOAD_RELIESON("engine.dll", ServerLimits, ConVar, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(engine.dll) + + g_pServerLimits = new ServerLimitsManager; + + g_pServerLimits->CVar_sv_quota_stringcmdspersecond = new ConVar( + "sv_quota_stringcmdspersecond", + "60", + FCVAR_GAMEDLL, + "How many string commands per second clients are allowed to submit, 0 to disallow all string commands, -1 to disable"); + g_pServerLimits->Cvar_net_chan_limit_mode = + new ConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = warn, 1 = kick"); + g_pServerLimits->Cvar_net_chan_limit_msec_per_sec = new ConVar( + "net_chan_limit_msec_per_sec", + "100", + FCVAR_GAMEDLL, + "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget"); + g_pServerLimits->Cvar_sv_querylimit_per_sec = new ConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, ""); + g_pServerLimits->Cvar_sv_max_chat_messages_per_sec = new ConVar("sv_max_chat_messages_per_sec", "5", FCVAR_GAMEDLL, ""); + g_pServerLimits->Cvar_sv_antispeedhack_enable = + new ConVar("sv_antispeedhack_enable", "0", FCVAR_NONE, "whether to enable antispeedhack protections"); + g_pServerLimits->Cvar_sv_antispeedhack_maxtickbudget = new ConVar( + "sv_antispeedhack_maxtickbudget", + "64", + FCVAR_GAMEDLL, + "Maximum number of client-issued usercmd ticks that can be replayed in packet loss conditions, 0 to allow no restrictions"); + g_pServerLimits->Cvar_sv_antispeedhack_budgetincreasemultiplier = new ConVar( + "sv_antispeedhack_budgetincreasemultiplier", + "1.2", + FCVAR_GAMEDLL, + "Increase usercmd processing budget by tickinterval * value per tick"); + + Cvar_net_datablock_enabled = R2::g_pCVar->FindVar("net_datablock_enabled"); +} + +ON_DLL_LOAD("server.dll", ServerLimitsServer, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(server.dll) +} diff --git a/NorthstarDLL/limits.h b/NorthstarDLL/limits.h new file mode 100644 index 00000000..068f91c9 --- /dev/null +++ b/NorthstarDLL/limits.h @@ -0,0 +1,51 @@ +#pragma once +#include "r2engine.h" +#include "convar.h" +#include <unordered_map> + +struct PlayerLimitData +{ + double lastClientCommandQuotaStart = -1.0; + int numClientCommandsInQuota = 0; + + double lastNetChanProcessingLimitStart = -1.0; + double netChanProcessingLimitTime = 0.0; + + double lastSayTextLimitStart = -1.0; + int sayTextLimitCount = 0; + + float flFrameUserCmdBudget = 0.0; +}; + +struct UnconnectedPlayerLimitData +{ + char ip[16]; + double lastQuotaStart = 0.0; + int packetCount = 0; + double timeoutEnd = -1.0; +}; + +class ServerLimitsManager +{ + public: + ConVar* CVar_sv_quota_stringcmdspersecond; + ConVar* Cvar_net_chan_limit_mode; + ConVar* Cvar_net_chan_limit_msec_per_sec; + ConVar* Cvar_sv_querylimit_per_sec; + ConVar* Cvar_sv_max_chat_messages_per_sec; + ConVar* Cvar_sv_antispeedhack_enable; + ConVar* Cvar_sv_antispeedhack_maxtickbudget; + ConVar* Cvar_sv_antispeedhack_budgetincreasemultiplier; + + std::unordered_map<R2::CBaseClient*, PlayerLimitData> m_PlayerLimitData; + std::vector<UnconnectedPlayerLimitData> m_UnconnectedPlayerLimitData; + + public: + void RunFrame(double flCurrentTime, float flFrameTime); + void AddPlayer(R2::CBaseClient* player); + void RemovePlayer(R2::CBaseClient* player); + bool CheckStringCommandLimits(R2::CBaseClient* player); + bool CheckChatLimits(R2::CBaseClient* player); +}; + +extern ServerLimitsManager* g_pServerLimits; diff --git a/NorthstarDedicatedTest/localchatwriter.cpp b/NorthstarDLL/localchatwriter.cpp index 72a5afa7..efa7eeee 100644 --- a/NorthstarDedicatedTest/localchatwriter.cpp +++ b/NorthstarDLL/localchatwriter.cpp @@ -37,12 +37,11 @@ class vgui_BaseRichText_vtable void(__fastcall* SetVerticalScrollbar)(vgui_BaseRichText* self, bool state); void(__fastcall* SetMaximumCharCount)(vgui_BaseRichText* self, int maxChars); - void(__fastcall* InsertColorChange)(vgui_BaseRichText* self, vgui_Color col); + void(__fastcall* InsertColorChange)(vgui_BaseRichText* self, Color col); void(__fastcall* InsertIndentChange)(vgui_BaseRichText* self, int pixelsIndent); void(__fastcall* InsertClickableTextStart)(vgui_BaseRichText* self, const char* pchClickAction); void(__fastcall* InsertClickableTextEnd)(vgui_BaseRichText* self); - void(__fastcall* InsertPossibleURLString)( - vgui_BaseRichText* self, const char* text, vgui_Color URLTextColor, vgui_Color normalTextColor); + void(__fastcall* InsertPossibleURLString)(vgui_BaseRichText* self, const char* text, Color URLTextColor, Color normalTextColor); void(__fastcall* InsertFade)(vgui_BaseRichText* self, float flSustain, float flLength); void(__fastcall* ResetAllFades)(vgui_BaseRichText* self, bool bHold, bool bOnlyExpired, float flNewSustain); void(__fastcall* SetToFullHeight)(vgui_BaseRichText* self); @@ -81,25 +80,25 @@ LocalChatWriter::SwatchColor swatchColors[4] = { LocalChatWriter::NetworkNameColor, }; -vgui_Color darkColors[8] = { - vgui_Color {0, 0, 0, 255}, - vgui_Color {205, 49, 49, 255}, - vgui_Color {13, 188, 121, 255}, - vgui_Color {229, 229, 16, 255}, - vgui_Color {36, 114, 200, 255}, - vgui_Color {188, 63, 188, 255}, - vgui_Color {17, 168, 205, 255}, - vgui_Color {229, 229, 229, 255}}; - -vgui_Color lightColors[8] = { - vgui_Color {102, 102, 102, 255}, - vgui_Color {241, 76, 76, 255}, - vgui_Color {35, 209, 139, 255}, - vgui_Color {245, 245, 67, 255}, - vgui_Color {59, 142, 234, 255}, - vgui_Color {214, 112, 214, 255}, - vgui_Color {41, 184, 219, 255}, - vgui_Color {255, 255, 255, 255}}; +Color darkColors[8] = { + Color {0, 0, 0, 255}, + Color {205, 49, 49, 255}, + Color {13, 188, 121, 255}, + Color {229, 229, 16, 255}, + Color {36, 114, 200, 255}, + Color {188, 63, 188, 255}, + Color {17, 168, 205, 255}, + Color {229, 229, 229, 255}}; + +Color lightColors[8] = { + Color {102, 102, 102, 255}, + Color {241, 76, 76, 255}, + Color {35, 209, 139, 255}, + Color {245, 245, 67, 255}, + Color {59, 142, 234, 255}, + Color {214, 112, 214, 255}, + Color {41, 184, 219, 255}, + Color {255, 255, 255, 255}}; class AnsiEscapeParser { @@ -144,7 +143,7 @@ class AnsiEscapeParser LocalChatWriter* m_writer; Next m_next = Next::ControlType; - vgui_Color m_expandedColor {0, 0, 0, 0}; + Color m_expandedColor {0, 0, 0, 0}; Next HandleControlType(unsigned long val) { @@ -190,7 +189,7 @@ class AnsiEscapeParser // Next values are r,g,b if (val == 2) { - m_expandedColor = {0, 0, 0, 255}; + m_expandedColor.SetColor(0, 0, 0, 255); return Next::ForegroundR; } // Next value is 8-bit swatch color @@ -219,13 +218,12 @@ class AnsiEscapeParser unsigned char blue = code % 6; unsigned char green = ((code - blue) / 6) % 6; unsigned char red = (code - blue - (green * 6)) / 36; - m_writer->InsertColorChange( - vgui_Color {(unsigned char)(red * 51), (unsigned char)(green * 51), (unsigned char)(blue * 51), 255}); + m_writer->InsertColorChange(Color {(unsigned char)(red * 51), (unsigned char)(green * 51), (unsigned char)(blue * 51), 255}); } else if (val < UCHAR_MAX) { unsigned char brightness = (val - 232) * 10 + 8; - m_writer->InsertColorChange(vgui_Color {brightness, brightness, brightness, 255}); + m_writer->InsertColorChange(Color {brightness, brightness, brightness, 255}); } return Next::ControlType; @@ -236,7 +234,7 @@ class AnsiEscapeParser if (val >= UCHAR_MAX) return Next::ControlType; - m_expandedColor.r = (unsigned char)val; + m_expandedColor[0] = (unsigned char)val; return Next::ForegroundG; } @@ -245,7 +243,7 @@ class AnsiEscapeParser if (val >= UCHAR_MAX) return Next::ControlType; - m_expandedColor.g = (unsigned char)val; + m_expandedColor[1] = (unsigned char)val; return Next::ForegroundB; } @@ -254,7 +252,7 @@ class AnsiEscapeParser if (val >= UCHAR_MAX) return Next::ControlType; - m_expandedColor.b = (unsigned char)val; + m_expandedColor[2] = (unsigned char)val; m_writer->InsertColorChange(m_expandedColor); return Next::ControlType; } @@ -280,12 +278,11 @@ void LocalChatWriter::Write(const char* str) if (startOfEscape != str) { // There is some text before the escape sequence, just print that - size_t copyChars = startOfEscape - str; if (copyChars > 255) copyChars = 255; - strncpy(writeBuffer, str, copyChars); - writeBuffer[copyChars] = 0; + + strncpy_s(writeBuffer, copyChars + 1, str, copyChars); InsertText(writeBuffer); } @@ -320,6 +317,8 @@ void LocalChatWriter::InsertChar(wchar_t ch) void LocalChatWriter::InsertText(const char* str) { + spdlog::info(str); + WCHAR messageUnicode[288]; ConvertANSIToUnicode(str, -1, messageUnicode, 274); @@ -347,7 +346,7 @@ void LocalChatWriter::InsertText(const wchar_t* str) InsertDefaultFade(); } -void LocalChatWriter::InsertColorChange(vgui_Color color) +void LocalChatWriter::InsertColorChange(Color color) { for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next) { @@ -358,20 +357,24 @@ void LocalChatWriter::InsertColorChange(vgui_Color color) } } -static vgui_Color GetHudSwatchColor(CHudChat* hud, LocalChatWriter::SwatchColor swatchColor) +static Color GetHudSwatchColor(CHudChat* hud, LocalChatWriter::SwatchColor swatchColor) { switch (swatchColor) { case LocalChatWriter::MainTextColor: return hud->m_mainTextColor; + case LocalChatWriter::SameTeamNameColor: return hud->m_sameTeamColor; + case LocalChatWriter::EnemyTeamNameColor: return hud->m_enemyTeamColor; + case LocalChatWriter::NetworkNameColor: return hud->m_networkNameColor; } - return vgui_Color {0, 0, 0, 0}; + + return Color(0, 0, 0, 0); } void LocalChatWriter::InsertSwatchColorChange(SwatchColor swatchColor) @@ -436,12 +439,12 @@ void LocalChatWriter::InsertDefaultFade() } } -void InitialiseLocalChatWriter(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT("client.dll", LocalChatWriter, (CModule module)) { - gGameSettings = (CGameSettings**)((char*)baseAddress + 0x11BAA48); - gChatFadeLength = (CGameFloatVar**)((char*)baseAddress + 0x11BAB78); - gChatFadeSustain = (CGameFloatVar**)((char*)baseAddress + 0x11BAC08); - CHudChat::allHuds = (CHudChat**)((char*)baseAddress + 0x11BA9E8); + gGameSettings = module.Offset(0x11BAA48).As<CGameSettings**>(); + gChatFadeLength = module.Offset(0x11BAB78).As<CGameFloatVar**>(); + gChatFadeSustain = module.Offset(0x11BAC08).As<CGameFloatVar**>(); + CHudChat::allHuds = module.Offset(0x11BA9E8).As<CHudChat**>(); - ConvertANSIToUnicode = (ConvertANSIToUnicodeType)((char*)baseAddress + 0x7339A0); + ConvertANSIToUnicode = module.Offset(0x7339A0).As<ConvertANSIToUnicodeType>(); } diff --git a/NorthstarDedicatedTest/localchatwriter.h b/NorthstarDLL/localchatwriter.h index 8048e084..0df0cac8 100644 --- a/NorthstarDedicatedTest/localchatwriter.h +++ b/NorthstarDLL/localchatwriter.h @@ -1,13 +1,6 @@ #pragma once #include "pch.h" - -struct vgui_Color -{ - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; -}; +#include "color.h" class vgui_BaseRichText; @@ -18,10 +11,10 @@ class CHudChat char unknown1[720]; - vgui_Color m_sameTeamColor; - vgui_Color m_enemyTeamColor; - vgui_Color m_mainTextColor; - vgui_Color m_networkNameColor; + Color m_sameTeamColor; + Color m_enemyTeamColor; + Color m_mainTextColor; + Color m_networkNameColor; char unknown2[12]; @@ -61,7 +54,7 @@ class LocalChatWriter void InsertChar(wchar_t ch); void InsertText(const char* str); void InsertText(const wchar_t* str); - void InsertColorChange(vgui_Color color); + void InsertColorChange(Color color); void InsertSwatchColorChange(SwatchColor color); private: @@ -70,5 +63,3 @@ class LocalChatWriter const char* ApplyAnsiEscape(const char* escape); void InsertDefaultFade(); }; - -void InitialiseLocalChatWriter(HMODULE baseAddress); diff --git a/NorthstarDLL/logging.cpp b/NorthstarDLL/logging.cpp new file mode 100644 index 00000000..7c6d50a6 --- /dev/null +++ b/NorthstarDLL/logging.cpp @@ -0,0 +1,259 @@ +#include "pch.h" +#include "logging.h" +#include "convar.h" +#include "concommand.h" +#include "nsprefix.h" +#include "bitbuf.h" +#include "tier0.h" +#include "spdlog/sinks/basic_file_sink.h" + +#include <iomanip> +#include <sstream> + +AUTOHOOK_INIT() + +ConVar* Cvar_spewlog_enable; + +enum class SpewType_t +{ + SPEW_MESSAGE = 0, + + SPEW_WARNING, + SPEW_ASSERT, + SPEW_ERROR, + SPEW_LOG, + + SPEW_TYPE_COUNT +}; + +const std::unordered_map<SpewType_t, const char*> PrintSpewTypes = { + {SpewType_t::SPEW_MESSAGE, "SPEW_MESSAGE"}, + {SpewType_t::SPEW_WARNING, "SPEW_WARNING"}, + {SpewType_t::SPEW_ASSERT, "SPEW_ASSERT"}, + {SpewType_t::SPEW_ERROR, "SPEW_ERROR"}, + {SpewType_t::SPEW_LOG, "SPEW_LOG"}}; + +// clang-format off +AUTOHOOK(EngineSpewFunc, engine.dll + 0x11CA80, +void, __fastcall, (void* pEngineServer, SpewType_t type, const char* format, va_list args)) +// clang-format on +{ + if (!Cvar_spewlog_enable->GetBool()) + return; + + const char* typeStr = PrintSpewTypes.at(type); + char formatted[2048] = {0}; + bool bShouldFormat = true; + + // because titanfall 2 is quite possibly the worst thing to yet exist, it sometimes gives invalid specifiers which will crash + // ttf2sdk had a way to prevent them from crashing but it doesnt work in debug builds + // so we use this instead + for (int i = 0; format[i]; i++) + { + if (format[i] == '%') + { + switch (format[i + 1]) + { + // this is fucking awful lol + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'f': + case 'F': + case 'g': + case 'G': + case 'a': + case 'A': + case 'c': + case 's': + case 'p': + case 'n': + case '%': + case '-': + case '+': + case ' ': + case '#': + case '*': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + + default: + { + bShouldFormat = false; + break; + } + } + } + } + + if (bShouldFormat) + vsnprintf(formatted, sizeof(formatted), format, args); + else + spdlog::warn("Failed to format {} \"{}\"", typeStr, format); + + auto endpos = strlen(formatted); + if (formatted[endpos - 1] == '\n') + formatted[endpos - 1] = '\0'; // cut off repeated newline + + spdlog::info("[SERVER {}] {}", typeStr, formatted); +} + +// used for printing the output of status +// clang-format off +AUTOHOOK(Status_ConMsg, engine.dll + 0x15ABD0, +void,, (const char* text, ...)) +// clang-format on +{ + char formatted[2048]; + va_list list; + + va_start(list, text); + vsprintf_s(formatted, text, list); + va_end(list); + + auto endpos = strlen(formatted); + if (formatted[endpos - 1] == '\n') + formatted[endpos - 1] = '\0'; // cut off repeated newline + + spdlog::info(formatted); +} + +// clang-format off +AUTOHOOK(CClientState_ProcessPrint, engine.dll + 0x1A1530, +bool,, (void* thisptr, uintptr_t msg)) +// clang-format on +{ + char* text = *(char**)(msg + 0x20); + + auto endpos = strlen(text); + if (text[endpos - 1] == '\n') + text[endpos - 1] = '\0'; // cut off repeated newline + + spdlog::info(text); + return true; +} + +ConVar* Cvar_cl_showtextmsg; + +class ICenterPrint +{ + public: + virtual void ctor() = 0; + virtual void Clear(void) = 0; + virtual void ColorPrint(int r, int g, int b, int a, wchar_t* text) = 0; + virtual void ColorPrint(int r, int g, int b, int a, char* text) = 0; + virtual void Print(wchar_t* text) = 0; + virtual void Print(char* text) = 0; + virtual void SetTextColor(int r, int g, int b, int a) = 0; +}; + +ICenterPrint* pInternalCenterPrint = NULL; + +enum class TextMsgPrintType_t +{ + HUD_PRINTNOTIFY = 1, + HUD_PRINTCONSOLE, + HUD_PRINTTALK, + HUD_PRINTCENTER +}; + +// clang-format off +AUTOHOOK(TextMsg, client.dll + 0x198710, +void,, (BFRead* msg)) +// clang-format on +{ + TextMsgPrintType_t msg_dest = (TextMsgPrintType_t)msg->ReadByte(); + + char text[256]; + msg->ReadString(text, sizeof(text)); + + if (!Cvar_cl_showtextmsg->GetBool()) + return; + + switch (msg_dest) + { + case TextMsgPrintType_t::HUD_PRINTCENTER: + pInternalCenterPrint->Print(text); + break; + + default: + spdlog::warn("Unimplemented TextMsg type {}! printing to console", msg_dest); + [[fallthrough]]; + + case TextMsgPrintType_t::HUD_PRINTCONSOLE: + auto endpos = strlen(text); + if (text[endpos - 1] == '\n') + text[endpos - 1] = '\0'; // cut off repeated newline + + spdlog::info(text); + break; + } +} + +// clang-format off +AUTOHOOK(ConCommand_echo, engine.dll + 0x123680, +void,, (const CCommand& arg)) +// clang-format on +{ + if (arg.ArgC() >= 2) + spdlog::info("[echo] {}", arg.ArgS()); +} + +// This needs to be called after hooks are loaded so we can access the command line args +void CreateLogFiles() +{ + if (strstr(GetCommandLineA(), "-disablelogs")) + { + spdlog::default_logger()->set_level(spdlog::level::off); + } + else + { + // todo: might be good to delete logs that are too old + time_t time = std::time(nullptr); + tm currentTime = *std::localtime(&time); + std::stringstream stream; + + stream << std::put_time(¤tTime, (GetNorthstarPrefix() + "/logs/nslog%Y-%m-%d %H-%M-%S.txt").c_str()); + spdlog::default_logger()->sinks().push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(stream.str(), false)); + spdlog::flush_on(spdlog::level::info); + } +} + +void InitialiseLogging() +{ + AllocConsole(); + + // Bind stdout to receive console output. + // these two lines are responsible for stuff to not show up in the console sometimes, from talking about it on discord + // apparently they were meant to make logging work when using -northstar, however from testing it seems that it doesnt + // work regardless of these two lines + // freopen("CONOUT$", "w", stdout); + // freopen("CONOUT$", "w", stderr); + spdlog::default_logger()->set_pattern("[%H:%M:%S] [%l] %v"); +} + +ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", EngineSpewFuncHooks, ConVar, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(engine.dll) + + Cvar_spewlog_enable = new ConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged"); +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientPrintHooks, ConVar, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(client.dll) + + Cvar_cl_showtextmsg = new ConVar("cl_showtextmsg", "1", FCVAR_NONE, "Enable/disable text messages printing on the screen."); + pInternalCenterPrint = module.Offset(0x216E940).As<ICenterPrint*>(); +} diff --git a/NorthstarDLL/logging.h b/NorthstarDLL/logging.h new file mode 100644 index 00000000..83fd0c12 --- /dev/null +++ b/NorthstarDLL/logging.h @@ -0,0 +1,4 @@ +#pragma once + +void CreateLogFiles(); +void InitialiseLogging(); diff --git a/NorthstarDedicatedTest/main.h b/NorthstarDLL/main.h index 64f9cfd2..412f1e25 100644 --- a/NorthstarDedicatedTest/main.h +++ b/NorthstarDLL/main.h @@ -1,4 +1,4 @@ #pragma once extern "C" __declspec(dllexport) bool InitialiseNorthstar(); -extern "C" __declspec(dllexport) bool LoadPlugins();
\ No newline at end of file +extern "C" __declspec(dllexport) bool LoadPlugins(); diff --git a/NorthstarDLL/masterserver.cpp b/NorthstarDLL/masterserver.cpp new file mode 100644 index 00000000..b8e00bdc --- /dev/null +++ b/NorthstarDLL/masterserver.cpp @@ -0,0 +1,1076 @@ +#include "pch.h" +#include "masterserver.h" +#include "concommand.h" +#include "playlist.h" +#include "serverauthentication.h" +#include "tier0.h" +#include "r2engine.h" +#include "modmanager.h" +#include "misccommands.h" +#include "version.h" + +#include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" +#include "rapidjson/error/en.h" + +#include <cstring> +#include <regex> + +MasterServerManager* g_pMasterServerManager; + +ConVar* Cvar_ns_masterserver_hostname; +ConVar* Cvar_ns_curl_log_enable; + +RemoteServerInfo::RemoteServerInfo( + const char* newId, + const char* newName, + const char* newDescription, + const char* newMap, + const char* newPlaylist, + int newPlayerCount, + int newMaxPlayers, + bool newRequiresPassword) +{ + // passworded servers don't have public ips + requiresPassword = newRequiresPassword; + + strncpy_s((char*)id, sizeof(id), newId, sizeof(id) - 1); + strncpy_s((char*)name, sizeof(name), newName, sizeof(name) - 1); + + description = std::string(newDescription); + + strncpy_s((char*)map, sizeof(map), newMap, sizeof(map) - 1); + strncpy_s((char*)playlist, sizeof(playlist), newPlaylist, sizeof(playlist) - 1); + + playerCount = newPlayerCount; + maxPlayers = newMaxPlayers; +} + +void SetCommonHttpClientOptions(CURL* curl) +{ + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + curl_easy_setopt(curl, CURLOPT_VERBOSE, Cvar_ns_curl_log_enable->GetBool()); + curl_easy_setopt(curl, CURLOPT_USERAGENT, &NSUserAgent); + // curl_easy_setopt(curl, CURLOPT_STDERR, stdout); + if (Tier0::CommandLine()->FindParm("-msinsecure")) // TODO: this check doesn't seem to work + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + } +} + +void MasterServerManager::ClearServerList() +{ + // this doesn't really do anything lol, probably isn't threadsafe + m_bRequestingServerList = true; + + m_vRemoteServers.clear(); + + m_bRequestingServerList = false; +} + +size_t CurlWriteToStringBufferCallback(char* contents, size_t size, size_t nmemb, void* userp) +{ + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; +} + +void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, const char* originToken) +{ + if (m_bOriginAuthWithMasterServerInProgress) + return; + + // do this here so it's instantly set + m_bOriginAuthWithMasterServerInProgress = true; + std::string uidStr(uid); + std::string tokenStr(originToken); + + std::thread requestThread( + [this, uidStr, tokenStr]() + { + spdlog::info("Trying to authenticate with northstar masterserver for user {}", uidStr); + + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + std::string readBuffer; + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format("{}/client/origin_auth?id={}&token={}", Cvar_ns_masterserver_hostname->GetString(), uidStr, tokenStr).c_str()); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + m_bSuccessfullyConnected = true; + + rapidjson_document originAuthInfo; + originAuthInfo.Parse(readBuffer.c_str()); + + if (originAuthInfo.HasParseError()) + { + spdlog::error( + "Failed reading origin auth info response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(originAuthInfo.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (!originAuthInfo.IsObject() || !originAuthInfo.HasMember("success")) + { + spdlog::error("Failed reading origin auth info response: malformed response object {}", readBuffer); + goto REQUEST_END_CLEANUP; + } + + if (originAuthInfo["success"].IsTrue() && originAuthInfo.HasMember("token") && originAuthInfo["token"].IsString()) + { + strncpy_s( + m_sOwnClientAuthToken, + sizeof(m_sOwnClientAuthToken), + originAuthInfo["token"].GetString(), + sizeof(m_sOwnClientAuthToken) - 1); + spdlog::info("Northstar origin authentication completed successfully!"); + } + else + spdlog::error("Northstar origin authentication failed"); + } + else + { + spdlog::error("Failed performing northstar origin auth: error {}", curl_easy_strerror(result)); + m_bSuccessfullyConnected = false; + } + + // we goto this instead of returning so we always hit this + REQUEST_END_CLEANUP: + m_bOriginAuthWithMasterServerInProgress = false; + m_bOriginAuthWithMasterServerDone = true; + curl_easy_cleanup(curl); + }); + + requestThread.detach(); +} + +void MasterServerManager::RequestServerList() +{ + // do this here so it's instantly set on call for scripts + m_bScriptRequestingServerList = true; + + std::thread requestThread( + [this]() + { + // make sure we never have 2 threads writing at once + // i sure do hope this is actually threadsafe + while (m_bRequestingServerList) + Sleep(100); + + m_bRequestingServerList = true; + m_bScriptRequestingServerList = true; + + spdlog::info("Requesting server list from {}", Cvar_ns_masterserver_hostname->GetString()); + + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/client/servers", Cvar_ns_masterserver_hostname->GetString()).c_str()); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + m_bSuccessfullyConnected = true; + + rapidjson_document serverInfoJson; + serverInfoJson.Parse(readBuffer.c_str()); + + if (serverInfoJson.HasParseError()) + { + spdlog::error( + "Failed reading masterserver response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(serverInfoJson.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (serverInfoJson.IsObject() && serverInfoJson.HasMember("error")) + { + spdlog::error("Failed reading masterserver response: got fastify error response"); + spdlog::error(readBuffer); + goto REQUEST_END_CLEANUP; + } + + if (!serverInfoJson.IsArray()) + { + spdlog::error("Failed reading masterserver response: root object is not an array"); + goto REQUEST_END_CLEANUP; + } + + rapidjson::GenericArray<false, rapidjson_document::GenericValue> serverArray = serverInfoJson.GetArray(); + + spdlog::info("Got {} servers", serverArray.Size()); + + for (auto& serverObj : serverArray) + { + if (!serverObj.IsObject()) + { + spdlog::error("Failed reading masterserver response: member of server array is not an object"); + goto REQUEST_END_CLEANUP; + } + + // todo: verify json props are fine before adding to m_remoteServers + if (!serverObj.HasMember("id") || !serverObj["id"].IsString() || !serverObj.HasMember("name") || + !serverObj["name"].IsString() || !serverObj.HasMember("description") || !serverObj["description"].IsString() || + !serverObj.HasMember("map") || !serverObj["map"].IsString() || !serverObj.HasMember("playlist") || + !serverObj["playlist"].IsString() || !serverObj.HasMember("playerCount") || !serverObj["playerCount"].IsNumber() || + !serverObj.HasMember("maxPlayers") || !serverObj["maxPlayers"].IsNumber() || !serverObj.HasMember("hasPassword") || + !serverObj["hasPassword"].IsBool() || !serverObj.HasMember("modInfo") || !serverObj["modInfo"].HasMember("Mods") || + !serverObj["modInfo"]["Mods"].IsArray()) + { + spdlog::error("Failed reading masterserver response: malformed server object"); + continue; + }; + + const char* id = serverObj["id"].GetString(); + + RemoteServerInfo* newServer = nullptr; + + bool createNewServerInfo = true; + for (RemoteServerInfo& server : m_vRemoteServers) + { + // if server already exists, update info rather than adding to it + if (!strncmp((const char*)server.id, id, 32)) + { + server = RemoteServerInfo( + id, + serverObj["name"].GetString(), + serverObj["description"].GetString(), + serverObj["map"].GetString(), + serverObj["playlist"].GetString(), + serverObj["playerCount"].GetInt(), + serverObj["maxPlayers"].GetInt(), + serverObj["hasPassword"].IsTrue()); + newServer = &server; + createNewServerInfo = false; + break; + } + } + + // server didn't exist + if (createNewServerInfo) + newServer = &m_vRemoteServers.emplace_back( + id, + serverObj["name"].GetString(), + serverObj["description"].GetString(), + serverObj["map"].GetString(), + serverObj["playlist"].GetString(), + serverObj["playerCount"].GetInt(), + serverObj["maxPlayers"].GetInt(), + serverObj["hasPassword"].IsTrue()); + + newServer->requiredMods.clear(); + for (auto& requiredMod : serverObj["modInfo"]["Mods"].GetArray()) + { + RemoteModInfo modInfo; + + if (!requiredMod.HasMember("RequiredOnClient") || !requiredMod["RequiredOnClient"].IsTrue()) + continue; + + if (!requiredMod.HasMember("Name") || !requiredMod["Name"].IsString()) + continue; + modInfo.Name = requiredMod["Name"].GetString(); + + if (!requiredMod.HasMember("Version") || !requiredMod["Version"].IsString()) + continue; + modInfo.Version = requiredMod["Version"].GetString(); + + newServer->requiredMods.push_back(modInfo); + } + // Can probably re-enable this later with a -verbose flag, but slows down loading of the server browser quite a bit as + // is + // spdlog::info( + // "Server {} on map {} with playlist {} has {}/{} players", serverObj["name"].GetString(), + // serverObj["map"].GetString(), serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), + // serverObj["maxPlayers"].GetInt()); + } + + std::sort( + m_vRemoteServers.begin(), + m_vRemoteServers.end(), + [](RemoteServerInfo& a, RemoteServerInfo& b) { return a.playerCount > b.playerCount; }); + } + else + { + spdlog::error("Failed requesting servers: error {}", curl_easy_strerror(result)); + m_bSuccessfullyConnected = false; + } + + // we goto this instead of returning so we always hit this + REQUEST_END_CLEANUP: + m_bRequestingServerList = false; + m_bScriptRequestingServerList = false; + curl_easy_cleanup(curl); + }); + + requestThread.detach(); +} + +void MasterServerManager::RequestMainMenuPromos() +{ + m_bHasMainMenuPromoData = false; + + std::thread requestThread( + [this]() + { + while (m_bOriginAuthWithMasterServerInProgress || !m_bOriginAuthWithMasterServerDone) + Sleep(500); + + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt( + curl, CURLOPT_URL, fmt::format("{}/client/mainmenupromos", Cvar_ns_masterserver_hostname->GetString()).c_str()); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + m_bSuccessfullyConnected = true; + + rapidjson_document mainMenuPromoJson; + mainMenuPromoJson.Parse(readBuffer.c_str()); + + if (mainMenuPromoJson.HasParseError()) + { + spdlog::error( + "Failed reading masterserver main menu promos response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(mainMenuPromoJson.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (!mainMenuPromoJson.IsObject()) + { + spdlog::error("Failed reading masterserver main menu promos response: root object is not an object"); + goto REQUEST_END_CLEANUP; + } + + if (mainMenuPromoJson.HasMember("error")) + { + spdlog::error("Failed reading masterserver response: got fastify error response"); + spdlog::error(readBuffer); + goto REQUEST_END_CLEANUP; + } + + if (!mainMenuPromoJson.HasMember("newInfo") || !mainMenuPromoJson["newInfo"].IsObject() || + !mainMenuPromoJson["newInfo"].HasMember("Title1") || !mainMenuPromoJson["newInfo"]["Title1"].IsString() || + !mainMenuPromoJson["newInfo"].HasMember("Title2") || !mainMenuPromoJson["newInfo"]["Title2"].IsString() || + !mainMenuPromoJson["newInfo"].HasMember("Title3") || !mainMenuPromoJson["newInfo"]["Title3"].IsString() || + + !mainMenuPromoJson.HasMember("largeButton") || !mainMenuPromoJson["largeButton"].IsObject() || + !mainMenuPromoJson["largeButton"].HasMember("Title") || !mainMenuPromoJson["largeButton"]["Title"].IsString() || + !mainMenuPromoJson["largeButton"].HasMember("Text") || !mainMenuPromoJson["largeButton"]["Text"].IsString() || + !mainMenuPromoJson["largeButton"].HasMember("Url") || !mainMenuPromoJson["largeButton"]["Url"].IsString() || + !mainMenuPromoJson["largeButton"].HasMember("ImageIndex") || + !mainMenuPromoJson["largeButton"]["ImageIndex"].IsNumber() || + + !mainMenuPromoJson.HasMember("smallButton1") || !mainMenuPromoJson["smallButton1"].IsObject() || + !mainMenuPromoJson["smallButton1"].HasMember("Title") || !mainMenuPromoJson["smallButton1"]["Title"].IsString() || + !mainMenuPromoJson["smallButton1"].HasMember("Url") || !mainMenuPromoJson["smallButton1"]["Url"].IsString() || + !mainMenuPromoJson["smallButton1"].HasMember("ImageIndex") || + !mainMenuPromoJson["smallButton1"]["ImageIndex"].IsNumber() || + + !mainMenuPromoJson.HasMember("smallButton2") || !mainMenuPromoJson["smallButton2"].IsObject() || + !mainMenuPromoJson["smallButton2"].HasMember("Title") || !mainMenuPromoJson["smallButton2"]["Title"].IsString() || + !mainMenuPromoJson["smallButton2"].HasMember("Url") || !mainMenuPromoJson["smallButton2"]["Url"].IsString() || + !mainMenuPromoJson["smallButton2"].HasMember("ImageIndex") || + !mainMenuPromoJson["smallButton2"]["ImageIndex"].IsNumber()) + { + spdlog::error("Failed reading masterserver main menu promos response: malformed json object"); + goto REQUEST_END_CLEANUP; + } + + m_sMainMenuPromoData.newInfoTitle1 = mainMenuPromoJson["newInfo"]["Title1"].GetString(); + m_sMainMenuPromoData.newInfoTitle2 = mainMenuPromoJson["newInfo"]["Title2"].GetString(); + m_sMainMenuPromoData.newInfoTitle3 = mainMenuPromoJson["newInfo"]["Title3"].GetString(); + + m_sMainMenuPromoData.largeButtonTitle = mainMenuPromoJson["largeButton"]["Title"].GetString(); + m_sMainMenuPromoData.largeButtonText = mainMenuPromoJson["largeButton"]["Text"].GetString(); + m_sMainMenuPromoData.largeButtonUrl = mainMenuPromoJson["largeButton"]["Url"].GetString(); + m_sMainMenuPromoData.largeButtonImageIndex = mainMenuPromoJson["largeButton"]["ImageIndex"].GetInt(); + + m_sMainMenuPromoData.smallButton1Title = mainMenuPromoJson["smallButton1"]["Title"].GetString(); + m_sMainMenuPromoData.smallButton1Url = mainMenuPromoJson["smallButton1"]["Url"].GetString(); + m_sMainMenuPromoData.smallButton1ImageIndex = mainMenuPromoJson["smallButton1"]["ImageIndex"].GetInt(); + + m_sMainMenuPromoData.smallButton2Title = mainMenuPromoJson["smallButton2"]["Title"].GetString(); + m_sMainMenuPromoData.smallButton2Url = mainMenuPromoJson["smallButton2"]["Url"].GetString(); + m_sMainMenuPromoData.smallButton2ImageIndex = mainMenuPromoJson["smallButton2"]["ImageIndex"].GetInt(); + + m_bHasMainMenuPromoData = true; + } + else + { + spdlog::error("Failed requesting main menu promos: error {}", curl_easy_strerror(result)); + m_bSuccessfullyConnected = false; + } + + REQUEST_END_CLEANUP: + // nothing lol + curl_easy_cleanup(curl); + }); + + requestThread.detach(); +} + +void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char* playerToken) +{ + // dont wait, just stop if we're trying to do 2 auth requests at once + if (m_bAuthenticatingWithGameServer) + return; + + m_bAuthenticatingWithGameServer = true; + m_bScriptAuthenticatingWithGameServer = true; + m_bSuccessfullyAuthenticatedWithGameServer = false; + + std::string uidStr(uid); + std::string tokenStr(playerToken); + + std::thread requestThread( + [this, uidStr, tokenStr]() + { + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format("{}/client/auth_with_self?id={}&playerToken={}", Cvar_ns_masterserver_hostname->GetString(), uidStr, tokenStr) + .c_str()); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + m_bSuccessfullyConnected = true; + + rapidjson_document authInfoJson; + authInfoJson.Parse(readBuffer.c_str()); + + if (authInfoJson.HasParseError()) + { + spdlog::error( + "Failed reading masterserver authentication response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(authInfoJson.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (!authInfoJson.IsObject()) + { + spdlog::error("Failed reading masterserver authentication response: root object is not an object"); + goto REQUEST_END_CLEANUP; + } + + if (authInfoJson.HasMember("error")) + { + spdlog::error("Failed reading masterserver response: got fastify error response"); + spdlog::error(readBuffer); + + if (authInfoJson["error"].HasMember("enum")) + m_sAuthFailureReason = authInfoJson["error"]["enum"].GetString(); + else + m_sAuthFailureReason = "No error message provided"; + + goto REQUEST_END_CLEANUP; + } + + if (!authInfoJson["success"].IsTrue()) + { + spdlog::error("Authentication with masterserver failed: \"success\" is not true"); + goto REQUEST_END_CLEANUP; + } + + if (!authInfoJson.HasMember("success") || !authInfoJson.HasMember("id") || !authInfoJson["id"].IsString() || + !authInfoJson.HasMember("authToken") || !authInfoJson["authToken"].IsString() || + !authInfoJson.HasMember("persistentData") || !authInfoJson["persistentData"].IsArray()) + { + spdlog::error("Failed reading masterserver authentication response: malformed json object"); + goto REQUEST_END_CLEANUP; + } + + RemoteAuthData newAuthData {}; + strncpy_s(newAuthData.uid, sizeof(newAuthData.uid), authInfoJson["id"].GetString(), sizeof(newAuthData.uid) - 1); + + newAuthData.pdataSize = authInfoJson["persistentData"].GetArray().Size(); + newAuthData.pdata = new char[newAuthData.pdataSize]; + // memcpy(newAuthData.pdata, authInfoJson["persistentData"].GetString(), newAuthData.pdataSize); + + int i = 0; + // note: persistentData is a uint8array because i had problems getting strings to behave, it sucks but it's just how it be + // unfortunately potentially refactor later + for (auto& byte : authInfoJson["persistentData"].GetArray()) + { + if (!byte.IsUint() || byte.GetUint() > 255) + { + spdlog::error("Failed reading masterserver authentication response: malformed json object"); + goto REQUEST_END_CLEANUP; + } + + newAuthData.pdata[i++] = static_cast<char>(byte.GetUint()); + } + + std::lock_guard<std::mutex> guard(g_pServerAuthentication->m_AuthDataMutex); + g_pServerAuthentication->m_RemoteAuthenticationData.clear(); + g_pServerAuthentication->m_RemoteAuthenticationData.insert( + std::make_pair(authInfoJson["authToken"].GetString(), newAuthData)); + + m_bSuccessfullyAuthenticatedWithGameServer = true; + } + else + { + spdlog::error("Failed authenticating with own server: error {}", curl_easy_strerror(result)); + m_bSuccessfullyConnected = false; + m_bSuccessfullyAuthenticatedWithGameServer = false; + m_bScriptAuthenticatingWithGameServer = false; + } + + REQUEST_END_CLEANUP: + m_bAuthenticatingWithGameServer = false; + m_bScriptAuthenticatingWithGameServer = false; + + if (m_bNewgameAfterSelfAuth) + { + // pretty sure this is threadsafe? + R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "ns_end_reauth_and_leave_to_lobby", R2::cmd_source_t::kCommandSrcCode); + m_bNewgameAfterSelfAuth = false; + } + + curl_easy_cleanup(curl); + }); + + requestThread.detach(); +} + +void MasterServerManager::AuthenticateWithServer(const char* uid, const char* playerToken, const char* serverId, const char* password) +{ + // dont wait, just stop if we're trying to do 2 auth requests at once + if (m_bAuthenticatingWithGameServer) + return; + + m_bAuthenticatingWithGameServer = true; + m_bScriptAuthenticatingWithGameServer = true; + m_bSuccessfullyAuthenticatedWithGameServer = false; + + std::string uidStr(uid); + std::string tokenStr(playerToken); + std::string serverIdStr(serverId); + std::string passwordStr(password); + + std::thread requestThread( + [this, uidStr, tokenStr, serverIdStr, passwordStr]() + { + // esnure that any persistence saving is done, so we know masterserver has newest + while (m_bSavingPersistentData) + Sleep(100); + + spdlog::info("Attempting authentication with server of id \"{}\"", serverIdStr); + + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + { + char* escapedPassword = curl_easy_escape(curl, passwordStr.c_str(), passwordStr.length()); + + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format( + "{}/client/auth_with_server?id={}&playerToken={}&server={}&password={}", + Cvar_ns_masterserver_hostname->GetString(), + uidStr, + tokenStr, + serverIdStr, + escapedPassword) + .c_str()); + + curl_free(escapedPassword); + } + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + m_bSuccessfullyConnected = true; + + rapidjson_document connectionInfoJson; + connectionInfoJson.Parse(readBuffer.c_str()); + + if (connectionInfoJson.HasParseError()) + { + spdlog::error( + "Failed reading masterserver authentication response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(connectionInfoJson.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (!connectionInfoJson.IsObject()) + { + spdlog::error("Failed reading masterserver authentication response: root object is not an object"); + goto REQUEST_END_CLEANUP; + } + + if (connectionInfoJson.HasMember("error")) + { + spdlog::error("Failed reading masterserver response: got fastify error response"); + spdlog::error(readBuffer); + + if (connectionInfoJson["error"].HasMember("enum")) + m_sAuthFailureReason = connectionInfoJson["error"]["enum"].GetString(); + else + m_sAuthFailureReason = "No error message provided"; + + goto REQUEST_END_CLEANUP; + } + + if (!connectionInfoJson["success"].IsTrue()) + { + spdlog::error("Authentication with masterserver failed: \"success\" is not true"); + goto REQUEST_END_CLEANUP; + } + + if (!connectionInfoJson.HasMember("success") || !connectionInfoJson.HasMember("ip") || + !connectionInfoJson["ip"].IsString() || !connectionInfoJson.HasMember("port") || + !connectionInfoJson["port"].IsNumber() || !connectionInfoJson.HasMember("authToken") || + !connectionInfoJson["authToken"].IsString()) + { + spdlog::error("Failed reading masterserver authentication response: malformed json object"); + goto REQUEST_END_CLEANUP; + } + + m_pendingConnectionInfo.ip.S_un.S_addr = inet_addr(connectionInfoJson["ip"].GetString()); + m_pendingConnectionInfo.port = (unsigned short)connectionInfoJson["port"].GetUint(); + + strncpy_s( + m_pendingConnectionInfo.authToken, + sizeof(m_pendingConnectionInfo.authToken), + connectionInfoJson["authToken"].GetString(), + sizeof(m_pendingConnectionInfo.authToken) - 1); + + m_bHasPendingConnectionInfo = true; + m_bSuccessfullyAuthenticatedWithGameServer = true; + } + else + { + spdlog::error("Failed authenticating with server: error {}", curl_easy_strerror(result)); + m_bSuccessfullyConnected = false; + m_bSuccessfullyAuthenticatedWithGameServer = false; + m_bScriptAuthenticatingWithGameServer = false; + } + + REQUEST_END_CLEANUP: + m_bAuthenticatingWithGameServer = false; + m_bScriptAuthenticatingWithGameServer = false; + curl_easy_cleanup(curl); + }); + + requestThread.detach(); +} + +void MasterServerManager::WritePlayerPersistentData(const char* playerId, const char* pdata, size_t pdataSize) +{ + // still call this if we don't have a server id, since lobbies that aren't port forwarded need to be able to call it + m_bSavingPersistentData = true; + if (!pdataSize) + { + spdlog::warn("attempted to write pdata of size 0!"); + return; + } + + std::string strPlayerId(playerId); + std::string strPdata(pdata, pdataSize); + + std::thread requestThread( + [this, strPlayerId, strPdata, pdataSize] + { + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format( + "{}/accounts/write_persistence?id={}&serverId={}", + Cvar_ns_masterserver_hostname->GetString(), + strPlayerId, + m_sOwnServerId) + .c_str()); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + curl_mime* mime = curl_mime_init(curl); + curl_mimepart* part = curl_mime_addpart(mime); + + curl_mime_data(part, strPdata.c_str(), pdataSize); + curl_mime_name(part, "pdata"); + curl_mime_filename(part, "file.pdata"); + curl_mime_type(part, "application/octet-stream"); + + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + m_bSuccessfullyConnected = true; + else + m_bSuccessfullyConnected = false; + + curl_easy_cleanup(curl); + + m_bSavingPersistentData = false; + }); + + requestThread.detach(); +} + +class MasterServerPresenceReporter : public ServerPresenceReporter +{ + const int MAX_REGISTRATION_ATTEMPTS = 5; + + bool m_bShouldTryRegisterServer; + bool m_bHasAddServerRequest; + int m_nNumRegistrationAttempts; + + void CreatePresence(const ServerPresence* pServerPresence) override + { + m_bShouldTryRegisterServer = true; + m_bHasAddServerRequest = false; + m_nNumRegistrationAttempts = 0; + } + + void ReportPresence(const ServerPresence* pServerPresence) override + { + // make a copy of presence for multithreading purposes + ServerPresence threadedPresence(pServerPresence); + + if (!*g_pMasterServerManager->m_sOwnServerId) + { + if (m_bShouldTryRegisterServer && !m_bHasAddServerRequest) + { + // add server + std::thread addServerThread( + [this, threadedPresence] + { + g_pMasterServerManager->m_sOwnServerId[0] = 0; + g_pMasterServerManager->m_sOwnServerAuthToken[0] = 0; + + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + curl_mime* mime = curl_mime_init(curl); + curl_mimepart* part = curl_mime_addpart(mime); + + curl_mime_data( + part, g_pMasterServerManager->m_sOwnModInfoJson.c_str(), g_pMasterServerManager->m_sOwnModInfoJson.size()); + curl_mime_name(part, "modinfo"); + curl_mime_filename(part, "modinfo.json"); + curl_mime_type(part, "application/json"); + + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + // format every paramter because computers hate me + { + char* nameEscaped = curl_easy_escape(curl, threadedPresence.m_sServerName.c_str(), NULL); + char* descEscaped = curl_easy_escape(curl, threadedPresence.m_sServerDesc.c_str(), NULL); + char* mapEscaped = curl_easy_escape(curl, threadedPresence.m_MapName, NULL); + char* playlistEscaped = curl_easy_escape(curl, threadedPresence.m_PlaylistName, NULL); + char* passwordEscaped = curl_easy_escape(curl, threadedPresence.m_Password, NULL); + + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format( + "{}/server/" + "add_server?port={}&authPort={}&name={}&description={}&map={}&playlist={}&maxPlayers={}&password={}", + Cvar_ns_masterserver_hostname->GetString(), + threadedPresence.m_iPort, + threadedPresence.m_iAuthPort, + nameEscaped, + descEscaped, + mapEscaped, + playlistEscaped, + threadedPresence.m_iMaxPlayers, + passwordEscaped) + .c_str()); + + curl_free(nameEscaped); + curl_free(descEscaped); + curl_free(mapEscaped); + curl_free(playlistEscaped); + curl_free(passwordEscaped); + } + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + g_pMasterServerManager->m_bSuccessfullyConnected = true; + + rapidjson_document serverAddedJson; + serverAddedJson.Parse(readBuffer.c_str()); + + if (serverAddedJson.HasParseError()) + { + spdlog::error( + "Failed reading masterserver authentication response: encountered parse error \"{}\"", + rapidjson::GetParseError_En(serverAddedJson.GetParseError())); + goto REQUEST_END_CLEANUP; + } + + if (!serverAddedJson.IsObject()) + { + spdlog::error("Failed reading masterserver authentication response: root object is not an object"); + goto REQUEST_END_CLEANUP; + } + + if (serverAddedJson.HasMember("error")) + { + spdlog::error("Failed reading masterserver response: got fastify error response"); + spdlog::error(readBuffer); + + if (serverAddedJson["error"].HasMember("enum") && + !strcmp(serverAddedJson["error"]["enum"].GetString(), "DUPLICATE_SERVER")) + { + if (++m_nNumRegistrationAttempts == MAX_REGISTRATION_ATTEMPTS) + m_bShouldTryRegisterServer = false; + + goto REQUEST_END_CLEANUP_RETRY; + } + + goto REQUEST_END_CLEANUP; + } + + if (!serverAddedJson["success"].IsTrue()) + { + spdlog::error("Adding server to masterserver failed: \"success\" is not true"); + goto REQUEST_END_CLEANUP; + } + + if (!serverAddedJson.HasMember("id") || !serverAddedJson["id"].IsString() || + !serverAddedJson.HasMember("serverAuthToken") || !serverAddedJson["serverAuthToken"].IsString()) + { + spdlog::error("Failed reading masterserver response: malformed json object"); + goto REQUEST_END_CLEANUP; + } + + strncpy_s( + g_pMasterServerManager->m_sOwnServerId, + sizeof(g_pMasterServerManager->m_sOwnServerId), + serverAddedJson["id"].GetString(), + sizeof(g_pMasterServerManager->m_sOwnServerId) - 1); + + strncpy_s( + g_pMasterServerManager->m_sOwnServerAuthToken, + sizeof(g_pMasterServerManager->m_sOwnServerAuthToken), + serverAddedJson["serverAuthToken"].GetString(), + sizeof(g_pMasterServerManager->m_sOwnServerAuthToken) - 1); + } + else + { + spdlog::error("Failed adding self to server list: error {}", curl_easy_strerror(result)); + g_pMasterServerManager->m_bSuccessfullyConnected = false; + } + + REQUEST_END_CLEANUP: + m_bShouldTryRegisterServer = false; + + REQUEST_END_CLEANUP_RETRY: + m_bHasAddServerRequest = false; + + curl_easy_cleanup(curl); + curl_mime_free(mime); + }); + + m_bHasAddServerRequest = true; + addServerThread.detach(); + } + } + else + { + // update server + std::thread updateServerThread( + [threadedPresence] + { + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); + + // send all registration info so we have all necessary info to reregister our server if masterserver goes down, + // without a restart this isn't threadsafe :terror: + { + char* nameEscaped = curl_easy_escape(curl, threadedPresence.m_sServerName.c_str(), NULL); + char* descEscaped = curl_easy_escape(curl, threadedPresence.m_sServerDesc.c_str(), NULL); + char* mapEscaped = curl_easy_escape(curl, threadedPresence.m_MapName, NULL); + char* playlistEscaped = curl_easy_escape(curl, threadedPresence.m_PlaylistName, NULL); + char* passwordEscaped = curl_easy_escape(curl, threadedPresence.m_Password, NULL); + + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format( + "{}/server/" + "update_values?id={}&port={}&authPort={}&name={}&description={}&map={}&playlist={}&playerCount={}&" + "maxPlayers={}&password={}", + Cvar_ns_masterserver_hostname->GetString(), + g_pMasterServerManager->m_sOwnServerId, + threadedPresence.m_iPort, + threadedPresence.m_iAuthPort, + nameEscaped, + descEscaped, + mapEscaped, + playlistEscaped, + threadedPresence.m_iPlayerCount, + threadedPresence.m_iMaxPlayers, + passwordEscaped) + .c_str()); + + curl_free(nameEscaped); + curl_free(descEscaped); + curl_free(mapEscaped); + curl_free(playlistEscaped); + curl_free(passwordEscaped); + } + + curl_mime* mime = curl_mime_init(curl); + curl_mimepart* part = curl_mime_addpart(mime); + + curl_mime_data( + part, g_pMasterServerManager->m_sOwnModInfoJson.c_str(), g_pMasterServerManager->m_sOwnModInfoJson.size()); + curl_mime_name(part, "modinfo"); + curl_mime_filename(part, "modinfo.json"); + curl_mime_type(part, "application/json"); + + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + { + rapidjson_document serverAddedJson; + serverAddedJson.Parse(readBuffer.c_str()); + + if (!serverAddedJson.HasParseError() && serverAddedJson.IsObject()) + { + if (serverAddedJson.HasMember("id") && serverAddedJson["id"].IsString()) + { + strncpy_s( + g_pMasterServerManager->m_sOwnServerId, + sizeof(g_pMasterServerManager->m_sOwnServerId), + serverAddedJson["id"].GetString(), + sizeof(g_pMasterServerManager->m_sOwnServerId) - 1); + } + + if (serverAddedJson.HasMember("serverAuthToken") && serverAddedJson["serverAuthToken"].IsString()) + { + + strncpy_s( + g_pMasterServerManager->m_sOwnServerAuthToken, + sizeof(g_pMasterServerManager->m_sOwnServerAuthToken), + serverAddedJson["serverAuthToken"].GetString(), + sizeof(g_pMasterServerManager->m_sOwnServerAuthToken) - 1); + } + } + } + else + spdlog::warn("Heartbeat failed with error {}", curl_easy_strerror(result)); + + curl_easy_cleanup(curl); + }); + updateServerThread.detach(); + } + } + + void DestroyPresence(const ServerPresence* pServerPresence) override + { + // dont call this if we don't have a server id + if (!*g_pMasterServerManager->m_sOwnServerId) + return; + + std::thread requestThread( + [this] + { + CURL* curl = curl_easy_init(); + SetCommonHttpClientOptions(curl); + + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + curl_easy_setopt( + curl, + CURLOPT_URL, + fmt::format( + "{}/server/remove_server?id={}", Cvar_ns_masterserver_hostname->GetString(), g_pMasterServerManager->m_sOwnServerId) + .c_str()); + + *g_pMasterServerManager->m_sOwnServerId = 0; + CURLcode result = curl_easy_perform(curl); + + if (result == CURLcode::CURLE_OK) + g_pMasterServerManager->m_bSuccessfullyConnected = true; + else + g_pMasterServerManager->m_bSuccessfullyConnected = false; + + curl_easy_cleanup(curl); + }); + + requestThread.detach(); + } +}; + +void ConCommand_ns_fetchservers(const CCommand& args) +{ + g_pMasterServerManager->RequestServerList(); +} + +MasterServerManager::MasterServerManager() : m_pendingConnectionInfo {}, m_sOwnServerId {""}, m_sOwnClientAuthToken {""} {} + +ON_DLL_LOAD_RELIESON("engine.dll", MasterServer, (ConCommand, ServerPresence), (CModule module)) +{ + g_pMasterServerManager = new MasterServerManager; + + Cvar_ns_masterserver_hostname = new ConVar("ns_masterserver_hostname", "127.0.0.1", FCVAR_NONE, ""); + Cvar_ns_curl_log_enable = new ConVar("ns_curl_log_enable", "0", FCVAR_NONE, "Whether curl should log to the console"); + + RegisterConCommand("ns_fetchservers", ConCommand_ns_fetchservers, "Fetch all servers from the masterserver", FCVAR_CLIENTDLL); + + MasterServerPresenceReporter* presenceReporter = new MasterServerPresenceReporter; + g_pServerPresence->AddPresenceReporter(presenceReporter); +} diff --git a/NorthstarDLL/masterserver.h b/NorthstarDLL/masterserver.h new file mode 100644 index 00000000..5a4e2a91 --- /dev/null +++ b/NorthstarDLL/masterserver.h @@ -0,0 +1,126 @@ +#pragma once +#include "convar.h" +#include "serverpresence.h" +#include <winsock2.h> +#include <string> +#include <cstring> + +extern ConVar* Cvar_ns_masterserver_hostname; +extern ConVar* Cvar_ns_curl_log_enable; + +struct RemoteModInfo +{ + public: + std::string Name; + std::string Version; +}; + +class RemoteServerInfo +{ + public: + char id[33]; // 32 bytes + nullterminator + + // server info + char name[64]; + std::string description; + char map[32]; + char playlist[16]; + std::vector<RemoteModInfo> requiredMods; + + int playerCount; + int maxPlayers; + + // connection stuff + bool requiresPassword; + + public: + RemoteServerInfo( + const char* newId, + const char* newName, + const char* newDescription, + const char* newMap, + const char* newPlaylist, + int newPlayerCount, + int newMaxPlayers, + bool newRequiresPassword); +}; + +struct RemoteServerConnectionInfo +{ + public: + char authToken[32]; + + in_addr ip; + unsigned short port; +}; + +struct MainMenuPromoData +{ + public: + std::string newInfoTitle1; + std::string newInfoTitle2; + std::string newInfoTitle3; + + std::string largeButtonTitle; + std::string largeButtonText; + std::string largeButtonUrl; + int largeButtonImageIndex; + + std::string smallButton1Title; + std::string smallButton1Url; + int smallButton1ImageIndex; + + std::string smallButton2Title; + std::string smallButton2Url; + int smallButton2ImageIndex; +}; + +class MasterServerManager +{ + private: + bool m_bRequestingServerList = false; + bool m_bAuthenticatingWithGameServer = false; + + public: + char m_sOwnServerId[33]; + char m_sOwnServerAuthToken[33]; + char m_sOwnClientAuthToken[33]; + + std::string m_sOwnModInfoJson; + + bool m_bOriginAuthWithMasterServerDone = false; + bool m_bOriginAuthWithMasterServerInProgress = false; + + bool m_bRequireClientAuth = false; + bool m_bSavingPersistentData = false; + + bool m_bScriptRequestingServerList = false; + bool m_bSuccessfullyConnected = true; + + bool m_bNewgameAfterSelfAuth = false; + bool m_bScriptAuthenticatingWithGameServer = false; + bool m_bSuccessfullyAuthenticatedWithGameServer = false; + std::string m_sAuthFailureReason {}; + + bool m_bHasPendingConnectionInfo = false; + RemoteServerConnectionInfo m_pendingConnectionInfo; + + std::vector<RemoteServerInfo> m_vRemoteServers; + + bool m_bHasMainMenuPromoData = false; + MainMenuPromoData m_sMainMenuPromoData; + + public: + MasterServerManager(); + + void ClearServerList(); + void RequestServerList(); + void RequestMainMenuPromos(); + void AuthenticateOriginWithMasterServer(const char* uid, const char* originToken); + void AuthenticateWithOwnServer(const char* uid, const char* playerToken); + void AuthenticateWithServer(const char* uid, const char* playerToken, const char* serverId, const char* password); + void WritePlayerPersistentData(const char* playerId, const char* pdata, size_t pdataSize); +}; + +extern MasterServerManager* g_pMasterServerManager; +extern ConVar* Cvar_ns_masterserver_hostname; diff --git a/NorthstarDLL/maxplayers.cpp b/NorthstarDLL/maxplayers.cpp new file mode 100644 index 00000000..ece8d14b --- /dev/null +++ b/NorthstarDLL/maxplayers.cpp @@ -0,0 +1,645 @@ +#include "pch.h" +#include "tier0.h" +#include "maxplayers.h" + +AUTOHOOK_INIT() + +// never set this to anything below 32 +#define NEW_MAX_PLAYERS 64 +// dg note: the theoretical limit is actually 100, 76 works without entity issues, and 64 works without clientside prediction issues. + +#define PAD_NUMBER(number, boundary) (((number) + ((boundary)-1)) / (boundary)) * (boundary) + +// this is horrible +constexpr int PlayerResource_Name_Start = 0; // Start of modded allocated space. +constexpr int PlayerResource_Name_Size = ((NEW_MAX_PLAYERS + 1) * 8); // const char* m_szName[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_Ping_Start = PlayerResource_Name_Start + PlayerResource_Name_Size; +constexpr int PlayerResource_Ping_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPing[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_Team_Start = PlayerResource_Ping_Start + PlayerResource_Ping_Size; +constexpr int PlayerResource_Team_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iTeam[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_PRHealth_Start = PlayerResource_Team_Start + PlayerResource_Team_Size; +constexpr int PlayerResource_PRHealth_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPRHealth[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_Connected_Start = PlayerResource_PRHealth_Start + PlayerResource_PRHealth_Size; +constexpr int PlayerResource_Connected_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bConnected[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_Alive_Start = PlayerResource_Connected_Start + PlayerResource_Connected_Size; +constexpr int PlayerResource_Alive_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bAlive[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_BoolStats_Start = PlayerResource_Alive_Start + PlayerResource_Alive_Size; +constexpr int PlayerResource_BoolStats_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool idk) m_boolStats[MAX_PLAYERS + 1]; + +constexpr int PlayerResource_KillStats_Start = PlayerResource_BoolStats_Start + PlayerResource_BoolStats_Size; +constexpr int PlayerResource_KillStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 6, 4); +constexpr int PlayerResource_KillStats_Size = (PlayerResource_KillStats_Length * 6); // int m_killStats[MAX_PLAYERS + 1][6]; + +constexpr int PlayerResource_ScoreStats_Start = PlayerResource_KillStats_Start + PlayerResource_KillStats_Size; +constexpr int PlayerResource_ScoreStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 5, 4); +constexpr int PlayerResource_ScoreStats_Size = (PlayerResource_ScoreStats_Length * 4); // int m_scoreStats[MAX_PLAYERS + 1][5]; + +// must be the usage of the last field to account for any possible paddings +constexpr int PlayerResource_TotalSize = PlayerResource_ScoreStats_Start + PlayerResource_ScoreStats_Size; + +constexpr int Team_PlayerArray_AddedLength = NEW_MAX_PLAYERS - 32; +constexpr int Team_PlayerArray_AddedSize = PAD_NUMBER(Team_PlayerArray_AddedLength * 8, 4); +constexpr int Team_AddedSize = Team_PlayerArray_AddedSize; + +bool MaxPlayersIncreaseEnabled() +{ + static bool bMaxPlayersIncreaseEnabled = Tier0::CommandLine()->CheckParm("-experimentalmaxplayersincrease"); + return bMaxPlayersIncreaseEnabled; +} + +// should we use R2 for this? not sure +namespace R2 // use R2 namespace for game funcs +{ + int GetMaxPlayers() + { + if (MaxPlayersIncreaseEnabled()) + return NEW_MAX_PLAYERS; + + return 32; + } +} // namespace R2 + +template <class T> void ChangeOffset(MemoryAddress addr, unsigned int offset) +{ + addr.Patch((BYTE*)&offset, sizeof(T)); +} + +// clang-format off +AUTOHOOK(StringTables_CreateStringTable, engine.dll + 0x22E220, +void*,, (void* thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags)) +// clang-format on +{ + // Change the amount of entries to account for a bigger player amount + if (!strcmp(name, "userinfo")) + { + int maxPlayersPowerOf2 = 1; + while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS) + maxPlayersPowerOf2 <<= 1; + + maxentries = maxPlayersPowerOf2; + } + + return StringTables_CreateStringTable(thisptr, name, maxentries, userdatafixedsize, userdatanetworkbits, flags); +} + +ON_DLL_LOAD("engine.dll", MaxPlayersOverride_Engine, (CModule module)) +{ + if (!MaxPlayersIncreaseEnabled()) + return; + + AUTOHOOK_DISPATCH_MODULE(engine.dll) + + // patch GetPlayerLimits to ignore the boundary limit + module.Offset(0x116458).Patch("0xEB"); // jle => jmp + + // patch ED_Alloc to change nFirstIndex + ChangeOffset<int>(module.Offset(0x18F46C + 1), NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1) + + // patch CGameServer::SpawnServer to change GetMaxClients inline + ChangeOffset<int>(module.Offset(0x119543 + 2), NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1) + + // patch CGameServer::SpawnServer to change for loop + ChangeOffset<unsigned char>(module.Offset(0x11957F + 2), NEW_MAX_PLAYERS); // original: 32 + + // patch CGameServer::SpawnServer to change for loop (there are two) + ChangeOffset<unsigned char>(module.Offset(0x119586 + 2), NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1) + + // patch max players somewhere in CClientState + ChangeOffset<unsigned char>(module.Offset(0x1A162C + 2), NEW_MAX_PLAYERS - 1); // original: 31 (32 - 1) + + // patch max players in userinfo stringtable creation + /*{ + int maxPlayersPowerOf2 = 1; + while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS) + maxPlayersPowerOf2 <<= 1; + ChangeOffset<unsigned char>((char*)baseAddress + 0x114B79 + 3, maxPlayersPowerOf2); // original: 32 + }*/ + // this is not supposed to work at all but it does on 64 players (how) + // proper fix below + + // patch max players in userinfo stringtable creation loop + ChangeOffset<unsigned char>(module.Offset(0x114C48 + 2), NEW_MAX_PLAYERS); // original: 32 + + // do not load prebaked SendTable message list + module.Offset(0x75859).Patch("EB"); // jnz -> jmp +} + +typedef void (*RunUserCmds_Type)(bool a1, float a2); +RunUserCmds_Type RunUserCmds_Original; + +HMODULE serverBase = 0; +auto RandomIntZeroMax = (__int64(__fastcall*)())0; + +// lazy rebuild +// clang-format off +AUTOHOOK(RunUserCmds, server.dll + 0x483D10, +void,, (bool a1, float a2)) +// clang-format on +{ + unsigned char v3; // bl + int v5; // er14 + int i; // edi + __int64 v7; // rax + DWORD* v8; // rbx + int v9; // edi + __int64* v10; // rsi + __int64 v11; // rax + int v12; // er12 + __int64 v13; // rdi + int v14; // ebx + int v15; // eax + __int64 v16; // r8 + int v17; // edx + char v18; // r15 + char v19; // bp + int v20; // esi + __int64* v21; // rdi + __int64 v22; // rcx + bool v23; // al + __int64 v24; // rax + __int64 v25[NEW_MAX_PLAYERS]; // [rsp+20h] [rbp-138h] BYREF + + uintptr_t base = (__int64)serverBase; + auto g_pGlobals = *(__int64*)(base + 0xBFBE08); + __int64 globals = g_pGlobals; + + auto g_pEngineServer = *(__int64*)(base + 0xBFBD98); + + auto qword_1814D9648 = *(__int64*)(base + 0x14D9648); + auto qword_1814DA408 = *(__int64*)(base + 0x14DA408); + auto qword_1812107E8 = *(__int64*)(base + 0x12107E8); + auto qword_1812105A8 = *(__int64*)(base + 0x12105A8); + + auto UTIL_PlayerByIndex = (__int64(__fastcall*)(int index))(base + 0x26AA10); + auto sub_180485590 = (void(__fastcall*)(__int64))(base + 0x485590); + auto sub_18058CD80 = (void(__fastcall*)(__int64))(base + 0x58CD80); + auto sub_1805A6D90 = (void(__fastcall*)(__int64))(base + 0x5A6D90); + auto sub_1805A6E50 = (bool(__fastcall*)(__int64, int, char))(base + 0x5A6E50); + auto sub_1805A6C20 = (void(__fastcall*)(__int64))(base + 0x5A6C20); + + v3 = *(unsigned char*)(g_pGlobals + 73); + if (*(DWORD*)(qword_1814D9648 + 92) && + ((*(unsigned __int8(__fastcall**)(__int64))(*(__int64*)g_pEngineServer + 32))(g_pEngineServer) || + !*(DWORD*)(qword_1814DA408 + 92)) && + v3) + { + globals = g_pGlobals; + v5 = 1; + for (i = 1; i <= *(DWORD*)(g_pGlobals + 52); ++i) + { + v7 = UTIL_PlayerByIndex(i); + v8 = (DWORD*)v7; + if (v7) + { + *(__int64*)(base + 0x1210420) = v7; + *(float*)(g_pGlobals + 16) = a2; + if (!a1) + sub_18058CD80(v7); + sub_1805A6D90((__int64)v8); + } + globals = g_pGlobals; + } + memset(v25, 0, sizeof(v25)); + v9 = 0; + if (*(int*)(globals + 52) > 0) + { + v10 = v25; + do + { + v11 = UTIL_PlayerByIndex(++v9); + globals = g_pGlobals; + *v10++ = v11; + } while (v9 < *(DWORD*)(globals + 52)); + } + v12 = *(DWORD*)(qword_1812107E8 + 92); + if (*(DWORD*)(qword_1812105A8 + 92)) + { + v13 = *(DWORD*)(globals + 52) - 1; + if (v13 >= 1) + { + v14 = *(DWORD*)(globals + 52); + do + { + v15 = RandomIntZeroMax(); + v16 = v25[v13--]; + v17 = v15 % v14--; + v25[v13 + 1] = v25[v17]; + v25[v17] = v16; + } while (v13 >= 1); + globals = g_pGlobals; + } + } + v18 = 1; + do + { + v19 = 0; + v20 = 0; + if (*(int*)(globals + 52) > 0) + { + v21 = v25; + do + { + v22 = *v21; + if (*v21) + { + *(__int64*)(base + 0x1210420) = *v21; + *(float*)(globals + 16) = a2; + v23 = sub_1805A6E50(v22, v12, v18); + globals = g_pGlobals; + if (v23) + v19 = 1; + else + *v21 = 0; + } + ++v20; + ++v21; + } while (v20 < *(DWORD*)(globals + 52)); + } + v18 = 0; + } while (v19); + if (*(int*)(globals + 52) >= 1) + { + do + { + v24 = UTIL_PlayerByIndex(v5); + if (v24) + { + *(__int64*)(base + 0x1210420) = v24; + *(float*)(g_pGlobals + 16) = a2; + sub_1805A6C20(v24); + } + ++v5; + } while (v5 <= *(DWORD*)(g_pGlobals + 52)); + } + sub_180485590(*(__int64*)(base + 0xB7B2D8)); + } +} + +// clang-format off +AUTOHOOK(SendPropArray2, server.dll + 0x12B130, +__int64, __fastcall, (__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1)) +// clang-format on +{ + // Change the amount of elements to account for a bigger player amount + if (!strcmp(name, "\"player_array\"")) + elements = NEW_MAX_PLAYERS; + + return SendPropArray2(recvProp, elements, flags, name, proxyFn, unk1); +} + +ON_DLL_LOAD("server.dll", MaxPlayersOverride_Server, (CModule module)) +{ + if (!MaxPlayersIncreaseEnabled()) + return; + + AUTOHOOK_DISPATCH_MODULE(server.dll) + + // get required data + serverBase = (HMODULE)module.m_nAddress; + RandomIntZeroMax = (decltype(RandomIntZeroMax))(GetProcAddress(GetModuleHandleA("vstdlib.dll"), "RandomIntZeroMax")); + + // patch max players amount + ChangeOffset<unsigned char>(module.Offset(0x9A44D + 3), NEW_MAX_PLAYERS); // 0x20 (32) => 0x80 (128) + + // patch SpawnGlobalNonRewinding to change forced edict index + ChangeOffset<unsigned char>(module.Offset(0x2BC403 + 2), NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1) + + constexpr int CPlayerResource_OriginalSize = 4776; + constexpr int CPlayerResource_AddedSize = PlayerResource_TotalSize; + constexpr int CPlayerResource_ModifiedSize = CPlayerResource_OriginalSize + CPlayerResource_AddedSize; + + // CPlayerResource class allocation function - allocate a bigger amount to fit all new max player data + ChangeOffset<unsigned int>(module.Offset(0x5C560A + 1), CPlayerResource_ModifiedSize); + + // DT_PlayerResource::m_iPing SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C5059 + 2), CPlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C50A8 + 2), CPlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C50E2 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_iPing DataMap + ChangeOffset<unsigned int>(module.Offset(0xB94598), CPlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned short>(module.Offset(0xB9459C), NEW_MAX_PLAYERS + 1); + ChangeOffset<unsigned short>(module.Offset(0xB945C0), PlayerResource_Ping_Size); + + // DT_PlayerResource::m_iTeam SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C5110 + 2), CPlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C519C + 2), CPlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C517E + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_iTeam DataMap + ChangeOffset<unsigned int>(module.Offset(0xB94600), CPlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned short>(module.Offset(0xB94604), NEW_MAX_PLAYERS + 1); + ChangeOffset<unsigned short>(module.Offset(0xB94628), PlayerResource_Team_Size); + + // DT_PlayerResource::m_iPRHealth SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C51C0 + 2), CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C5204 + 2), CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C523E + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_iPRHealth DataMap + ChangeOffset<unsigned int>(module.Offset(0xB94668), CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned short>(module.Offset(0xB9466C), NEW_MAX_PLAYERS + 1); + ChangeOffset<unsigned short>(module.Offset(0xB94690), PlayerResource_PRHealth_Size); + + // DT_PlayerResource::m_bConnected SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C526C + 2), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C52B4 + 2), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C52EE + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_bConnected DataMap + ChangeOffset<unsigned int>(module.Offset(0xB946D0), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned short>(module.Offset(0xB946D4), NEW_MAX_PLAYERS + 1); + ChangeOffset<unsigned short>(module.Offset(0xB946F8), PlayerResource_Connected_Size); + + // DT_PlayerResource::m_bAlive SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C5321 + 2), CPlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C5364 + 2), CPlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C539E + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_bAlive DataMap + ChangeOffset<unsigned int>(module.Offset(0xB94738), CPlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned short>(module.Offset(0xB9473C), NEW_MAX_PLAYERS + 1); + ChangeOffset<unsigned short>(module.Offset(0xB94760), PlayerResource_Alive_Size); + + // DT_PlayerResource::m_boolStats SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C53CC + 2), CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C5414 + 2), CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C544E + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_boolStats DataMap + ChangeOffset<unsigned int>(module.Offset(0xB947A0), CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned short>(module.Offset(0xB947A4), NEW_MAX_PLAYERS + 1); + ChangeOffset<unsigned short>(module.Offset(0xB947C8), PlayerResource_BoolStats_Size); + + // DT_PlayerResource::m_killStats SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C547C + 2), CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C54E2 + 2), CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C54FE + 4), PlayerResource_KillStats_Length); + + // DT_PlayerResource::m_killStats DataMap + ChangeOffset<unsigned int>(module.Offset(0xB94808), CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned short>(module.Offset(0xB9480C), PlayerResource_KillStats_Length); + ChangeOffset<unsigned short>(module.Offset(0xB94830), PlayerResource_KillStats_Size); + + // DT_PlayerResource::m_scoreStats SendProp + ChangeOffset<unsigned int>(module.Offset(0x5C5528 + 2), CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C5576 + 2), CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C5584 + 4), PlayerResource_ScoreStats_Length); + + // DT_PlayerResource::m_scoreStats DataMap + ChangeOffset<unsigned int>(module.Offset(0xB94870), CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned short>(module.Offset(0xB94874), PlayerResource_ScoreStats_Length); + ChangeOffset<unsigned short>(module.Offset(0xB94898), PlayerResource_ScoreStats_Size); + + // CPlayerResource::UpdatePlayerData - m_bConnected + ChangeOffset<unsigned int>(module.Offset(0x5C66EE + 4), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C672E + 4), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + + // CPlayerResource::UpdatePlayerData - m_iPing + ChangeOffset<unsigned int>(module.Offset(0x5C6394 + 4), CPlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C63DB + 4), CPlayerResource_OriginalSize + PlayerResource_Ping_Start); + + // CPlayerResource::UpdatePlayerData - m_iTeam + ChangeOffset<unsigned int>(module.Offset(0x5C63FD + 4), CPlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C6442 + 4), CPlayerResource_OriginalSize + PlayerResource_Team_Start); + + // CPlayerResource::UpdatePlayerData - m_iPRHealth + ChangeOffset<unsigned int>(module.Offset(0x5C645B + 4), CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C64A0 + 4), CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + + // CPlayerResource::UpdatePlayerData - m_bConnected + ChangeOffset<unsigned int>(module.Offset(0x5C64AA + 4), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C64F0 + 4), CPlayerResource_OriginalSize + PlayerResource_Connected_Start); + + // CPlayerResource::UpdatePlayerData - m_bAlive + ChangeOffset<unsigned int>(module.Offset(0x5C650A + 4), CPlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C654F + 4), CPlayerResource_OriginalSize + PlayerResource_Alive_Start); + + // CPlayerResource::UpdatePlayerData - m_boolStats + ChangeOffset<unsigned int>(module.Offset(0x5C6557 + 4), CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C65A5 + 4), CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + + // CPlayerResource::UpdatePlayerData - m_scoreStats + ChangeOffset<unsigned int>(module.Offset(0x5C65C2 + 3), CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C65E3 + 4), CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + + // CPlayerResource::UpdatePlayerData - m_killStats + ChangeOffset<unsigned int>(module.Offset(0x5C6654 + 3), CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x5C665B + 3), CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); + + *module.Offset(0x14E7390).As<DWORD*>() = 0; + auto DT_PlayerResource_Construct = module.Offset(0x5C4FE0).As<__int64(__fastcall*)()>(); + DT_PlayerResource_Construct(); + + constexpr int CTeam_OriginalSize = 3336; + constexpr int CTeam_AddedSize = Team_AddedSize; + constexpr int CTeam_ModifiedSize = CTeam_OriginalSize + CTeam_AddedSize; + + // CTeam class allocation function - allocate a bigger amount to fit all new team player data + ChangeOffset<unsigned int>(module.Offset(0x23924A + 1), CTeam_ModifiedSize); + + // CTeam::CTeam - increase memset length to clean newly allocated data + ChangeOffset<unsigned int>(module.Offset(0x2395AE + 2), 256 + CTeam_AddedSize); + + *module.Offset(0xC945A0).As<DWORD*>() = 0; + auto DT_Team_Construct = module.Offset(0x238F50).As<__int64(__fastcall*)()>(); + DT_Team_Construct(); +} + +// clang-format off +AUTOHOOK(RecvPropArray2, client.dll + 0x1CEDA0, +__int64, __fastcall, (__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn)) +// clang-format on +{ + // Change the amount of elements to account for a bigger player amount + if (!strcmp(name, "\"player_array\"")) + elements = NEW_MAX_PLAYERS; + + return RecvPropArray2(recvProp, elements, flags, name, proxyFn); +} + +ON_DLL_LOAD("client.dll", MaxPlayersOverride_Client, (CModule module)) +{ + if (!MaxPlayersIncreaseEnabled()) + return; + + AUTOHOOK_DISPATCH_MODULE(client.dll) + + constexpr int C_PlayerResource_OriginalSize = 5768; + constexpr int C_PlayerResource_AddedSize = PlayerResource_TotalSize; + constexpr int C_PlayerResource_ModifiedSize = C_PlayerResource_OriginalSize + C_PlayerResource_AddedSize; + + // C_PlayerResource class allocation function - allocate a bigger amount to fit all new max player data + ChangeOffset<unsigned int>(module.Offset(0x164C41 + 1), C_PlayerResource_ModifiedSize); + + // C_PlayerResource::C_PlayerResource - change loop end value + ChangeOffset<unsigned char>(module.Offset(0x1640C4 + 2), NEW_MAX_PLAYERS - 32); + + // C_PlayerResource::C_PlayerResource - change m_szName address + ChangeOffset<unsigned int>( + module.Offset(0x1640D0 + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class + + // C_PlayerResource::C_PlayerResource - change m_szName address + ChangeOffset<unsigned int>( + module.Offset(0x1640D0 + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class + + // C_PlayerResource::C_PlayerResource - increase memset length to clean newly allocated data + ChangeOffset<unsigned int>(module.Offset(0x1640D0 + 3), 2244 + C_PlayerResource_AddedSize); + + // C_PlayerResource::UpdatePlayerName - change m_szName address + ChangeOffset<unsigned int>(module.Offset(0x16431F + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName - change m_szName address 1 + ChangeOffset<unsigned int>(module.Offset(0x1645B1 + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName - change m_szName address 2 + ChangeOffset<unsigned int>(module.Offset(0x1645C0 + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName - change m_szName address 3 + ChangeOffset<unsigned int>(module.Offset(0x1645DD + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName internal func - change m_szName address 1 + ChangeOffset<unsigned int>(module.Offset(0x164B71 + 4), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName internal func - change m_szName address 2 + ChangeOffset<unsigned int>(module.Offset(0x164B9B + 4), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 1 + ChangeOffset<unsigned int>(module.Offset(0x164641 + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 2 + ChangeOffset<unsigned int>(module.Offset(0x164650 + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 3 + ChangeOffset<unsigned int>(module.Offset(0x16466D + 3), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 1 + ChangeOffset<unsigned int>(module.Offset(0x164BA3 + 4), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 2 + ChangeOffset<unsigned int>(module.Offset(0x164BCE + 4), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 3 + ChangeOffset<unsigned int>(module.Offset(0x164BE7 + 4), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + + // C_PlayerResource::m_szName + ChangeOffset<unsigned int>(module.Offset(0xc350f8), C_PlayerResource_OriginalSize + PlayerResource_Name_Start); + ChangeOffset<unsigned short>(module.Offset(0xc350f8 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource size + ChangeOffset<unsigned int>(module.Offset(0x163415 + 6), C_PlayerResource_ModifiedSize); + + // DT_PlayerResource::m_iPing RecvProp + ChangeOffset<unsigned int>(module.Offset(0x163492 + 2), C_PlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned int>(module.Offset(0x1634D6 + 2), C_PlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned int>(module.Offset(0x163515 + 5), NEW_MAX_PLAYERS + 1); + + // C_PlayerResource::m_iPing + ChangeOffset<unsigned int>(module.Offset(0xc35170), C_PlayerResource_OriginalSize + PlayerResource_Ping_Start); + ChangeOffset<unsigned short>(module.Offset(0xc35170 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_iTeam RecvProp + ChangeOffset<unsigned int>(module.Offset(0x163549 + 2), C_PlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned int>(module.Offset(0x1635C8 + 2), C_PlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned int>(module.Offset(0x1635AD + 5), NEW_MAX_PLAYERS + 1); + + // C_PlayerResource::m_iTeam + ChangeOffset<unsigned int>(module.Offset(0xc351e8), C_PlayerResource_OriginalSize + PlayerResource_Team_Start); + ChangeOffset<unsigned short>(module.Offset(0xc351e8 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_iPRHealth RecvProp + ChangeOffset<unsigned int>(module.Offset(0x1635F9 + 2), C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned int>(module.Offset(0x163625 + 2), C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned int>(module.Offset(0x163675 + 5), NEW_MAX_PLAYERS + 1); + + // C_PlayerResource::m_iPRHealth + ChangeOffset<unsigned int>(module.Offset(0xc35260), C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start); + ChangeOffset<unsigned short>(module.Offset(0xc35260 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_bConnected RecvProp + ChangeOffset<unsigned int>(module.Offset(0x1636A9 + 2), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned int>(module.Offset(0x1636D5 + 2), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned int>(module.Offset(0x163725 + 5), NEW_MAX_PLAYERS + 1); + + // C_PlayerResource::m_bConnected + ChangeOffset<unsigned int>(module.Offset(0xc352d8), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + ChangeOffset<unsigned short>(module.Offset(0xc352d8 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_bAlive RecvProp + ChangeOffset<unsigned int>(module.Offset(0x163759 + 2), C_PlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned int>(module.Offset(0x163785 + 2), C_PlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned int>(module.Offset(0x1637D5 + 5), NEW_MAX_PLAYERS + 1); + + // C_PlayerResource::m_bAlive + ChangeOffset<unsigned int>(module.Offset(0xc35350), C_PlayerResource_OriginalSize + PlayerResource_Alive_Start); + ChangeOffset<unsigned short>(module.Offset(0xc35350 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_boolStats RecvProp + ChangeOffset<unsigned int>(module.Offset(0x163809 + 2), C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x163835 + 2), C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x163885 + 5), NEW_MAX_PLAYERS + 1); + + // C_PlayerResource::m_boolStats + ChangeOffset<unsigned int>(module.Offset(0xc353c8), C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start); + ChangeOffset<unsigned short>(module.Offset(0xc353c8 + 4), NEW_MAX_PLAYERS + 1); + + // DT_PlayerResource::m_killStats RecvProp + ChangeOffset<unsigned int>(module.Offset(0x1638B3 + 2), C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x1638E5 + 2), C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x163935 + 5), PlayerResource_KillStats_Length); + + // C_PlayerResource::m_killStats + ChangeOffset<unsigned int>(module.Offset(0xc35440), C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start); + ChangeOffset<unsigned short>(module.Offset(0xc35440 + 4), PlayerResource_KillStats_Length); + + // DT_PlayerResource::m_scoreStats RecvProp + ChangeOffset<unsigned int>(module.Offset(0x163969 + 2), C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x163995 + 2), C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned int>(module.Offset(0x1639E5 + 5), PlayerResource_ScoreStats_Length); + + // C_PlayerResource::m_scoreStats + ChangeOffset<unsigned int>(module.Offset(0xc354b8), C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); + ChangeOffset<unsigned short>(module.Offset(0xc354b8 + 4), PlayerResource_ScoreStats_Length); + + // C_PlayerResource::GetPlayerName - change m_bConnected address + ChangeOffset<unsigned int>(module.Offset(0x164599 + 3), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + + // C_PlayerResource::GetPlayerName2 (?) - change m_bConnected address + ChangeOffset<unsigned int>(module.Offset(0x164629 + 3), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + + // C_PlayerResource::GetPlayerName internal func - change m_bConnected address + ChangeOffset<unsigned int>(module.Offset(0x164B13 + 3), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + + // Some other get name func (that seems to be unused) - change m_bConnected address + ChangeOffset<unsigned int>(module.Offset(0x164860 + 3), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + + // Some other get name func 2 (that seems to be unused too) - change m_bConnected address + ChangeOffset<unsigned int>(module.Offset(0x164834 + 3), C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); + + *module.Offset(0xC35068).As<DWORD*>() = 0; + auto DT_PlayerResource_Construct = module.Offset(0x163400).As<__int64(__fastcall*)()>(); + DT_PlayerResource_Construct(); + + constexpr int C_Team_OriginalSize = 3200; + constexpr int C_Team_AddedSize = Team_AddedSize; + constexpr int C_Team_ModifiedSize = C_Team_OriginalSize + C_Team_AddedSize; + + // C_Team class allocation function - allocate a bigger amount to fit all new team player data + ChangeOffset<unsigned int>(module.Offset(0x182321 + 1), C_Team_ModifiedSize); + + // C_Team::C_Team - increase memset length to clean newly allocated data + ChangeOffset<unsigned int>(module.Offset(0x1804A2 + 2), 256 + C_Team_AddedSize); + + // DT_Team size + ChangeOffset<unsigned int>(module.Offset(0xC3AA0C), C_Team_ModifiedSize); + + *module.Offset(0xC3AFF8).As<DWORD*>() = 0; + auto DT_Team_Construct = module.Offset(0x17F950).As<__int64(__fastcall*)()>(); + DT_Team_Construct(); +} diff --git a/NorthstarDLL/maxplayers.h b/NorthstarDLL/maxplayers.h new file mode 100644 index 00000000..b251f6a6 --- /dev/null +++ b/NorthstarDLL/maxplayers.h @@ -0,0 +1,7 @@ +#pragma once + +// should we use R2 for this? not sure +namespace R2 // use R2 namespace for game funcs +{ + int GetMaxPlayers(); +} // namespace R2 diff --git a/NorthstarDedicatedTest/memalloc.cpp b/NorthstarDLL/memalloc.cpp index 4ba54c73..8c0fafc8 100644 --- a/NorthstarDedicatedTest/memalloc.cpp +++ b/NorthstarDLL/memalloc.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "memalloc.h" -#include "gameutils.h" +#include "tier0.h" + +using namespace Tier0; // TODO: rename to malloc and free after removing statically compiled .libs @@ -8,9 +10,8 @@ extern "C" void* _malloc_base(size_t n) { // allocate into static buffer if g_pMemAllocSingleton isn't initialised if (!g_pMemAllocSingleton) - { - InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll")); - } + TryCreateGlobalMemAlloc(); + return g_pMemAllocSingleton->m_vtable->Alloc(g_pMemAllocSingleton, n); } @@ -22,19 +23,16 @@ extern "C" void* _malloc_base(size_t n) extern "C" void _free_base(void* p) { if (!g_pMemAllocSingleton) - { - spdlog::warn("Trying to free something before g_pMemAllocSingleton was ready, this should never happen"); - InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll")); - } + TryCreateGlobalMemAlloc(); + g_pMemAllocSingleton->m_vtable->Free(g_pMemAllocSingleton, p); } extern "C" void* _realloc_base(void* oldPtr, size_t size) { if (!g_pMemAllocSingleton) - { - InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll")); - } + TryCreateGlobalMemAlloc(); + return g_pMemAllocSingleton->m_vtable->Realloc(g_pMemAllocSingleton, oldPtr, size); } @@ -70,7 +68,7 @@ void* operator new(size_t n) return _malloc_base(n); } -void operator delete(void* p) +void operator delete(void* p) noexcept { _free_base(p); -} // /FORCE:MULTIPLE
\ No newline at end of file +} // /FORCE:MULTIPLE diff --git a/NorthstarDedicatedTest/memalloc.h b/NorthstarDLL/memalloc.h index a1b16ad4..fdd6474b 100644 --- a/NorthstarDedicatedTest/memalloc.h +++ b/NorthstarDLL/memalloc.h @@ -11,7 +11,7 @@ extern "C" void _free_base(void* const block); extern "C" char* _strdup_base(const char* src); void* operator new(size_t n); -void operator delete(void* p); +void operator delete(void* p) noexcept; // void* malloc(size_t n); diff --git a/NorthstarDLL/memory.cpp b/NorthstarDLL/memory.cpp new file mode 100644 index 00000000..2e994fb2 --- /dev/null +++ b/NorthstarDLL/memory.cpp @@ -0,0 +1,348 @@ +#include "pch.h" +#include "memory.h" + +MemoryAddress::MemoryAddress() : m_nAddress(0) {} +MemoryAddress::MemoryAddress(const uintptr_t nAddress) : m_nAddress(nAddress) {} +MemoryAddress::MemoryAddress(const void* pAddress) : m_nAddress(reinterpret_cast<uintptr_t>(pAddress)) {} + +// operators +MemoryAddress::operator uintptr_t() const +{ + return m_nAddress; +} + +MemoryAddress::operator void*() const +{ + return reinterpret_cast<void*>(m_nAddress); +} + +MemoryAddress::operator bool() const +{ + return m_nAddress != 0; +} + +bool MemoryAddress::operator==(const MemoryAddress& other) const +{ + return m_nAddress == other.m_nAddress; +} + +bool MemoryAddress::operator!=(const MemoryAddress& other) const +{ + return m_nAddress != other.m_nAddress; +} + +bool MemoryAddress::operator==(const uintptr_t& addr) const +{ + return m_nAddress == addr; +} + +bool MemoryAddress::operator!=(const uintptr_t& addr) const +{ + return m_nAddress != addr; +} + +MemoryAddress MemoryAddress::operator+(const MemoryAddress& other) const +{ + return Offset(other.m_nAddress); +} + +MemoryAddress MemoryAddress::operator-(const MemoryAddress& other) const +{ + return MemoryAddress(m_nAddress - other.m_nAddress); +} + +MemoryAddress MemoryAddress::operator+(const uintptr_t& addr) const +{ + return Offset(addr); +} + +MemoryAddress MemoryAddress::operator-(const uintptr_t& addr) const +{ + return MemoryAddress(m_nAddress - addr); +} + +MemoryAddress MemoryAddress::operator*() const +{ + return Deref(); +} + +// traversal +MemoryAddress MemoryAddress::Offset(const uintptr_t nOffset) const +{ + return MemoryAddress(m_nAddress + nOffset); +} + +MemoryAddress MemoryAddress::Deref(const int nNumDerefs) const +{ + uintptr_t ret = m_nAddress; + for (int i = 0; i < nNumDerefs; i++) + ret = *reinterpret_cast<uintptr_t*>(ret); + + return MemoryAddress(ret); +} + +// patching +void MemoryAddress::Patch(const uint8_t* pBytes, const size_t nSize) +{ + if (nSize) + WriteProcessMemory(GetCurrentProcess(), reinterpret_cast<LPVOID>(m_nAddress), pBytes, nSize, NULL); +} + +void MemoryAddress::Patch(const std::initializer_list<uint8_t> bytes) +{ + uint8_t* pBytes = new uint8_t[bytes.size()]; + + int i = 0; + for (const uint8_t& byte : bytes) + pBytes[i++] = byte; + + Patch(pBytes, bytes.size()); + delete[] pBytes; +} + +inline std::vector<uint8_t> HexBytesToString(const char* pHexString) +{ + std::vector<uint8_t> ret; + + int size = strlen(pHexString); + for (int i = 0; i < size; i++) + { + // If this is a space character, ignore it + if (isspace(pHexString[i])) + continue; + + if (i < size - 1) + { + BYTE result = 0; + for (int j = 0; j < 2; j++) + { + int val = 0; + char c = *(pHexString + i + j); + if (c >= 'a') + { + val = c - 'a' + 0xA; + } + else if (c >= 'A') + { + val = c - 'A' + 0xA; + } + else if (isdigit(c)) + { + val = c - '0'; + } + else + { + assert(false, "Failed to parse invalid hex string."); + val = -1; + } + + result += (j == 0) ? val * 16 : val; + } + ret.push_back(result); + } + + i++; + } + + return ret; +} + +void MemoryAddress::Patch(const char* pBytes) +{ + std::vector<uint8_t> vBytes = HexBytesToString(pBytes); + Patch(vBytes.data(), vBytes.size()); +} + +void MemoryAddress::NOP(const size_t nSize) +{ + uint8_t* pBytes = new uint8_t[nSize]; + + memset(pBytes, 0x90, nSize); + Patch(pBytes, nSize); + + delete[] pBytes; +} + +bool MemoryAddress::IsMemoryReadable(const size_t nSize) +{ + static SYSTEM_INFO sysInfo; + if (!sysInfo.dwPageSize) + GetSystemInfo(&sysInfo); + + MEMORY_BASIC_INFORMATION memInfo; + if (!VirtualQuery(reinterpret_cast<LPCVOID>(m_nAddress), &memInfo, sizeof(memInfo))) + return false; + + return memInfo.RegionSize >= nSize && memInfo.State & MEM_COMMIT && !(memInfo.Protect & PAGE_NOACCESS); +} + +CModule::CModule(const HMODULE pModule) +{ + MODULEINFO mInfo {0}; + + if (pModule && pModule != INVALID_HANDLE_VALUE) + GetModuleInformation(GetCurrentProcess(), pModule, &mInfo, sizeof(MODULEINFO)); + + m_nModuleSize = static_cast<size_t>(mInfo.SizeOfImage); + m_pModuleBase = reinterpret_cast<uintptr_t>(mInfo.lpBaseOfDll); + m_nAddress = m_pModuleBase; + + if (!m_nModuleSize || !m_pModuleBase) + return; + + m_pDOSHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(m_pModuleBase); + m_pNTHeaders = reinterpret_cast<IMAGE_NT_HEADERS64*>(m_pModuleBase + m_pDOSHeader->e_lfanew); + + const IMAGE_SECTION_HEADER* hSection = IMAGE_FIRST_SECTION(m_pNTHeaders); // Get first image section. + + for (WORD i = 0; i < m_pNTHeaders->FileHeader.NumberOfSections; i++) // Loop through the sections. + { + const IMAGE_SECTION_HEADER& hCurrentSection = hSection[i]; // Get current section. + + ModuleSections_t moduleSection = ModuleSections_t( + std::string(reinterpret_cast<const char*>(hCurrentSection.Name)), + static_cast<uintptr_t>(m_pModuleBase + hCurrentSection.VirtualAddress), + hCurrentSection.SizeOfRawData); + + if (!strcmp((const char*)hCurrentSection.Name, ".text")) + m_ExecutableCode = moduleSection; + else if (!strcmp((const char*)hCurrentSection.Name, ".pdata")) + m_ExceptionTable = moduleSection; + else if (!strcmp((const char*)hCurrentSection.Name, ".data")) + m_RunTimeData = moduleSection; + else if (!strcmp((const char*)hCurrentSection.Name, ".rdata")) + m_ReadOnlyData = moduleSection; + + m_vModuleSections.push_back(moduleSection); // Push back a struct with the section data. + } +} + +CModule::CModule(const char* pModuleName) : CModule(GetModuleHandleA(pModuleName)) {} + +MemoryAddress CModule::GetExport(const char* pExportName) +{ + return MemoryAddress(reinterpret_cast<uintptr_t>(GetProcAddress(reinterpret_cast<HMODULE>(m_nAddress), pExportName))); +} + +MemoryAddress CModule::FindPattern(const uint8_t* pPattern, const char* pMask) +{ + if (!m_ExecutableCode.IsSectionValid()) + return MemoryAddress(); + + uint64_t nBase = static_cast<uint64_t>(m_ExecutableCode.m_pSectionBase); + uint64_t nSize = static_cast<uint64_t>(m_ExecutableCode.m_nSectionSize); + + const uint8_t* pData = reinterpret_cast<uint8_t*>(nBase); + const uint8_t* pEnd = pData + static_cast<uint32_t>(nSize) - strlen(pMask); + + int nMasks[64]; // 64*16 = enough masks for 1024 bytes. + int iNumMasks = static_cast<int>(ceil(static_cast<float>(strlen(pMask)) / 16.f)); + + memset(nMasks, '\0', iNumMasks * sizeof(int)); + for (intptr_t i = 0; i < iNumMasks; ++i) + { + for (intptr_t j = strnlen(pMask + i * 16, 16) - 1; j >= 0; --j) + { + if (pMask[i * 16 + j] == 'x') + { + _bittestandset(reinterpret_cast<LONG*>(&nMasks[i]), j); + } + } + } + __m128i xmm1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pPattern)); + __m128i xmm2, xmm3, msks; + for (; pData != pEnd; _mm_prefetch(reinterpret_cast<const char*>(++pData + 64), _MM_HINT_NTA)) + { + if (pPattern[0] == pData[0]) + { + xmm2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pData)); + msks = _mm_cmpeq_epi8(xmm1, xmm2); + if ((_mm_movemask_epi8(msks) & nMasks[0]) == nMasks[0]) + { + for (uintptr_t i = 1; i < static_cast<uintptr_t>(iNumMasks); ++i) + { + xmm2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>((pData + i * 16))); + xmm3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>((pPattern + i * 16))); + msks = _mm_cmpeq_epi8(xmm2, xmm3); + if ((_mm_movemask_epi8(msks) & nMasks[i]) == nMasks[i]) + { + if ((i + 1) == iNumMasks) + { + return MemoryAddress(const_cast<uint8_t*>(pData)); + } + } + else + goto CONTINUE; + } + + return MemoryAddress((&*(const_cast<uint8_t*>(pData)))); + } + } + + CONTINUE:; + } + + return MemoryAddress(); +} + +inline std::pair<std::vector<uint8_t>, std::string> MaskedBytesFromPattern(const char* pPatternString) +{ + std::vector<uint8_t> vRet; + std::string sMask; + + int size = strlen(pPatternString); + for (int i = 0; i < size; i++) + { + // If this is a space character, ignore it + if (isspace(pPatternString[i])) + continue; + + if (pPatternString[i] == '?') + { + // Add a wildcard + vRet.push_back(0); + sMask.append("?"); + } + else if (i < size - 1) + { + BYTE result = 0; + for (int j = 0; j < 2; j++) + { + int val = 0; + char c = *(pPatternString + i + j); + if (c >= 'a') + { + val = c - 'a' + 0xA; + } + else if (c >= 'A') + { + val = c - 'A' + 0xA; + } + else if (isdigit(c)) + { + val = c - '0'; + } + else + { + assert(false, "Failed to parse invalid pattern string."); + val = -1; + } + + result += (j == 0) ? val * 16 : val; + } + + vRet.push_back(result); + sMask.append("x"); + } + + i++; + } + + return std::make_pair(vRet, sMask); +} + +MemoryAddress CModule::FindPattern(const char* pPattern) +{ + const auto pattern = MaskedBytesFromPattern(pPattern); + return FindPattern(pattern.first.data(), pattern.second.c_str()); +} diff --git a/NorthstarDLL/memory.h b/NorthstarDLL/memory.h new file mode 100644 index 00000000..38c76cb3 --- /dev/null +++ b/NorthstarDLL/memory.h @@ -0,0 +1,90 @@ +#pragma once + +class MemoryAddress +{ + public: + uintptr_t m_nAddress; + + public: + MemoryAddress(); + MemoryAddress(const uintptr_t nAddress); + MemoryAddress(const void* pAddress); + + // operators + operator uintptr_t() const; + operator void*() const; + operator bool() const; + + bool operator==(const MemoryAddress& other) const; + bool operator!=(const MemoryAddress& other) const; + bool operator==(const uintptr_t& addr) const; + bool operator!=(const uintptr_t& addr) const; + + MemoryAddress operator+(const MemoryAddress& other) const; + MemoryAddress operator-(const MemoryAddress& other) const; + MemoryAddress operator+(const uintptr_t& other) const; + MemoryAddress operator-(const uintptr_t& other) const; + MemoryAddress operator*() const; + + template <typename T> T As() + { + return reinterpret_cast<T>(m_nAddress); + } + + // traversal + MemoryAddress Offset(const uintptr_t nOffset) const; + MemoryAddress Deref(const int nNumDerefs = 1) const; + + // patching + void Patch(const uint8_t* pBytes, const size_t nSize); + void Patch(const std::initializer_list<uint8_t> bytes); + void Patch(const char* pBytes); + void NOP(const size_t nSize); + + bool IsMemoryReadable(const size_t nSize); +}; + +// based on https://github.com/Mauler125/r5sdk/blob/master/r5dev/public/include/module.h +class CModule : public MemoryAddress +{ + public: + struct ModuleSections_t + { + ModuleSections_t(void) = default; + ModuleSections_t(const std::string& svSectionName, uintptr_t pSectionBase, size_t nSectionSize) + : m_svSectionName(svSectionName), m_pSectionBase(pSectionBase), m_nSectionSize(nSectionSize) + { + } + + bool IsSectionValid(void) const + { + return m_nSectionSize != 0; + } + + std::string m_svSectionName; // Name of section. + uintptr_t m_pSectionBase {}; // Start address of section. + size_t m_nSectionSize {}; // Size of section. + }; + + ModuleSections_t m_ExecutableCode; + ModuleSections_t m_ExceptionTable; + ModuleSections_t m_RunTimeData; + ModuleSections_t m_ReadOnlyData; + + private: + std::string m_svModuleName; + uintptr_t m_pModuleBase {}; + DWORD m_nModuleSize {}; + IMAGE_NT_HEADERS64* m_pNTHeaders = nullptr; + IMAGE_DOS_HEADER* m_pDOSHeader = nullptr; + std::vector<ModuleSections_t> m_vModuleSections; + + public: + CModule() = delete; // no default, we need a module name + CModule(const HMODULE pModule); + CModule(const char* pModuleName); + + MemoryAddress GetExport(const char* pExportName); + MemoryAddress FindPattern(const uint8_t* pPattern, const char* pMask); + MemoryAddress FindPattern(const char* pPattern); +}; diff --git a/NorthstarDLL/misccommands.cpp b/NorthstarDLL/misccommands.cpp new file mode 100644 index 00000000..572d5620 --- /dev/null +++ b/NorthstarDLL/misccommands.cpp @@ -0,0 +1,65 @@ +#include "pch.h" +#include "misccommands.h" +#include "concommand.h" +#include "playlist.h" +#include "r2engine.h" +#include "r2client.h" +#include "hoststate.h" +#include "masterserver.h" +#include "serverauthentication.h" +#include "squirrel.h" + +void ConCommand_force_newgame(const CCommand& arg) +{ + if (arg.ArgC() < 2) + return; + + R2::g_pHostState->m_iNextState = R2::HostState_t::HS_NEW_GAME; + strncpy(R2::g_pHostState->m_levelName, arg.Arg(1), sizeof(R2::g_pHostState->m_levelName)); +} + +void ConCommand_ns_start_reauth_and_leave_to_lobby(const CCommand& arg) +{ + // hack for special case where we're on a local server, so we erase our own newly created auth data on disconnect + g_pMasterServerManager->m_bNewgameAfterSelfAuth = true; + g_pMasterServerManager->AuthenticateWithOwnServer(R2::g_pLocalPlayerUserID, g_pMasterServerManager->m_sOwnClientAuthToken); +} + +void ConCommand_ns_end_reauth_and_leave_to_lobby(const CCommand& arg) +{ + R2::Cbuf_AddText( + R2::Cbuf_GetCurrentPlayer(), + fmt::format("serverfilter {}", g_pServerAuthentication->m_RemoteAuthenticationData.begin()->first).c_str(), + R2::cmd_source_t::kCommandSrcCode); + R2::Cbuf_Execute(); + + // weird way of checking, but check if client script vm is initialised, mainly just to allow players to cancel this + if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM) + { + g_pServerAuthentication->m_bNeedLocalAuthForNewgame = true; + + // this won't set playlist correctly on remote clients, don't think they can set playlist until they've left which sorta + // fucks things should maybe set this in HostState_NewGame? + R2::SetCurrentPlaylist("tdm"); + strcpy(R2::g_pHostState->m_levelName, "mp_lobby"); + R2::g_pHostState->m_iNextState = R2::HostState_t::HS_NEW_GAME; + } +} + +void AddMiscConCommands() +{ + RegisterConCommand( + "force_newgame", + ConCommand_force_newgame, + "forces a map load through directly setting g_pHostState->m_iNextState to HS_NEW_GAME", + FCVAR_NONE); + + RegisterConCommand( + "ns_start_reauth_and_leave_to_lobby", + ConCommand_ns_start_reauth_and_leave_to_lobby, + "called by the server, used to reauth and return the player to lobby when leaving a game", + FCVAR_SERVER_CAN_EXECUTE); + + // this is a concommand because we make a deferred call to it from another thread + RegisterConCommand("ns_end_reauth_and_leave_to_lobby", ConCommand_ns_end_reauth_and_leave_to_lobby, "", FCVAR_NONE); +} diff --git a/NorthstarDLL/misccommands.h b/NorthstarDLL/misccommands.h new file mode 100644 index 00000000..fbd41b32 --- /dev/null +++ b/NorthstarDLL/misccommands.h @@ -0,0 +1,2 @@ +#pragma once +void AddMiscConCommands(); diff --git a/NorthstarDLL/miscserverfixes.cpp b/NorthstarDLL/miscserverfixes.cpp new file mode 100644 index 00000000..4feca505 --- /dev/null +++ b/NorthstarDLL/miscserverfixes.cpp @@ -0,0 +1,7 @@ +#include "pch.h" + +ON_DLL_LOAD("server.dll", MiscServerFixes, (CModule module)) +{ + // nop out call to VGUI shutdown since it crashes the game when quitting from the console + module.Offset(0x154A96).NOP(5); +} diff --git a/NorthstarDLL/miscserverscript.cpp b/NorthstarDLL/miscserverscript.cpp new file mode 100644 index 00000000..7ae8047f --- /dev/null +++ b/NorthstarDLL/miscserverscript.cpp @@ -0,0 +1,65 @@ +#include "pch.h" +#include "squirrel.h" +#include "masterserver.h" +#include "serverauthentication.h" +#include "dedicated.h" +#include "r2client.h" +#include "r2server.h" + +#include <filesystem> + +// void function NSEarlyWritePlayerIndexPersistenceForLeave( int playerIndex ) +SQRESULT SQ_EarlyWritePlayerIndexPersistenceForLeave(HSquirrelVM* sqvm) +{ + int playerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 1); + R2::CBaseClient* player = &R2::g_pClientArray[playerIndex]; + + if (!g_pServerAuthentication->m_PlayerAuthenticationData.count(player)) + { + g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, fmt::format("Invalid playerindex {}", playerIndex).c_str()); + return SQRESULT_ERROR; + } + + g_pServerAuthentication->m_PlayerAuthenticationData[player].needPersistenceWriteOnLeave = false; + g_pServerAuthentication->WritePersistentData(player); + return SQRESULT_NULL; +} + +// bool function NSIsWritingPlayerPersistence() +SQRESULT SQ_IsWritingPlayerPersistence(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::SERVER>->pushbool(sqvm, g_pMasterServerManager->m_bSavingPersistentData); + return SQRESULT_NOTNULL; +} + +// bool function NSIsPlayerIndexLocalPlayer( int playerIndex ) +SQRESULT SQ_IsPlayerIndexLocalPlayer(HSquirrelVM* sqvm) +{ + int playerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 1); + R2::CBaseClient* player = &R2::g_pClientArray[playerIndex]; + if (!g_pServerAuthentication->m_PlayerAuthenticationData.count(player)) + { + g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, fmt::format("Invalid playerindex {}", playerIndex).c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::SERVER>->pushbool(sqvm, !strcmp(R2::g_pLocalPlayerUserID, player->m_UID)); + return SQRESULT_NOTNULL; +} + +// bool function NSIsDedicated() +SQRESULT SQ_IsDedicated(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::SERVER>->pushbool(sqvm, IsDedicatedServer()); + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_RELIESON("server.dll", MiscServerScriptCommands, ServerSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "void", "NSEarlyWritePlayerIndexPersistenceForLeave", "int playerIndex", "", SQ_EarlyWritePlayerIndexPersistenceForLeave); + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration("bool", "NSIsWritingPlayerPersistence", "", "", SQ_IsWritingPlayerPersistence); + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "bool", "NSIsPlayerIndexLocalPlayer", "int playerIndex", "", SQ_IsPlayerIndexLocalPlayer); + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration("bool", "NSIsDedicated", "", "", SQ_IsDedicated); +} diff --git a/NorthstarDLL/modlocalisation.cpp b/NorthstarDLL/modlocalisation.cpp new file mode 100644 index 00000000..b12f0a40 --- /dev/null +++ b/NorthstarDLL/modlocalisation.cpp @@ -0,0 +1,35 @@ +#include "pch.h" +#include "modmanager.h" + +AUTOHOOK_INIT() + +// clang-format off +AUTOHOOK(AddLocalisationFile, localize.dll + 0x6D80, +bool, __fastcall, (void* pVguiLocalize, const char* path, const char* pathId, char unknown)) +// clang-format on +{ + static bool bLoadModLocalisationFiles = true; + bool ret = AddLocalisationFile(pVguiLocalize, path, pathId, unknown); + + if (ret) + spdlog::info("Loaded localisation file {} successfully", path); + + if (!bLoadModLocalisationFiles) + return ret; + + bLoadModLocalisationFiles = false; + + for (Mod mod : g_pModManager->m_LoadedMods) + if (mod.m_bEnabled) + for (std::string& localisationFile : mod.LocalisationFiles) + AddLocalisationFile(pVguiLocalize, localisationFile.c_str(), pathId, unknown); + + bLoadModLocalisationFiles = true; + + return ret; +} + +ON_DLL_LOAD_CLIENT("localize.dll", Localize, (CModule module)) +{ + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDLL/modmanager.cpp index 50c7b371..05060902 100644 --- a/NorthstarDedicatedTest/modmanager.cpp +++ b/NorthstarDLL/modmanager.cpp @@ -4,6 +4,10 @@ #include "concommand.h" #include "audio.h" #include "masterserver.h" +#include "filesystem.h" +#include "rpakfilesystem.h" +#include "nsprefix.h" + #include "rapidjson/error/en.h" #include "rapidjson/document.h" #include "rapidjson/ostreamwrapper.h" @@ -13,17 +17,14 @@ #include <string> #include <sstream> #include <vector> -#include "filesystem.h" -#include "rpakfilesystem.h" -#include "configurables.h" -ModManager* g_ModManager; +ModManager* g_pModManager; Mod::Mod(fs::path modDir, char* jsonBuf) { - wasReadSuccessfully = false; + m_bWasReadSuccessfully = false; - ModDirectory = modDir; + m_ModDirectory = modDir; rapidjson_document modJson; modJson.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>(jsonBuf); @@ -106,11 +107,55 @@ Mod::Mod(fs::path modDir, char* jsonBuf) else convar->HelpString = ""; - // todo: could possibly parse FCVAR names here instead, would be easier + convar->Flags = FCVAR_NONE; + if (convarObj.HasMember("Flags")) - convar->Flags = convarObj["Flags"].GetInt(); - else - convar->Flags = FCVAR_NONE; + { + // read raw integer flags + if (convarObj["Flags"].IsInt()) + convar->Flags = convarObj["Flags"].GetInt(); + else if (convarObj["Flags"].IsString()) + { + // parse cvar flags from string + // example string: ARCHIVE_PLAYERPROFILE | GAMEDLL + + std::string sFlags = convarObj["Flags"].GetString(); + sFlags += '|'; // add additional | so we register the last flag + std::string sCurrentFlag; + + for (int i = 0; i < sFlags.length(); i++) + { + if (isspace(sFlags[i])) + continue; + + // if we encounter a |, add current string as a flag + if (sFlags[i] == '|') + { + bool bHasFlags = false; + int iCurrentFlags; + + for (auto& flagPair : g_PrintCommandFlags) + { + if (!sCurrentFlag.compare(flagPair.second)) + { + iCurrentFlags = flagPair.first; + bHasFlags = true; + break; + } + } + + if (bHasFlags) + convar->Flags |= iCurrentFlags; + else + spdlog::warn("Mod ConVar {} has unknown flag {}", convar->Name, sCurrentFlag); + + sCurrentFlag = ""; + } + else + sCurrentFlag += sFlags[i]; + } + } + } ConVars.push_back(convar); } @@ -127,7 +172,7 @@ Mod::Mod(fs::path modDir, char* jsonBuf) ModScript script; script.Path = scriptObj["Path"].GetString(); - script.RsonRunOn = scriptObj["RunOn"].GetString(); + script.RunOn = scriptObj["RunOn"].GetString(); if (scriptObj.HasMember("ServerCallback") && scriptObj["ServerCallback"].IsObject()) { @@ -186,7 +231,27 @@ Mod::Mod(fs::path modDir, char* jsonBuf) } } - wasReadSuccessfully = true; + if (modJson.HasMember("Dependencies") && modJson["Dependencies"].IsObject()) + { + for (auto v = modJson["Dependencies"].MemberBegin(); v != modJson["Dependencies"].MemberEnd(); v++) + { + if (!v->name.IsString() || !v->value.IsString()) + continue; + + spdlog::info("Constant {} defined by {} for mod {}", v->name.GetString(), Name, v->value.GetString()); + if (DependencyConstants.find(v->name.GetString()) != DependencyConstants.end() && + v->value.GetString() != DependencyConstants[v->name.GetString()]) + { + spdlog::error("A dependency constant with the same name already exists for another mod. Change the constant name."); + return; + } + + if (DependencyConstants.find(v->name.GetString()) == DependencyConstants.end()) + DependencyConstants.emplace(v->name.GetString(), v->value.GetString()); + } + } + + m_bWasReadSuccessfully = true; } ModManager::ModManager() @@ -203,7 +268,7 @@ ModManager::ModManager() void ModManager::LoadMods() { - if (m_hasLoadedMods) + if (m_bHasLoadedMods) UnloadMods(); std::vector<fs::path> modDirs; @@ -212,6 +277,8 @@ void ModManager::LoadMods() fs::remove_all(GetCompiledAssetsPath()); fs::create_directories(GetModFolderPath()); + m_DependencyConstants.clear(); + // read enabled mods cfg std::ifstream enabledModsStream(GetNorthstarPrefix() + "/enabledmods.json"); std::stringstream enabledModsStringStream; @@ -222,10 +289,10 @@ void ModManager::LoadMods() enabledModsStringStream << (char)enabledModsStream.get(); enabledModsStream.close(); - m_enabledModsCfg.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>( + m_EnabledModsCfg.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>( enabledModsStringStream.str().c_str()); - m_hasEnabledModsCfg = m_enabledModsCfg.IsObject(); + m_bHasEnabledModsCfg = m_EnabledModsCfg.IsObject(); } // get mod directories @@ -253,31 +320,43 @@ void ModManager::LoadMods() Mod mod(modDir, (char*)jsonStringStream.str().c_str()); - if (m_hasEnabledModsCfg && m_enabledModsCfg.HasMember(mod.Name.c_str())) - mod.Enabled = m_enabledModsCfg[mod.Name.c_str()].IsTrue(); + for (auto& pair : mod.DependencyConstants) + { + if (m_DependencyConstants.find(pair.first) != m_DependencyConstants.end() && m_DependencyConstants[pair.first] != pair.second) + { + spdlog::error("Constant {} in mod {} already exists in another mod.", pair.first, mod.Name); + mod.m_bWasReadSuccessfully = false; + break; + } + if (m_DependencyConstants.find(pair.first) == m_DependencyConstants.end()) + m_DependencyConstants.emplace(pair); + } + + if (m_bHasEnabledModsCfg && m_EnabledModsCfg.HasMember(mod.Name.c_str())) + mod.m_bEnabled = m_EnabledModsCfg[mod.Name.c_str()].IsTrue(); else - mod.Enabled = true; + mod.m_bEnabled = true; - if (mod.wasReadSuccessfully) + if (mod.m_bWasReadSuccessfully) { spdlog::info("Loaded mod {} successfully", mod.Name); - if (mod.Enabled) + if (mod.m_bEnabled) spdlog::info("Mod {} is enabled", mod.Name); else spdlog::info("Mod {} is disabled", mod.Name); - m_loadedMods.push_back(mod); + m_LoadedMods.push_back(mod); } else spdlog::warn("Skipping loading mod file {}", (modDir / "mod.json").string()); } // sort by load prio, lowest-highest - std::sort(m_loadedMods.begin(), m_loadedMods.end(), [](Mod& a, Mod& b) { return a.LoadPriority < b.LoadPriority; }); + std::sort(m_LoadedMods.begin(), m_LoadedMods.end(), [](Mod& a, Mod& b) { return a.LoadPriority < b.LoadPriority; }); - for (Mod& mod : m_loadedMods) + for (Mod& mod : m_LoadedMods) { - if (!mod.Enabled) + if (!mod.m_bEnabled) continue; // register convars @@ -285,15 +364,15 @@ void ModManager::LoadMods() // preexisting convars note: we don't delete convars if they already exist because they're used for script stuff, unfortunately this // causes us to leak memory on reload, but not much, potentially find a way to not do this at some point for (ModConVar* convar : mod.ConVars) - if (!g_pCVar->FindVar(convar->Name.c_str())) // make sure convar isn't registered yet, unsure if necessary but idk what - // behaviour is for defining same convar multiple times + if (!R2::g_pCVar->FindVar(convar->Name.c_str())) // make sure convar isn't registered yet, unsure if necessary but idk what + // behaviour is for defining same convar multiple times new ConVar(convar->Name.c_str(), convar->DefaultValue.c_str(), convar->Flags, convar->HelpString.c_str()); // read vpk paths - if (fs::exists(mod.ModDirectory / "vpk")) + if (fs::exists(mod.m_ModDirectory / "vpk")) { // read vpk cfg - std::ifstream vpkJsonStream(mod.ModDirectory / "vpk/vpk.json"); + std::ifstream vpkJsonStream(mod.m_ModDirectory / "vpk/vpk.json"); std::stringstream vpkJsonStringStream; bool bUseVPKJson = false; @@ -311,7 +390,7 @@ void ModManager::LoadMods() bUseVPKJson = !dVpkJson.HasParseError() && dVpkJson.IsObject(); } - for (fs::directory_entry file : fs::directory_iterator(mod.ModDirectory / "vpk")) + for (fs::directory_entry file : fs::directory_iterator(mod.m_ModDirectory / "vpk")) { // a bunch of checks to make sure we're only adding dir vpks and their paths are good // note: the game will literally only load vpks with the english prefix @@ -322,25 +401,24 @@ void ModManager::LoadMods() std::string formattedPath = file.path().filename().string(); // this really fucking sucks but it'll work - std::string vpkName = - (file.path().parent_path() / formattedPath.substr(strlen("english"), formattedPath.find(".bsp") - 3)).string(); + std::string vpkName = formattedPath.substr(strlen("english"), formattedPath.find(".bsp") - 3); ModVPKEntry& modVpk = mod.Vpks.emplace_back(); modVpk.m_bAutoLoad = !bUseVPKJson || (dVpkJson.HasMember("Preload") && dVpkJson["Preload"].IsObject() && dVpkJson["Preload"].HasMember(vpkName) && dVpkJson["Preload"][vpkName].IsTrue()); - modVpk.m_sVpkPath = vpkName; + modVpk.m_sVpkPath = (file.path().parent_path() / vpkName).string(); - if (m_hasLoadedMods && modVpk.m_bAutoLoad) - (*g_Filesystem)->m_vtable->MountVPK(*g_Filesystem, vpkName.c_str()); + if (m_bHasLoadedMods && modVpk.m_bAutoLoad) + (*R2::g_pFilesystem)->m_vtable->MountVPK(*R2::g_pFilesystem, vpkName.c_str()); } } } // read rpak paths - if (fs::exists(mod.ModDirectory / "paks")) + if (fs::exists(mod.m_ModDirectory / "paks")) { // read rpak cfg - std::ifstream rpakJsonStream(mod.ModDirectory / "paks/rpak.json"); + std::ifstream rpakJsonStream(mod.m_ModDirectory / "paks/rpak.json"); std::stringstream rpakJsonStringStream; bool bUseRpakJson = false; @@ -372,7 +450,7 @@ void ModManager::LoadMods() } } - for (fs::directory_entry file : fs::directory_iterator(mod.ModDirectory / "paks")) + for (fs::directory_entry file : fs::directory_iterator(mod.m_ModDirectory / "paks")) { // ensure we're only loading rpaks if (fs::is_regular_file(file) && file.path().extension() == ".rpak") @@ -383,32 +461,39 @@ void ModManager::LoadMods() modPak.m_bAutoLoad = !bUseRpakJson || (dRpakJson.HasMember("Preload") && dRpakJson["Preload"].IsObject() && dRpakJson["Preload"].HasMember(pakName) && dRpakJson["Preload"][pakName].IsTrue()); + + // postload things + if (!bUseRpakJson || + (dRpakJson.HasMember("Postload") && dRpakJson["Postload"].IsObject() && dRpakJson["Postload"].HasMember(pakName))) + modPak.m_sLoadAfterPak = dRpakJson["Postload"][pakName].GetString(); + modPak.m_sPakName = pakName; // not using atm because we need to resolve path to rpak // if (m_hasLoadedMods && modPak.m_bAutoLoad) - // g_PakLoadManager->LoadPakAsync(pakName.c_str()); + // g_pPakLoadManager->LoadPakAsync(pakName.c_str()); } } } // read keyvalues paths - if (fs::exists(mod.ModDirectory / "keyvalues")) + if (fs::exists(mod.m_ModDirectory / "keyvalues")) { - for (fs::directory_entry file : fs::recursive_directory_iterator(mod.ModDirectory / "keyvalues")) + for (fs::directory_entry file : fs::recursive_directory_iterator(mod.m_ModDirectory / "keyvalues")) { if (fs::is_regular_file(file)) { - std::string kvStr = file.path().lexically_relative(mod.ModDirectory / "keyvalues").lexically_normal().string(); + std::string kvStr = + g_pModManager->NormaliseModFilePath(file.path().lexically_relative(mod.m_ModDirectory / "keyvalues")); mod.KeyValues.emplace(STR_HASH(kvStr), kvStr); } } } // read pdiff - if (fs::exists(mod.ModDirectory / "mod.pdiff")) + if (fs::exists(mod.m_ModDirectory / "mod.pdiff")) { - std::ifstream pdiffStream(mod.ModDirectory / "mod.pdiff"); + std::ifstream pdiffStream(mod.m_ModDirectory / "mod.pdiff"); if (!pdiffStream.fail()) { @@ -423,17 +508,17 @@ void ModManager::LoadMods() } // read bink video paths - if (fs::exists(mod.ModDirectory / "media")) + if (fs::exists(mod.m_ModDirectory / "media")) { - for (fs::directory_entry file : fs::recursive_directory_iterator(mod.ModDirectory / "media")) + for (fs::directory_entry file : fs::recursive_directory_iterator(mod.m_ModDirectory / "media")) if (fs::is_regular_file(file) && file.path().extension() == ".bik") mod.BinkVideos.push_back(file.path().filename().string()); } // try to load audio - if (fs::exists(mod.ModDirectory / "audio")) + if (fs::exists(mod.m_ModDirectory / "audio")) { - for (fs::directory_entry file : fs::directory_iterator(mod.ModDirectory / "audio")) + for (fs::directory_entry file : fs::directory_iterator(mod.m_ModDirectory / "audio")) { if (fs::is_regular_file(file) && file.path().extension().string() == ".json") { @@ -448,23 +533,23 @@ void ModManager::LoadMods() } // in a seperate loop because we register mod files in reverse order, since mods loaded later should have their files prioritised - for (int64_t i = m_loadedMods.size() - 1; i > -1; i--) + for (int64_t i = m_LoadedMods.size() - 1; i > -1; i--) { - if (!m_loadedMods[i].Enabled) + if (!m_LoadedMods[i].m_bEnabled) continue; - if (fs::exists(m_loadedMods[i].ModDirectory / MOD_OVERRIDE_DIR)) + if (fs::exists(m_LoadedMods[i].m_ModDirectory / MOD_OVERRIDE_DIR)) { - for (fs::directory_entry file : fs::recursive_directory_iterator(m_loadedMods[i].ModDirectory / MOD_OVERRIDE_DIR)) + for (fs::directory_entry file : fs::recursive_directory_iterator(m_LoadedMods[i].m_ModDirectory / MOD_OVERRIDE_DIR)) { - fs::path path = file.path().lexically_relative(m_loadedMods[i].ModDirectory / MOD_OVERRIDE_DIR).lexically_normal(); - - if (file.is_regular_file() && m_modFiles.find(path.string()) == m_modFiles.end()) + std::string path = + g_pModManager->NormaliseModFilePath(file.path().lexically_relative(m_LoadedMods[i].m_ModDirectory / MOD_OVERRIDE_DIR)); + if (file.is_regular_file() && m_ModFiles.find(path) == m_ModFiles.end()) { ModOverrideFile modFile; - modFile.owningMod = &m_loadedMods[i]; - modFile.path = path; - m_modFiles.insert(std::make_pair(path.string(), modFile)); + modFile.m_pOwningMod = &m_LoadedMods[i]; + modFile.m_Path = path; + m_ModFiles.insert(std::make_pair(path, modFile)); } } } @@ -476,9 +561,9 @@ void ModManager::LoadMods() modinfoDoc.AddMember("Mods", rapidjson_document::GenericValue(rapidjson::kArrayType), modinfoDoc.GetAllocator()); int currentModIndex = 0; - for (Mod& mod : m_loadedMods) + for (Mod& mod : m_LoadedMods) { - if (!mod.Enabled || (!mod.RequiredOnClient && !mod.Pdiff.size())) + if (!mod.m_bEnabled || (!mod.RequiredOnClient && !mod.Pdiff.size())) continue; modinfoDoc["Mods"].PushBack(rapidjson_document::GenericValue(rapidjson::kObjectType), modinfoDoc.GetAllocator()); @@ -494,27 +579,27 @@ void ModManager::LoadMods() buffer.Clear(); rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); modinfoDoc.Accept(writer); - g_MasterServerManager->m_ownModInfoJson = std::string(buffer.GetString()); + g_pMasterServerManager->m_sOwnModInfoJson = std::string(buffer.GetString()); - m_hasLoadedMods = true; + m_bHasLoadedMods = true; } void ModManager::UnloadMods() { // clean up stuff from mods before we unload - m_modFiles.clear(); + m_ModFiles.clear(); fs::remove_all(GetCompiledAssetsPath()); g_CustomAudioManager.ClearAudioOverrides(); - if (!m_hasEnabledModsCfg) - m_enabledModsCfg.SetObject(); + if (!m_bHasEnabledModsCfg) + m_EnabledModsCfg.SetObject(); - for (Mod& mod : m_loadedMods) + for (Mod& mod : m_LoadedMods) { // remove all built kvs for (std::pair<size_t, std::string> kvPaths : mod.KeyValues) - fs::remove(GetCompiledAssetsPath() / fs::path(kvPaths.second).lexically_relative(mod.ModDirectory)); + fs::remove(GetCompiledAssetsPath() / fs::path(kvPaths.second).lexically_relative(mod.m_ModDirectory)); mod.KeyValues.clear(); @@ -522,27 +607,39 @@ void ModManager::UnloadMods() // should we be doing this here or should scripts be doing this manually? // main issue with doing this here is when we reload mods for connecting to a server, we write enabled mods, which isn't necessarily // what we wanna do - if (!m_enabledModsCfg.HasMember(mod.Name.c_str())) - m_enabledModsCfg.AddMember( + if (!m_EnabledModsCfg.HasMember(mod.Name.c_str())) + m_EnabledModsCfg.AddMember( rapidjson_document::StringRefType(mod.Name.c_str()), rapidjson_document::GenericValue(false), - m_enabledModsCfg.GetAllocator()); + m_EnabledModsCfg.GetAllocator()); - m_enabledModsCfg[mod.Name.c_str()].SetBool(mod.Enabled); + m_EnabledModsCfg[mod.Name.c_str()].SetBool(mod.m_bEnabled); } std::ofstream writeStream(GetNorthstarPrefix() + "/enabledmods.json"); rapidjson::OStreamWrapper writeStreamWrapper(writeStream); rapidjson::Writer<rapidjson::OStreamWrapper> writer(writeStreamWrapper); - m_enabledModsCfg.Accept(writer); + m_EnabledModsCfg.Accept(writer); // do we need to dealloc individual entries in m_loadedMods? idk, rework - m_loadedMods.clear(); + m_LoadedMods.clear(); +} + +std::string ModManager::NormaliseModFilePath(const fs::path path) +{ + std::string str = path.lexically_normal().string(); + + // force to lowercase + for (char& c : str) + if (c <= 'Z' && c >= 'A') + c = c - ('Z' - 'z'); + + return str; } void ModManager::CompileAssetsForFile(const char* filename) { - size_t fileHash = STR_HASH(fs::path(filename).lexically_normal().string()); + size_t fileHash = STR_HASH(NormaliseModFilePath(fs::path(filename))); if (fileHash == m_hScriptsRsonHash) BuildScriptsRson(); @@ -551,9 +648,9 @@ void ModManager::CompileAssetsForFile(const char* filename) else { // check if we should build keyvalues, depending on whether any of our mods have patch kvs for this file - for (Mod& mod : m_loadedMods) + for (Mod& mod : m_LoadedMods) { - if (!mod.Enabled) + if (!mod.m_bEnabled) continue; if (mod.KeyValues.find(fileHash) != mod.KeyValues.end()) @@ -565,16 +662,9 @@ void ModManager::CompileAssetsForFile(const char* filename) } } -void ReloadModsCommand(const CCommand& args) -{ - g_ModManager->LoadMods(); -} - -void InitialiseModManager(HMODULE baseAddress) +void ConCommand_reload_mods(const CCommand& args) { - g_ModManager = new ModManager; - - RegisterConCommand("reload_mods", ReloadModsCommand, "idk", FCVAR_NONE); + g_pModManager->LoadMods(); } fs::path GetModFolderPath() @@ -584,4 +674,11 @@ fs::path GetModFolderPath() fs::path GetCompiledAssetsPath() { return fs::path(GetNorthstarPrefix() + COMPILED_ASSETS_SUFFIX); -}
\ No newline at end of file +} + +ON_DLL_LOAD_RELIESON("engine.dll", ModManager, (ConCommand, MasterServer), (CModule module)) +{ + g_pModManager = new ModManager; + + RegisterConCommand("reload_mods", ConCommand_reload_mods, "reloads mods", FCVAR_NONE); +} diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDLL/modmanager.h index 798c2306..f622c675 100644 --- a/NorthstarDedicatedTest/modmanager.h +++ b/NorthstarDLL/modmanager.h @@ -1,14 +1,15 @@ #pragma once #include "convar.h" +#include "memalloc.h" +#include "squirrel.h" + +#include "rapidjson/document.h" #include <string> #include <vector> #include <filesystem> -#include "rapidjson/document.h" -#include "memalloc.h" - -namespace fs = std::filesystem; const std::string MOD_FOLDER_SUFFIX = "/mods"; +const std::string REMOTE_MOD_FOLDER_SUFFIX = "/runtime/remote/mods"; const fs::path MOD_OVERRIDE_DIR = "mod"; const std::string COMPILED_ASSETS_SUFFIX = "/runtime/compiled"; @@ -24,9 +25,6 @@ struct ModConVar struct ModScriptCallback { public: - // would've liked to make it possible to hook arbitrary codecallbacks, but couldn't find a function that calls some ui ones - // std::string HookedCodeCallback; - ScriptContext Context; // called before the codecallback is executed @@ -39,7 +37,7 @@ struct ModScript { public: std::string Path; - std::string RsonRunOn; + std::string RunOn; std::vector<ModScriptCallback> Callbacks; }; @@ -57,14 +55,17 @@ struct ModRpakEntry public: bool m_bAutoLoad; std::string m_sPakName; + std::string m_sLoadAfterPak; }; class Mod { public: // runtime stuff - fs::path ModDirectory; - bool Enabled = true; + bool m_bEnabled = true; + bool m_bWasReadSuccessfully = false; + fs::path m_ModDirectory; + // bool m_bIsRemote; // mod.json stuff: @@ -100,9 +101,7 @@ class Mod std::unordered_map<std::string, std::string> RpakAliases; // paks we alias to other rpaks, e.g. to load sp_crashsite paks on the map mp_crashsite - // other stuff - - bool wasReadSuccessfully = false; + std::unordered_map<std::string, std::string> DependencyConstants; public: Mod(fs::path modPath, char* jsonBuf); @@ -111,39 +110,40 @@ class Mod struct ModOverrideFile { public: - Mod* owningMod; - fs::path path; + Mod* m_pOwningMod; + fs::path m_Path; }; class ModManager { private: - bool m_hasLoadedMods = false; - bool m_hasEnabledModsCfg; - rapidjson_document m_enabledModsCfg; + bool m_bHasLoadedMods = false; + bool m_bHasEnabledModsCfg; + rapidjson_document m_EnabledModsCfg; // precalculated hashes size_t m_hScriptsRsonHash; size_t m_hPdefHash; public: - std::vector<Mod> m_loadedMods; - std::unordered_map<std::string, ModOverrideFile> m_modFiles; + std::vector<Mod> m_LoadedMods; + std::unordered_map<std::string, ModOverrideFile> m_ModFiles; + std::unordered_map<std::string, std::string> m_DependencyConstants; public: ModManager(); void LoadMods(); void UnloadMods(); + std::string NormaliseModFilePath(const fs::path path); void CompileAssetsForFile(const char* filename); - // compile asset type stuff, these are done in files under Mods/Compiled/ + // compile asset type stuff, these are done in files under runtime/compiled/ void BuildScriptsRson(); void TryBuildKeyValues(const char* filename); void BuildPdef(); }; -void InitialiseModManager(HMODULE baseAddress); fs::path GetModFolderPath(); fs::path GetCompiledAssetsPath(); -extern ModManager* g_ModManager;
\ No newline at end of file +extern ModManager* g_pModManager; diff --git a/NorthstarDedicatedTest/ns_version.h b/NorthstarDLL/ns_version.h index d30594fb..d30594fb 100644 --- a/NorthstarDedicatedTest/ns_version.h +++ b/NorthstarDLL/ns_version.h diff --git a/NorthstarDedicatedTest/configurables.cpp b/NorthstarDLL/nsprefix.cpp index 389e6e0b..64a9d1f1 100644 --- a/NorthstarDedicatedTest/configurables.cpp +++ b/NorthstarDLL/nsprefix.cpp @@ -1,13 +1,13 @@ -#include <string> #include "pch.h" -#include "configurables.h" +#include "nsprefix.h" +#include <string> std::string GetNorthstarPrefix() { return NORTHSTAR_FOLDER_PREFIX; } -void parseConfigurables() +void InitialiseNorthstarPrefix() { char* clachar = strstr(GetCommandLineA(), "-profile="); if (clachar) diff --git a/NorthstarDedicatedTest/configurables.h b/NorthstarDLL/nsprefix.h index cc98e15e..9f3087fb 100644 --- a/NorthstarDedicatedTest/configurables.h +++ b/NorthstarDLL/nsprefix.h @@ -3,5 +3,5 @@ static std::string NORTHSTAR_FOLDER_PREFIX; +void InitialiseNorthstarPrefix(); std::string GetNorthstarPrefix(); -void parseConfigurables(); diff --git a/NorthstarDedicatedTest/pch.cpp b/NorthstarDLL/pch.cpp index 64b7eef6..64b7eef6 100644 --- a/NorthstarDedicatedTest/pch.cpp +++ b/NorthstarDLL/pch.cpp diff --git a/NorthstarDedicatedTest/pch.h b/NorthstarDLL/pch.h index 1955071c..e23d6a9b 100644 --- a/NorthstarDedicatedTest/pch.h +++ b/NorthstarDLL/pch.h @@ -8,23 +8,24 @@ #define _WINSOCK_DEPRECATED_NO_WARNINGS // temp because i'm very lazy and want to use inet_addr, remove later #define RAPIDJSON_HAS_STDSTRING 1 -// httplib ssl - // add headers that you want to pre-compile here #include "memalloc.h" -#include <Windows.h> -#include <Psapi.h> +#include <windows.h> +#include <psapi.h> #include <set> #include <map> #include <filesystem> #include <sstream> +namespace fs = std::filesystem; + #include "logging.h" -#include "include/MinHook.h" +#include "MinHook.h" #include "spdlog/spdlog.h" #include "libcurl/include/curl/curl.h" -#include "hookutils.h" +#include "hooks.h" +#include "memory.h" template <typename ReturnType, typename... Args> ReturnType CallVFunc(int index, void* thisPtr, Args... args) { @@ -45,4 +46,4 @@ template <typename T, size_t index, typename... Args> constexpr T CallVFunc_Alt( return CallVFunc_Alt<returnType, index> argsRaw; \ } -#endif
\ No newline at end of file +#endif diff --git a/NorthstarDedicatedTest/pdef.cpp b/NorthstarDLL/pdef.cpp index 86642874..05fba710 100644 --- a/NorthstarDedicatedTest/pdef.cpp +++ b/NorthstarDLL/pdef.cpp @@ -1,8 +1,8 @@ #include "pch.h" #include "modmanager.h" #include "filesystem.h" -#include "hookutils.h" #include "pdef.h" + #include <map> #include <sstream> #include <fstream> @@ -14,11 +14,11 @@ void ModManager::BuildPdef() fs::path MOD_PDEF_PATH = fs::path(GetCompiledAssetsPath() / MOD_PDEF_SUFFIX); fs::remove(MOD_PDEF_PATH); - std::string pdef = ReadVPKOriginalFile(VPK_PDEF_PATH); + std::string pdef = R2::ReadVPKOriginalFile(VPK_PDEF_PATH); - for (Mod& mod : m_loadedMods) + for (Mod& mod : m_LoadedMods) { - if (!mod.Enabled || !mod.Pdiff.size()) + if (!mod.m_bEnabled || !mod.Pdiff.size()) continue; // this code probably isn't going to be pretty lol @@ -107,11 +107,11 @@ void ModManager::BuildPdef() writeStream.close(); ModOverrideFile overrideFile; - overrideFile.owningMod = nullptr; - overrideFile.path = VPK_PDEF_PATH; + overrideFile.m_pOwningMod = nullptr; + overrideFile.m_Path = VPK_PDEF_PATH; - if (m_modFiles.find(VPK_PDEF_PATH) == m_modFiles.end()) - m_modFiles.insert(std::make_pair(VPK_PDEF_PATH, overrideFile)); + if (m_ModFiles.find(VPK_PDEF_PATH) == m_ModFiles.end()) + m_ModFiles.insert(std::make_pair(VPK_PDEF_PATH, overrideFile)); else - m_modFiles[VPK_PDEF_PATH] = overrideFile; -}
\ No newline at end of file + m_ModFiles[VPK_PDEF_PATH] = overrideFile; +} diff --git a/NorthstarDedicatedTest/pdef.h b/NorthstarDLL/pdef.h index a6bffbe4..379e76da 100644 --- a/NorthstarDedicatedTest/pdef.h +++ b/NorthstarDLL/pdef.h @@ -1,4 +1,4 @@ #pragma once const fs::path MOD_PDEF_SUFFIX = "cfg/server/persistent_player_data_version_231.pdef"; -const char* VPK_PDEF_PATH = "cfg/server/persistent_player_data_version_231.pdef";
\ No newline at end of file +const char* VPK_PDEF_PATH = "cfg/server/persistent_player_data_version_231.pdef"; diff --git a/NorthstarDLL/playlist.cpp b/NorthstarDLL/playlist.cpp new file mode 100644 index 00000000..4f34dbb1 --- /dev/null +++ b/NorthstarDLL/playlist.cpp @@ -0,0 +1,130 @@ +#include "pch.h" +#include "playlist.h" +#include "concommand.h" +#include "convar.h" +#include "squirrel.h" +#include "hoststate.h" +#include "serverpresence.h" + +AUTOHOOK_INIT() + +// use the R2 namespace for game funcs +namespace R2 +{ + const char* (*GetCurrentPlaylistName)(); + void (*SetCurrentPlaylist)(const char* pPlaylistName); + void (*SetPlaylistVarOverride)(const char* pVarName, const char* pValue); + const char* (*GetCurrentPlaylistVar)(const char* pVarName, bool bUseOverrides); +} // namespace R2 + +ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride; + +// clang-format off +AUTOHOOK(clc_SetPlaylistVarOverride__Process, engine.dll + 0x222180, +char, __fastcall, (void* a1, void* a2)) +// clang-format on +{ + // the private_match playlist on mp_lobby is the only situation where there should be any legitimate sending of this netmessage + if (!Cvar_ns_use_clc_SetPlaylistVarOverride->GetBool() || strcmp(R2::GetCurrentPlaylistName(), "private_match") || + strcmp(R2::g_pHostState->m_levelName, "mp_lobby")) + return 1; + + return clc_SetPlaylistVarOverride__Process(a1, a2); +} + +// clang-format off +AUTOHOOK(SetCurrentPlaylist, engine.dll + 0x18EB20, +bool, __fastcall, (const char* pPlaylistName)) +// clang-format on +{ + bool bSuccess = SetCurrentPlaylist(pPlaylistName); + + if (bSuccess) + { + spdlog::info("Set playlist to {}", R2::GetCurrentPlaylistName()); + g_pServerPresence->SetPlaylist(R2::GetCurrentPlaylistName()); + } + + return bSuccess; +} + +// clang-format off +AUTOHOOK(SetPlaylistVarOverride, engine.dll + 0x18ED00, +void, __fastcall, (const char* pVarName, const char* pValue)) +// clang-format on +{ + if (strlen(pValue) >= 64) + return; + + SetPlaylistVarOverride(pVarName, pValue); +} + +// clang-format off +AUTOHOOK(GetCurrentPlaylistVar, engine.dll + 0x18C680, +const char*, __fastcall, (const char* pVarName, bool bUseOverrides)) +// clang-format on +{ + if (!bUseOverrides && !strcmp(pVarName, "max_players")) + bUseOverrides = true; + + return GetCurrentPlaylistVar(pVarName, bUseOverrides); +} + +// clang-format off +AUTOHOOK(GetCurrentGamemodeMaxPlayers, engine.dll + 0x18C430, +int, __fastcall, ()) +// clang-format on +{ + const char* pMaxPlayers = R2::GetCurrentPlaylistVar("max_players", 0); + if (!pMaxPlayers) + return GetCurrentGamemodeMaxPlayers(); + + int iMaxPlayers = atoi(pMaxPlayers); + return iMaxPlayers; +} + +void ConCommand_playlist(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + R2::SetCurrentPlaylist(args.Arg(1)); +} + +void ConCommand_setplaylistvaroverride(const CCommand& args) +{ + if (args.ArgC() < 3) + return; + + for (int i = 1; i < args.ArgC(); i += 2) + R2::SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1)); +} + +ON_DLL_LOAD_RELIESON("engine.dll", PlaylistHooks, (ConCommand, ConVar), (CModule module)) +{ + AUTOHOOK_DISPATCH() + + R2::GetCurrentPlaylistName = module.Offset(0x18C640).As<const char* (*)()>(); + R2::SetCurrentPlaylist = module.Offset(0x18EB20).As<void (*)(const char*)>(); + R2::SetPlaylistVarOverride = module.Offset(0x18ED00).As<void (*)(const char*, const char*)>(); + R2::GetCurrentPlaylistVar = module.Offset(0x18C680).As<const char* (*)(const char*, bool)>(); + + // playlist is the name of the command on respawn servers, but we already use setplaylist so can't get rid of it + RegisterConCommand("playlist", ConCommand_playlist, "Sets the current playlist", FCVAR_NONE); + RegisterConCommand("setplaylist", ConCommand_playlist, "Sets the current playlist", FCVAR_NONE); + RegisterConCommand("setplaylistvaroverrides", ConCommand_setplaylistvaroverride, "sets a playlist var override", FCVAR_NONE); + + // note: clc_SetPlaylistVarOverride is pretty insecure, since it allows for entirely arbitrary playlist var overrides to be sent to the + // server, this is somewhat restricted on custom servers to prevent it being done outside of private matches, but ideally it should be + // disabled altogether, since the custom menus won't use it anyway this should only really be accepted if you want vanilla client + // compatibility + Cvar_ns_use_clc_SetPlaylistVarOverride = new ConVar( + "ns_use_clc_SetPlaylistVarOverride", "0", FCVAR_GAMEDLL, "Whether the server should accept clc_SetPlaylistVarOverride messages"); + + // patch to prevent clc_SetPlaylistVarOverride from being able to crash servers if we reach max overrides due to a call to Error (why is + // this possible respawn, wtf) todo: add a warning for this + module.Offset(0x18ED8D).Patch("C3"); + + // patch to allow setplaylistvaroverride to be called before map init on dedicated and private match launched through the game + module.Offset(0x18ED17).NOP(6); +} diff --git a/NorthstarDLL/playlist.h b/NorthstarDLL/playlist.h new file mode 100644 index 00000000..c77b37d9 --- /dev/null +++ b/NorthstarDLL/playlist.h @@ -0,0 +1,10 @@ +#pragma once + +// use the R2 namespace for game funcs +namespace R2 +{ + extern const char* (*GetCurrentPlaylistName)(); + extern void (*SetCurrentPlaylist)(const char* pPlaylistName); + extern void (*SetPlaylistVarOverride)(const char* pVarName, const char* pValue); + extern const char* (*GetCurrentPlaylistVar)(const char* pVarName, bool bUseOverrides); +} // namespace R2 diff --git a/NorthstarDedicatedTest/plugin_abi.h b/NorthstarDLL/plugin_abi.h index 698c33ab..4b176a32 100644 --- a/NorthstarDedicatedTest/plugin_abi.h +++ b/NorthstarDLL/plugin_abi.h @@ -65,4 +65,4 @@ struct PlayerInfo int (*getPlayerInfoChar)(char* out_buf, size_t out_buf_len, PlayerInfoType var); int (*getPlayerInfoInt)(int* out_ptr, PlayerInfoType var); int (*getPlayerInfoBool)(bool* out_ptr, PlayerInfoType var); -};
\ No newline at end of file +}; diff --git a/NorthstarDedicatedTest/plugins.cpp b/NorthstarDLL/plugins.cpp index 70535a32..790439d1 100644 --- a/NorthstarDedicatedTest/plugins.cpp +++ b/NorthstarDLL/plugins.cpp @@ -1,9 +1,11 @@ #include "pch.h" #include "squirrel.h" #include "plugins.h" -#include <chrono> #include "masterserver.h" #include "convar.h" +#include "serverpresence.h" + +#include <chrono> #include <windows.h> /// <summary> @@ -109,31 +111,31 @@ void initGameState() } // string gamemode, string gamemodeName, string map, string mapName, bool connected, bool loading -SQRESULT SQ_UpdateGameStateUI(void* sqvm) +SQRESULT SQ_UpdateGameStateUI(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&gameStateLock); - gameState.map = ClientSq_getstring(sqvm, 1); - gameState.mapDisplayName = ClientSq_getstring(sqvm, 2); - gameState.playlist = ClientSq_getstring(sqvm, 3); - gameState.playlistDisplayName = ClientSq_getstring(sqvm, 4); - gameState.connected = ClientSq_getbool(sqvm, 5); - gameState.loading = ClientSq_getbool(sqvm, 6); + gameState.map = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + gameState.mapDisplayName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 2); + gameState.playlist = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 3); + gameState.playlistDisplayName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 4); + gameState.connected = g_pSquirrel<ScriptContext::UI>->getbool(sqvm, 5); + gameState.loading = g_pSquirrel<ScriptContext::UI>->getbool(sqvm, 6); ReleaseSRWLockExclusive(&gameStateLock); return SQRESULT_NOTNULL; } // int playerCount, int outScore, int secondHighestScore, int highestScore, bool roundBased, int scoreLimit -SQRESULT SQ_UpdateGameStateClient(void* sqvm) +SQRESULT SQ_UpdateGameStateClient(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&gameStateLock); AcquireSRWLockExclusive(&serverInfoLock); - gameState.players = ClientSq_getinteger(sqvm, 1); - serverInfo.maxPlayers = ClientSq_getinteger(sqvm, 2); - gameState.ourScore = ClientSq_getinteger(sqvm, 3); - gameState.secondHighestScore = ClientSq_getinteger(sqvm, 4); - gameState.highestScore = ClientSq_getinteger(sqvm, 5); - serverInfo.roundBased = ClientSq_getbool(sqvm, 6); - serverInfo.scoreLimit = ClientSq_getbool(sqvm, 7); + gameState.players = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1); + serverInfo.maxPlayers = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 2); + gameState.ourScore = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 3); + gameState.secondHighestScore = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 4); + gameState.highestScore = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 5); + serverInfo.roundBased = g_pSquirrel<ScriptContext::CLIENT>->getbool(sqvm, 6); + serverInfo.scoreLimit = g_pSquirrel<ScriptContext::CLIENT>->getbool(sqvm, 7); ReleaseSRWLockExclusive(&gameStateLock); ReleaseSRWLockExclusive(&serverInfoLock); return SQRESULT_NOTNULL; @@ -141,59 +143,59 @@ SQRESULT SQ_UpdateGameStateClient(void* sqvm) // string id, string name, string password, int players, int maxPlayers, string map, string mapDisplayName, string playlist, string // playlistDisplayName -SQRESULT SQ_UpdateServerInfo(void* sqvm) +SQRESULT SQ_UpdateServerInfo(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&gameStateLock); AcquireSRWLockExclusive(&serverInfoLock); - serverInfo.id = ClientSq_getstring(sqvm, 1); - serverInfo.name = ClientSq_getstring(sqvm, 2); - serverInfo.password = ClientSq_getstring(sqvm, 3); - gameState.players = ClientSq_getinteger(sqvm, 4); - serverInfo.maxPlayers = ClientSq_getinteger(sqvm, 5); - gameState.map = ClientSq_getstring(sqvm, 6); - gameState.mapDisplayName = ClientSq_getstring(sqvm, 7); - gameState.playlist = ClientSq_getstring(sqvm, 8); - gameState.playlistDisplayName = ClientSq_getstring(sqvm, 9); + serverInfo.id = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + serverInfo.name = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 2); + serverInfo.password = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 3); + gameState.players = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 4); + serverInfo.maxPlayers = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 5); + gameState.map = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 6); + gameState.mapDisplayName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 7); + gameState.playlist = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 8); + gameState.playlistDisplayName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 9); ReleaseSRWLockExclusive(&gameStateLock); ReleaseSRWLockExclusive(&serverInfoLock); return SQRESULT_NOTNULL; } // int maxPlayers -SQRESULT SQ_UpdateServerInfoBetweenRounds(void* sqvm) +SQRESULT SQ_UpdateServerInfoBetweenRounds(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&serverInfoLock); - serverInfo.id = ClientSq_getstring(sqvm, 1); - serverInfo.name = ClientSq_getstring(sqvm, 2); - serverInfo.password = ClientSq_getstring(sqvm, 3); - serverInfo.maxPlayers = ClientSq_getinteger(sqvm, 4); + serverInfo.id = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 1); + serverInfo.name = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2); + serverInfo.password = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 3); + serverInfo.maxPlayers = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 4); ReleaseSRWLockExclusive(&serverInfoLock); return SQRESULT_NOTNULL; } // float timeInFuture -SQRESULT SQ_UpdateTimeInfo(void* sqvm) +SQRESULT SQ_UpdateTimeInfo(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&serverInfoLock); - serverInfo.endTime = ceil(ClientSq_getfloat(sqvm, 1)); + serverInfo.endTime = ceil(g_pSquirrel<ScriptContext::CLIENT>->getfloat(sqvm, 1)); ReleaseSRWLockExclusive(&serverInfoLock); return SQRESULT_NOTNULL; } // bool loading -SQRESULT SQ_SetConnected(void* sqvm) +SQRESULT SQ_SetConnected(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&gameStateLock); - gameState.loading = ClientSq_getbool(sqvm, 1); + gameState.loading = g_pSquirrel<ScriptContext::UI>->getbool(sqvm, 1); ReleaseSRWLockExclusive(&gameStateLock); return SQRESULT_NOTNULL; } -SQRESULT SQ_UpdateListenServer(void* sqvm) +SQRESULT SQ_UpdateListenServer(HSquirrelVM* sqvm) { AcquireSRWLockExclusive(&serverInfoLock); - serverInfo.id = g_MasterServerManager->m_ownServerId; - serverInfo.password = Cvar_ns_server_password->GetString(); + serverInfo.id = g_pMasterServerManager->m_sOwnServerId; + serverInfo.password = ""; // g_pServerPresence->Cvar_ns_server_password->GetString(); todo this fr ReleaseSRWLockExclusive(&serverInfoLock); return SQRESULT_NOTNULL; } @@ -384,26 +386,26 @@ int getPlayerInfoBool(bool* out_ptr, PlayerInfoType var) return n; } -void InitialisePluginCommands(HMODULE baseAddress) +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", PluginCommands, ClientSquirrel, (CModule module)) { // i swear there's a way to make this not have be run in 2 contexts but i can't figure it out // some funcs i need are just not available in UI or CLIENT - if (g_UISquirrelManager && g_ClientSquirrelManager) + if (g_pSquirrel<ScriptContext::UI> && g_pSquirrel<ScriptContext::CLIENT>) { - g_UISquirrelManager->AddFuncRegistration( + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( "void", "NSUpdateGameStateUI", "string gamemode, string gamemodeName, string map, string mapName, bool connected, bool loading", "", SQ_UpdateGameStateUI); - g_ClientSquirrelManager->AddFuncRegistration( + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( "void", "NSUpdateGameStateClient", "int playerCount, int maxPlayers, int outScore, int secondHighestScore, int highestScore, bool roundBased, int scoreLimit", "", SQ_UpdateGameStateClient); - g_UISquirrelManager->AddFuncRegistration( + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( "void", "NSUpdateServerInfo", "string id, string name, string password, int players, int maxPlayers, string map, string mapDisplayName, string playlist, " @@ -411,10 +413,10 @@ void InitialisePluginCommands(HMODULE baseAddress) "playlistDisplayName", "", SQ_UpdateServerInfo); - g_ClientSquirrelManager->AddFuncRegistration( + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( "void", "NSUpdateServerInfoReload", "int maxPlayers", "", SQ_UpdateServerInfoBetweenRounds); - g_ClientSquirrelManager->AddFuncRegistration("void", "NSUpdateTimeInfo", "float timeInFuture", "", SQ_UpdateTimeInfo); - g_UISquirrelManager->AddFuncRegistration("void", "NSSetLoading", "bool loading", "", SQ_SetConnected); - g_UISquirrelManager->AddFuncRegistration("void", "NSUpdateListenServer", "", "", SQ_UpdateListenServer); + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration("void", "NSUpdateTimeInfo", "float timeInFuture", "", SQ_UpdateTimeInfo); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSSetLoading", "bool loading", "", SQ_SetConnected); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSUpdateListenServer", "", "", SQ_UpdateListenServer); } } diff --git a/NorthstarDedicatedTest/plugins.h b/NorthstarDLL/plugins.h index 27312da9..953801a2 100644 --- a/NorthstarDedicatedTest/plugins.h +++ b/NorthstarDLL/plugins.h @@ -15,5 +15,3 @@ int getPlayerInfoBool(bool* out_ptr, PlayerInfoType var); void initGameState(); void* getPluginObject(PluginObject var); - -void InitialisePluginCommands(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDLL/printcommand.h b/NorthstarDLL/printcommand.h new file mode 100644 index 00000000..6c3ef850 --- /dev/null +++ b/NorthstarDLL/printcommand.h @@ -0,0 +1,6 @@ +#pragma once +#include "concommand.h" + +void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name); +void TryPrintCvarHelpForCommand(const char* pCommand); +void InitialiseCommandPrint(); diff --git a/NorthstarDLL/printcommands.cpp b/NorthstarDLL/printcommands.cpp new file mode 100644 index 00000000..90af1575 --- /dev/null +++ b/NorthstarDLL/printcommands.cpp @@ -0,0 +1,174 @@ +#include "pch.h" +#include "printcommand.h" +#include "convar.h" +#include "concommand.h" + +void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name) +{ + if (!command) + { + spdlog::info("unknown command {}", name); + return; + } + + // temp because command->IsCommand does not currently work + ConVar* cvar = R2::g_pCVar->FindVar(command->m_pszName); + + // build string for flags if not FCVAR_NONE + std::string flagString; + if (command->GetFlags() != FCVAR_NONE) + { + flagString = "( "; + + for (auto& flagPair : g_PrintCommandFlags) + { + if (command->GetFlags() & flagPair.first) + { + // special case, slightly hacky: PRINTABLEONLY is for commands, GAMEDLL_FOR_REMOTE_CLIENTS is for concommands, both have the + // same value + if (flagPair.first == FCVAR_PRINTABLEONLY) + { + if (cvar && !strcmp(flagPair.second, "GAMEDLL_FOR_REMOTE_CLIENTS")) + continue; + + if (!cvar && !strcmp(flagPair.second, "PRINTABLEONLY")) + continue; + } + + flagString += flagPair.second; + flagString += " "; + } + } + + flagString += ") "; + } + + if (cvar) + spdlog::info("\"{}\" = \"{}\" {}- {}", cvar->GetBaseName(), cvar->GetString(), flagString, cvar->GetHelpText()); + else + spdlog::info("\"{}\" {} - {}", command->m_pszName, flagString, command->GetHelpText()); +} + +void TryPrintCvarHelpForCommand(const char* pCommand) +{ + // try to display help text for an inputted command string from the console + int pCommandLen = strlen(pCommand); + char* pCvarStr = new char[pCommandLen]; + strcpy(pCvarStr, pCommand); + + // trim whitespace from right + for (int i = pCommandLen - 1; i; i--) + { + if (isspace(pCvarStr[i])) + pCvarStr[i] = '\0'; + else + break; + } + + // check if we're inputting a cvar, but not setting it at all + ConVar* cvar = R2::g_pCVar->FindVar(pCvarStr); + if (cvar) + PrintCommandHelpDialogue(&cvar->m_ConCommandBase, pCvarStr); + + delete[] pCvarStr; +} + +void ConCommand_help(const CCommand& arg) +{ + if (arg.ArgC() < 2) + { + spdlog::info("Usage: help <cvarname>"); + return; + } + + PrintCommandHelpDialogue(R2::g_pCVar->FindCommandBase(arg.Arg(1)), arg.Arg(1)); +} + +void ConCommand_find(const CCommand& arg) +{ + if (arg.ArgC() < 2) + { + spdlog::info("Usage: find <string> [<string>...]"); + return; + } + + char pTempName[256]; + char pTempSearchTerm[256]; + + for (auto& map : R2::g_pCVar->DumpToMap()) + { + bool bPrintCommand = true; + for (int i = 0; i < arg.ArgC() - 1; i++) + { + // make lowercase to avoid case sensitivity + strncpy_s(pTempName, sizeof(pTempName), map.second->m_pszName, sizeof(pTempName) - 1); + strncpy_s(pTempSearchTerm, sizeof(pTempSearchTerm), arg.Arg(i + 1), sizeof(pTempSearchTerm) - 1); + + for (int i = 0; pTempName[i]; i++) + pTempName[i] = tolower(pTempName[i]); + + for (int i = 0; pTempSearchTerm[i]; i++) + pTempSearchTerm[i] = tolower(pTempSearchTerm[i]); + + if (!strstr(pTempName, pTempSearchTerm)) + { + bPrintCommand = false; + break; + } + } + + if (bPrintCommand) + PrintCommandHelpDialogue(map.second, map.second->m_pszName); + } +} + +void ConCommand_findflags(const CCommand& arg) +{ + if (arg.ArgC() < 2) + { + spdlog::info("Usage: findflags <string>"); + for (auto& flagPair : g_PrintCommandFlags) + spdlog::info(" - {}", flagPair.second); + + return; + } + + // convert input flag to uppercase + char* upperFlag = new char[strlen(arg.Arg(1))]; + strcpy(upperFlag, arg.Arg(1)); + + for (int i = 0; upperFlag[i]; i++) + upperFlag[i] = toupper(upperFlag[i]); + + // resolve flag name => int flags + int resolvedFlag = FCVAR_NONE; + for (auto& flagPair : g_PrintCommandFlags) + { + if (!strcmp(flagPair.second, upperFlag)) + { + resolvedFlag |= flagPair.first; + break; + } + } + + // print cvars + for (auto& map : R2::g_pCVar->DumpToMap()) + { + if (map.second->m_nFlags & resolvedFlag) + PrintCommandHelpDialogue(map.second, map.second->m_pszName); + } + + delete[] upperFlag; +} + +void InitialiseCommandPrint() +{ + RegisterConCommand("find", ConCommand_find, "Find concommands with the specified string in their name/help text.", FCVAR_NONE); + RegisterConCommand("findflags", ConCommand_findflags, "Find concommands by flags.", FCVAR_NONE); + + // help is already a command, so we need to modify the preexisting command to use our func instead + // and clear the flags also + ConCommand* helpCommand = R2::g_pCVar->FindCommand("help"); + helpCommand->m_nFlags = FCVAR_NONE; + helpCommand->m_pCommandCallback = ConCommand_help; +} diff --git a/NorthstarDLL/printmaps.cpp b/NorthstarDLL/printmaps.cpp new file mode 100644 index 00000000..c378daad --- /dev/null +++ b/NorthstarDLL/printmaps.cpp @@ -0,0 +1,168 @@ +#include "pch.h" +#include "printmaps.h" +#include "convar.h" +#include "concommand.h" +#include "modmanager.h" +#include "tier0.h" +#include "r2engine.h" + +#include <filesystem> +#include <regex> + +AUTOHOOK_INIT() + +enum class MapSource_t +{ + VPK, + GAMEDIR, + MOD +}; + +const std::unordered_map<MapSource_t, const char*> PrintMapSource = { + {MapSource_t::VPK, "VPK"}, {MapSource_t::MOD, "MOD"}, {MapSource_t::GAMEDIR, "R2"}}; + +struct MapVPKInfo +{ + std::string name; + std::string parent; + MapSource_t source; +}; + +// our current list of maps in the game +std::vector<MapVPKInfo> vMapList; + +void RefreshMapList() +{ + vMapList.clear(); + + // get modded maps + // TODO: could probably check mod vpks to get mapnames from there too? + for (auto& modFilePair : g_pModManager->m_ModFiles) + { + ModOverrideFile file = modFilePair.second; + if (file.m_Path.extension() == ".bsp" && file.m_Path.parent_path().string() == "maps") // only allow mod maps actually in /maps atm + { + MapVPKInfo& map = vMapList.emplace_back(); + map.name = file.m_Path.stem().string(); + map.parent = file.m_pOwningMod->Name; + map.source = MapSource_t::MOD; + } + } + + // get maps in vpk + { + const int iNumRetailNonMapVpks = 1; + static const char* const ppRetailNonMapVpks[] = { + "englishclient_frontend.bsp.pak000_dir.vpk"}; // don't include mp_common here as it contains mp_lobby + + // matches directory vpks, and captures their map name in the first group + static const std::regex rVpkMapRegex("englishclient_([a-zA-Z_]+)\\.bsp\\.pak000_dir\\.vpk", std::regex::icase); + + for (fs::directory_entry file : fs::directory_iterator("./vpk")) + { + std::string pathString = file.path().filename().string(); + + bool bIsValidMapVpk = true; + for (int i = 0; i < iNumRetailNonMapVpks; i++) + { + if (!pathString.compare(ppRetailNonMapVpks[i])) + { + bIsValidMapVpk = false; + break; + } + } + + if (!bIsValidMapVpk) + continue; + + // run our map vpk regex on the filename + std::smatch match; + std::regex_match(pathString, match, rVpkMapRegex); + + if (match.length() < 2) + continue; + + std::string mapName = match[1].str(); + // special case: englishclient_mp_common contains mp_lobby, so hardcode the name here + if (mapName == "mp_common") + mapName = "mp_lobby"; + + MapVPKInfo& map = vMapList.emplace_back(); + map.name = mapName; + map.parent = pathString; + map.source = MapSource_t::VPK; + } + } + + // get maps in game dir + for (fs::directory_entry file : fs::directory_iterator(fmt::format("{}/maps", R2::g_pModName))) + { + if (file.path().extension() == ".bsp") + { + MapVPKInfo& map = vMapList.emplace_back(); + map.name = file.path().stem().string(); + map.parent = "R2"; + map.source = MapSource_t::GAMEDIR; + } + } +} + +// clang-format off +AUTOHOOK(_Host_Map_f_CompletionFunc, engine.dll + 0x161AE0, +int, __fastcall, (const char const* cmdname, const char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])) +// clang-format on +{ + // don't update our map list often from this func, only refresh every 10 seconds so we avoid constantly reading fs + static double flLastAutocompleteRefresh = -999; + + if (flLastAutocompleteRefresh + 10.0 < Tier0::Plat_FloatTime()) + { + RefreshMapList(); + flLastAutocompleteRefresh = Tier0::Plat_FloatTime(); + } + + // use a custom autocomplete func for all map loading commands + const int cmdLength = strlen(cmdname); + const char* query = partial + cmdLength; + const int queryLength = strlen(query); + + int numMaps = 0; + for (int i = 0; i < vMapList.size() && numMaps < COMMAND_COMPLETION_MAXITEMS; i++) + { + if (!strncmp(query, vMapList[i].name.c_str(), queryLength)) + { + strcpy(commands[numMaps], cmdname); + strncpy_s( + commands[numMaps++] + cmdLength, + COMMAND_COMPLETION_ITEM_LENGTH, + &vMapList[i].name[0], + COMMAND_COMPLETION_ITEM_LENGTH - cmdLength); + } + } + + return numMaps; +} + +void ConCommand_maps(const CCommand& args) +{ + if (args.ArgC() < 2) + { + spdlog::info("Usage: maps <substring>"); + spdlog::info("maps * for full listing"); + return; + } + + RefreshMapList(); + + for (MapVPKInfo& map : vMapList) // need to figure out a nice way to include parent path without making the formatting awful + if ((*args.Arg(1) == '*' && !args.Arg(1)[1]) || strstr(map.name.c_str(), args.Arg(1))) + spdlog::info("({}) {}", PrintMapSource.at(map.source), map.name); +} + +void InitialiseMapsPrint() +{ + AUTOHOOK_DISPATCH() + + ConCommand* mapsCommand = R2::g_pCVar->FindCommand("maps"); + mapsCommand->m_pCommandCallback = ConCommand_maps; +} diff --git a/NorthstarDLL/printmaps.h b/NorthstarDLL/printmaps.h new file mode 100644 index 00000000..b01761c0 --- /dev/null +++ b/NorthstarDLL/printmaps.h @@ -0,0 +1,2 @@ +#pragma once +void InitialiseMapsPrint(); diff --git a/NorthstarDLL/r2client.cpp b/NorthstarDLL/r2client.cpp new file mode 100644 index 00000000..2e7bd564 --- /dev/null +++ b/NorthstarDLL/r2client.cpp @@ -0,0 +1,20 @@ +#include "pch.h" +#include "r2client.h" + +using namespace R2; + +// use the R2 namespace for game funcs +namespace R2 +{ + char* g_pLocalPlayerUserID; + char* g_pLocalPlayerOriginToken; + GetBaseLocalClientType GetBaseLocalClient; +} // namespace R2 + +ON_DLL_LOAD("engine.dll", R2EngineClient, (CModule module)) +{ + g_pLocalPlayerUserID = module.Offset(0x13F8E688).As<char*>(); + g_pLocalPlayerOriginToken = module.Offset(0x13979C80).As<char*>(); + + GetBaseLocalClient = module.Offset(0x78200).As<GetBaseLocalClientType>(); +} diff --git a/NorthstarDLL/r2client.h b/NorthstarDLL/r2client.h new file mode 100644 index 00000000..64ed6c61 --- /dev/null +++ b/NorthstarDLL/r2client.h @@ -0,0 +1,11 @@ +#pragma once + +// use the R2 namespace for game funcs +namespace R2 +{ + extern char* g_pLocalPlayerUserID; + extern char* g_pLocalPlayerOriginToken; + + typedef void* (*GetBaseLocalClientType)(); + extern GetBaseLocalClientType GetBaseLocalClient; +} // namespace R2 diff --git a/NorthstarDLL/r2engine.cpp b/NorthstarDLL/r2engine.cpp new file mode 100644 index 00000000..11233a2d --- /dev/null +++ b/NorthstarDLL/r2engine.cpp @@ -0,0 +1,36 @@ +#include "pch.h" +#include "r2engine.h" + +using namespace R2; + +// use the R2 namespace for game funcs +namespace R2 +{ + Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer; + Cbuf_AddTextType Cbuf_AddText; + Cbuf_ExecuteType Cbuf_Execute; + + CEngine* g_pEngine; + + void (*CBaseClient__Disconnect)(void* self, uint32_t unknownButAlways1, const char* reason, ...); + CBaseClient* g_pClientArray; + + server_state_t* g_pServerState; + + char* g_pModName = + nullptr; // we cant set this up here atm since we dont have an offset to it in engine, instead we store it in IsRespawnMod +} // namespace R2 + +ON_DLL_LOAD("engine.dll", R2Engine, (CModule module)) +{ + Cbuf_GetCurrentPlayer = module.Offset(0x120630).As<Cbuf_GetCurrentPlayerType>(); + Cbuf_AddText = module.Offset(0x1203B0).As<Cbuf_AddTextType>(); + Cbuf_Execute = module.Offset(0x1204B0).As<Cbuf_ExecuteType>(); + + g_pEngine = module.Offset(0x7D70C8).Deref().As<CEngine*>(); + + CBaseClient__Disconnect = module.Offset(0x1012C0).As<void (*)(void*, uint32_t, const char*, ...)>(); + g_pClientArray = module.Offset(0x12A53F90).As<CBaseClient*>(); + + g_pServerState = module.Offset(0x12A53D48).As<server_state_t*>(); +} diff --git a/NorthstarDLL/r2engine.h b/NorthstarDLL/r2engine.h new file mode 100644 index 00000000..5566f339 --- /dev/null +++ b/NorthstarDLL/r2engine.h @@ -0,0 +1,199 @@ +#pragma once + +// use the R2 namespace for game funcs +namespace R2 +{ + // Cbuf + enum class ECommandTarget_t + { + CBUF_FIRST_PLAYER = 0, + CBUF_LAST_PLAYER = 1, // MAX_SPLITSCREEN_CLIENTS - 1, MAX_SPLITSCREEN_CLIENTS = 2 + CBUF_SERVER = CBUF_LAST_PLAYER + 1, + + CBUF_COUNT, + }; + + enum class cmd_source_t + { + // Added to the console buffer by gameplay code. Generally unrestricted. + kCommandSrcCode, + + // Sent from code via engine->ClientCmd, which is restricted to commands visible + // via FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS. + kCommandSrcClientCmd, + + // Typed in at the console or via a user key-bind. Generally unrestricted, although + // the client will throttle commands sent to the server this way to 16 per second. + kCommandSrcUserInput, + + // Came in over a net connection as a clc_stringcmd + // host_client will be valid during this state. + // + // Restricted to FCVAR_GAMEDLL commands (but not convars) and special non-ConCommand + // server commands hardcoded into gameplay code (e.g. "joingame") + kCommandSrcNetClient, + + // Received from the server as the client + // + // Restricted to commands with FCVAR_SERVER_CAN_EXECUTE + kCommandSrcNetServer, + + // Being played back from a demo file + // + // Not currently restricted by convar flag, but some commands manually ignore calls + // from this source. FIXME: Should be heavily restricted as demo commands can come + // from untrusted sources. + kCommandSrcDemoFile, + + // Invalid value used when cleared + kCommandSrcInvalid = -1 + }; + + typedef ECommandTarget_t (*Cbuf_GetCurrentPlayerType)(); + extern Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer; + + typedef void (*Cbuf_AddTextType)(ECommandTarget_t eTarget, const char* text, cmd_source_t source); + extern Cbuf_AddTextType Cbuf_AddText; + + typedef void (*Cbuf_ExecuteType)(); + extern Cbuf_ExecuteType Cbuf_Execute; + + // CEngine + + enum EngineQuitState + { + QUIT_NOTQUITTING = 0, + QUIT_TODESKTOP, + QUIT_RESTART + }; + + enum class EngineState_t + { + DLL_INACTIVE = 0, // no dll + DLL_ACTIVE, // engine is focused + DLL_CLOSE, // closing down dll + DLL_RESTART, // engine is shutting down but will restart right away + DLL_PAUSED, // engine is paused, can become active from this state + }; + + class CEngine + { + public: + virtual void unknown() {} // unsure if this is where + virtual bool Load(bool dedicated, const char* baseDir) {} + virtual void Unload() {} + virtual void SetNextState(EngineState_t iNextState) {} + virtual EngineState_t GetState() {} + virtual void Frame() {} + virtual double GetFrameTime() {} + virtual float GetCurTime() {} + + EngineQuitState m_nQuitting; + EngineState_t m_nDllState; + EngineState_t m_nNextDllState; + double m_flCurrentTime; + float m_flFrameTime; + double m_flPreviousTime; + float m_flFilteredTime; + float m_flMinFrameTime; // Expected duration of a frame, or zero if it is unlimited. + }; + + extern CEngine* g_pEngine; + + extern void (*CBaseClient__Disconnect)(void* self, uint32_t unknownButAlways1, const char* reason, ...); + +#pragma once + typedef enum + { + NA_NULL = 0, + NA_LOOPBACK, + NA_IP, + } netadrtype_t; + +#pragma pack(push, 1) + typedef struct netadr_s + { + netadrtype_t type; + unsigned char ip[16]; // IPv6 + // IPv4's 127.0.0.1 is [::ffff:127.0.0.1], that is: + // 00 00 00 00 00 00 00 00 00 00 FF FF 7F 00 00 01 + unsigned short port; + } netadr_t; +#pragma pack(pop) + +#pragma pack(push, 1) + typedef struct netpacket_s + { + netadr_t adr; // sender address + // int source; // received source + char unk[10]; + double received_time; + unsigned char* data; // pointer to raw packet data + void* message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer) + char unk2[16]; + int size; + + // bf_read message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer) + // int size; // size in bytes + // int wiresize; // size in bytes before decompression + // bool stream; // was send as stream + // struct netpacket_s* pNext; // for internal use, should be NULL in public + } netpacket_t; +#pragma pack(pop) + + const int PERSISTENCE_MAX_SIZE = 0xD000; + + // note: NOT_READY and READY are the only entries we have here that are defined by the vanilla game + // entries after this are custom and used to determine the source of persistence, e.g. whether it is local or remote + enum class ePersistenceReady : char + { + NOT_READY, + READY = 3, + READY_INSECURE = 3, + READY_REMOTE + }; + +#pragma pack(push, 1) + struct CBaseClient // 0x2D728 bytes + { + char pad0[0x16]; + + // +0x16 + char m_Name[64]; + // +0x56 + + char pad1[0x44A]; + + // +0x4A0 + ePersistenceReady m_iPersistenceReady; + // +0x4A1 + + char pad2[0x59]; + + // +0x4FA + char m_PersistenceBuffer[PERSISTENCE_MAX_SIZE]; + + char pad3[0x2006]; + + // +0xF500 + char m_UID[32]; + // +0xF520 + + char pad4[0x1E208]; + }; +#pragma pack(pop) + + extern CBaseClient* g_pClientArray; + + enum server_state_t + { + ss_dead = 0, // Dead + ss_loading, // Spawning + ss_active, // Running + ss_paused, // Running, but paused + }; + + extern server_state_t* g_pServerState; + + extern char* g_pModName; +} // namespace R2 diff --git a/NorthstarDLL/r2server.cpp b/NorthstarDLL/r2server.cpp new file mode 100644 index 00000000..50cfa239 --- /dev/null +++ b/NorthstarDLL/r2server.cpp @@ -0,0 +1,17 @@ +#include "pch.h" +#include "r2server.h" + +using namespace R2; + +// use the R2 namespace for game funcs +namespace R2 +{ + CBaseEntity* (*Server_GetEntityByIndex)(int index); + CBasePlayer*(__fastcall* UTIL_PlayerByIndex)(int playerIndex); +} // namespace R2 + +ON_DLL_LOAD("server.dll", R2GameServer, (CModule module)) +{ + Server_GetEntityByIndex = module.Offset(0xFB820).As<CBaseEntity* (*)(int)>(); + UTIL_PlayerByIndex = module.Offset(0x26AA10).As<CBasePlayer*(__fastcall*)(int)>(); +} diff --git a/NorthstarDLL/r2server.h b/NorthstarDLL/r2server.h new file mode 100644 index 00000000..58b39a05 --- /dev/null +++ b/NorthstarDLL/r2server.h @@ -0,0 +1,19 @@ +#pragma once + +// use the R2 namespace for game funcs +namespace R2 +{ + // server entity stuff + class CBaseEntity; + extern CBaseEntity* (*Server_GetEntityByIndex)(int index); + +#pragma pack(push, 1) + struct CBasePlayer + { + char pad[88]; + int m_nPlayerIndex; + }; +#pragma pack(pop) + + extern CBasePlayer*(__fastcall* UTIL_PlayerByIndex)(int playerIndex); +} // namespace R2 diff --git a/NorthstarDLL/rpakfilesystem.cpp b/NorthstarDLL/rpakfilesystem.cpp new file mode 100644 index 00000000..b1363589 --- /dev/null +++ b/NorthstarDLL/rpakfilesystem.cpp @@ -0,0 +1,299 @@ +#include "pch.h" +#include "rpakfilesystem.h" +#include "modmanager.h" +#include "dedicated.h" +#include "tier0.h" + +AUTOHOOK_INIT() + +// there are more i'm just too lazy to add +struct PakLoadFuncs +{ + void* unk0[3]; + int (*LoadPakAsync)(const char* pPath, void* unknownSingleton, int flags, void* callback0, void* callback1); + void* unk1[2]; + void* (*UnloadPak)(int iPakHandle, void* callback); + void* unk2[6]; + void* (*LoadFile)(const char* path); // unsure + void* unk3[10]; + void* (*ReadFileAsync)(const char* pPath, void* a2); +}; + +PakLoadFuncs* g_pakLoadApi; + +PakLoadManager* g_pPakLoadManager; +void** pUnknownPakLoadSingleton; + +int PakLoadManager::LoadPakAsync(const char* pPath, const ePakLoadSource nLoadSource) +{ + int nHandle = g_pakLoadApi->LoadPakAsync(pPath, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); + + // set the load source of the pak we just loaded + if (nHandle != -1) + GetPakInfo(nHandle)->m_nLoadSource = nLoadSource; + + return nHandle; +} + +void PakLoadManager::UnloadPak(const int nPakHandle) +{ + g_pakLoadApi->UnloadPak(nPakHandle, nullptr); +} + +void PakLoadManager::UnloadMapPaks() +{ + for (auto& pair : m_vLoadedPaks) + if (pair.second.m_nLoadSource == ePakLoadSource::MAP) + UnloadPak(pair.first); +} + +LoadedPak* PakLoadManager::TrackLoadedPak(ePakLoadSource nLoadSource, int nPakHandle, size_t nPakNameHash) +{ + LoadedPak pak; + pak.m_nLoadSource = nLoadSource; + pak.m_nPakHandle = nPakHandle; + pak.m_nPakNameHash = nPakNameHash; + + m_vLoadedPaks.insert(std::make_pair(nPakHandle, pak)); + return &m_vLoadedPaks.at(nPakHandle); +} + +void PakLoadManager::RemoveLoadedPak(int nPakHandle) +{ + m_vLoadedPaks.erase(nPakHandle); +} + +LoadedPak* PakLoadManager::GetPakInfo(const int nPakHandle) +{ + return &m_vLoadedPaks.at(nPakHandle); +} + +int PakLoadManager::GetPakHandle(const size_t nPakNameHash) +{ + for (auto& pair : m_vLoadedPaks) + if (pair.second.m_nPakNameHash == nPakNameHash) + return pair.first; + + return -1; +} + +int PakLoadManager::GetPakHandle(const char* pPath) +{ + return GetPakHandle(STR_HASH(pPath)); +} + +void* PakLoadManager::LoadFile(const char* path) +{ + return g_pakLoadApi->LoadFile(path); +} + +void HandlePakAliases(char** map) +{ + // convert the pak being loaded to it's aliased one, e.g. aliasing mp_hub_timeshift => sp_hub_timeshift + for (int64_t i = g_pModManager->m_LoadedMods.size() - 1; i > -1; i--) + { + Mod* mod = &g_pModManager->m_LoadedMods[i]; + if (!mod->m_bEnabled) + continue; + + if (mod->RpakAliases.find(*map) != mod->RpakAliases.end()) + { + *map = &mod->RpakAliases[*map][0]; + return; + } + } +} + +void LoadPreloadPaks() +{ + // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + // need to get a relative path of mod to mod folder + fs::path modPakPath("./" / mod.m_ModDirectory / "paks"); + + for (ModRpakEntry& pak : mod.Rpaks) + if (pak.m_bAutoLoad) + g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), ePakLoadSource::CONSTANT); + } +} + +void LoadPostloadPaks(const char* pPath) +{ + // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + // need to get a relative path of mod to mod folder + fs::path modPakPath("./" / mod.m_ModDirectory / "paks"); + + for (ModRpakEntry& pak : mod.Rpaks) + if (pak.m_sLoadAfterPak == pPath) + g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), ePakLoadSource::CONSTANT); + } +} + +void LoadCustomMapPaks(char** pakName, bool* bNeedToFreePakName) +{ + // whether the vanilla game has this rpak + bool bHasOriginalPak = fs::exists(fs::path("r2/paks/Win64/") / *pakName); + + // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + // need to get a relative path of mod to mod folder + fs::path modPakPath("./" / mod.m_ModDirectory / "paks"); + + for (ModRpakEntry& pak : mod.Rpaks) + { + if (!pak.m_bAutoLoad && !pak.m_sPakName.compare(*pakName)) + { + // if the game doesn't have the original pak, let it handle loading this one as if it was the one it was loading originally + if (!bHasOriginalPak) + { + std::string path = (modPakPath / pak.m_sPakName).string(); + *pakName = new char[path.size() + 1]; + strcpy(*pakName, &path[0]); + (*pakName)[path.size()] = '\0'; + + bHasOriginalPak = true; + *bNeedToFreePakName = + true; // we can't free this memory until we're done with the pak, so let whatever's calling this deal with it + } + else + g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), ePakLoadSource::MAP); + } + } + } +} + +// clang-format off +HOOK(LoadPakAsyncHook, LoadPakAsync, +int, __fastcall, (char* pPath, void* unknownSingleton, int flags, void* pCallback0, void* pCallback1)) +// clang-format on +{ + HandlePakAliases(&pPath); + + // dont load the pak if it's currently loaded already + size_t nPathHash = STR_HASH(pPath); + if (g_pPakLoadManager->GetPakHandle(nPathHash) != -1) + return -1; + + bool bNeedToFreePakName = false; + + static bool bShouldLoadPaks = true; + if (bShouldLoadPaks) + { + // make a copy of the path for comparing to determine whether we should load this pak on dedi, before it could get overwritten by + // LoadCustomMapPaks + std::string originalPath(pPath); + + // disable preloading while we're doing this + bShouldLoadPaks = false; + + LoadPreloadPaks(); + LoadCustomMapPaks(&pPath, &bNeedToFreePakName); + + bShouldLoadPaks = true; + + // do this after custom paks load and in bShouldLoadPaks so we only ever call this on the root pakload call + // todo: could probably add some way to flag custom paks to not be loaded on dedicated servers in rpak.json + if (IsDedicatedServer() && (Tier0::CommandLine()->CheckParm("-nopakdedi") || + strncmp(&originalPath[0], "common", 6))) // dedicated only needs common and common_mp + { + if (bNeedToFreePakName) + delete[] pPath; + + spdlog::info("Not loading pak {} for dedicated server", originalPath); + return -1; + } + } + + int iPakHandle = LoadPakAsync(pPath, unknownSingleton, flags, pCallback0, pCallback1); + spdlog::info("LoadPakAsync {} {}", pPath, iPakHandle); + + // trak the pak + g_pPakLoadManager->TrackLoadedPak(ePakLoadSource::UNTRACKED, iPakHandle, nPathHash); + LoadPostloadPaks(pPath); + + if (bNeedToFreePakName) + delete[] pPath; + + return iPakHandle; +} + +// clang-format off +HOOK(UnloadPakHook, UnloadPak, +void*, __fastcall, (int nPakHandle, void* pCallback)) +// clang-format on +{ + // stop tracking the pak + g_pPakLoadManager->RemoveLoadedPak(nPakHandle); + + static bool bShouldUnloadPaks = true; + if (bShouldUnloadPaks) + { + bShouldUnloadPaks = false; + g_pPakLoadManager->UnloadMapPaks(); + bShouldUnloadPaks = true; + } + + spdlog::info("UnloadPak {}", nPakHandle); + return UnloadPak(nPakHandle, pCallback); +} + +// we hook this exclusively for resolving stbsp paths, but seemingly it's also used for other stuff like vpk, rpak, mprj and starpak loads +// tbh this actually might be for memory mapped files or something, would make sense i think +// clang-format off +HOOK(ReadFileAsyncHook, ReadFileAsync, +void*, __fastcall, (const char* pPath, void* pCallback)) +// clang-format on +{ + fs::path path(pPath); + char* allocatedNewPath = nullptr; + + if (path.extension() == ".stbsp") + { + fs::path filename = path.filename(); + spdlog::info("LoadStreamBsp: {}", filename.string()); + + // resolve modded stbsp path so we can load mod stbsps + auto modFile = g_pModManager->m_ModFiles.find(g_pModManager->NormaliseModFilePath(fs::path("maps" / filename))); + if (modFile != g_pModManager->m_ModFiles.end()) + { + // need to allocate a new string for this + std::string newPath = (modFile->second.m_pOwningMod->m_ModDirectory / "mod" / modFile->second.m_Path).string(); + allocatedNewPath = new char[newPath.size() + 1]; + strncpy_s(allocatedNewPath, newPath.size() + 1, newPath.c_str(), newPath.size()); + pPath = allocatedNewPath; + } + } + + void* ret = ReadFileAsync(pPath, pCallback); + if (allocatedNewPath) + delete[] allocatedNewPath; + + return ret; +} + +ON_DLL_LOAD("engine.dll", RpakFilesystem, (CModule module)) +{ + AUTOHOOK_DISPATCH(); + + g_pPakLoadManager = new PakLoadManager; + + g_pakLoadApi = module.Offset(0x5BED78).Deref().As<PakLoadFuncs*>(); + pUnknownPakLoadSingleton = module.Offset(0x7C5E20).As<void**>(); + + LoadPakAsyncHook.Dispatch(g_pakLoadApi->LoadPakAsync); + UnloadPakHook.Dispatch(g_pakLoadApi->UnloadPak); + ReadFileAsyncHook.Dispatch(g_pakLoadApi->ReadFileAsync); +} diff --git a/NorthstarDLL/rpakfilesystem.h b/NorthstarDLL/rpakfilesystem.h new file mode 100644 index 00000000..3f608dba --- /dev/null +++ b/NorthstarDLL/rpakfilesystem.h @@ -0,0 +1,39 @@ +#pragma once + +enum class ePakLoadSource +{ + UNTRACKED = -1, // not a pak we loaded, we shouldn't touch this one + + CONSTANT, // should be loaded at all times + MAP // loaded from a map, should be unloaded when the map is unloaded +}; + +struct LoadedPak +{ + ePakLoadSource m_nLoadSource; + int m_nPakHandle; + size_t m_nPakNameHash; +}; + +class PakLoadManager +{ + private: + std::map<int, LoadedPak> m_vLoadedPaks {}; + std::unordered_map<size_t, int> m_HashToPakHandle {}; + + public: + int LoadPakAsync(const char* pPath, const ePakLoadSource nLoadSource); + void UnloadPak(const int nPakHandle); + void UnloadMapPaks(); + void* LoadFile(const char* path); // this is a guess + + LoadedPak* TrackLoadedPak(ePakLoadSource nLoadSource, int nPakHandle, size_t nPakNameHash); + void RemoveLoadedPak(int nPakHandle); + + LoadedPak* GetPakInfo(const int nPakHandle); + + int GetPakHandle(const size_t nPakNameHash); + int GetPakHandle(const char* pPath); +}; + +extern PakLoadManager* g_pPakLoadManager; diff --git a/NorthstarDLL/runframe.cpp b/NorthstarDLL/runframe.cpp new file mode 100644 index 00000000..eb401f51 --- /dev/null +++ b/NorthstarDLL/runframe.cpp @@ -0,0 +1,20 @@ +#include "pch.h" +#include "r2engine.h" +#include "r2server.h" +#include "hoststate.h" +#include "serverpresence.h" + +AUTOHOOK_INIT() + +// clang-format off +AUTOHOOK(CEngine__Frame, engine.dll + 0x1C8650, +void, __fastcall, (R2::CEngine* self)) +// clang-format on +{ + CEngine__Frame(self); +} + +ON_DLL_LOAD("engine.dll", RunFrame, (CModule module)) +{ + AUTOHOOK_DISPATCH() +} diff --git a/NorthstarDLL/scriptbrowserhooks.cpp b/NorthstarDLL/scriptbrowserhooks.cpp new file mode 100644 index 00000000..df4014de --- /dev/null +++ b/NorthstarDLL/scriptbrowserhooks.cpp @@ -0,0 +1,25 @@ +#include "pch.h" + +AUTOHOOK_INIT() + +bool* bIsOriginOverlayEnabled; + +// clang-format off +AUTOHOOK(OpenExternalWebBrowser, engine.dll + 0x184E40, +void, __fastcall, (char* pUrl, char flags)) +// clang-format on +{ + bool bIsOriginOverlayEnabledOriginal = *bIsOriginOverlayEnabled; + if (flags & 2 && !strncmp(pUrl, "http", 4)) // custom force external browser flag + *bIsOriginOverlayEnabled = false; // if this bool is false, game will use an external browser rather than the origin overlay one + + OpenExternalWebBrowser(pUrl, flags); + *bIsOriginOverlayEnabled = bIsOriginOverlayEnabledOriginal; +} + +ON_DLL_LOAD_CLIENT("engine.dll", ScriptExternalBrowserHooks, (CModule module)) +{ + AUTOHOOK_DISPATCH() + + bIsOriginOverlayEnabled = module.Offset(0x13978255).As<bool*>(); +} diff --git a/NorthstarDLL/scriptdatatables.cpp b/NorthstarDLL/scriptdatatables.cpp new file mode 100644 index 00000000..fc2be943 --- /dev/null +++ b/NorthstarDLL/scriptdatatables.cpp @@ -0,0 +1,940 @@ +#include "pch.h" +#include "squirrel.h" +#include "rpakfilesystem.h" +#include "convar.h" +#include "dedicated.h" +#include "filesystem.h" +#include "vector.h" +#include "tier0.h" +#include "r2engine.h" +#include <iostream> +#include <sstream> +#include <map> +#include <fstream> +#include <filesystem> + +const uint64_t USERDATA_TYPE_DATATABLE = 0xFFF7FFF700000004; +const uint64_t USERDATA_TYPE_DATATABLE_CUSTOM = 0xFFFCFFFC12345678; + +enum class DatatableType : int +{ + BOOL = 0, + INT, + FLOAT, + VECTOR, + STRING, + ASSET, + UNK_STRING // unknown but deffo a string type +}; + +struct ColumnInfo +{ + char* name; + DatatableType type; + int offset; +}; + +struct Datatable +{ + int numColumns; + int numRows; + ColumnInfo* columnInfo; + char* data; // actually data pointer + int rowInfo; +}; + +ConVar* Cvar_ns_prefer_datatable_from_disk; + +template <ScriptContext context> Datatable* (*SQ_GetDatatableInternal)(HSquirrelVM* sqvm); + +struct CSVData +{ + std::string m_sAssetName; + std::string m_sCSVString; + char* m_pDataBuf; + size_t m_nDataBufSize; + + std::vector<char*> columns; + std::vector<std::vector<char*>> dataPointers; +}; + +std::unordered_map<std::string, CSVData> CSVCache; + +Vector3 StringToVector(char* pString) +{ + Vector3 vRet; + + int length = 0; + while (pString[length]) + { + if ((pString[length] == '<') || (pString[length] == '>')) + pString[length] = '\0'; + length++; + } + + int startOfFloat = 1; + int currentIndex = 1; + + while (pString[currentIndex] && (pString[currentIndex] != ',')) + currentIndex++; + pString[currentIndex] = '\0'; + vRet.x = std::stof(&pString[startOfFloat]); + startOfFloat = ++currentIndex; + + while (pString[currentIndex] && (pString[currentIndex] != ',')) + currentIndex++; + pString[currentIndex] = '\0'; + vRet.y = std::stof(&pString[startOfFloat]); + startOfFloat = ++currentIndex; + + while (pString[currentIndex] && (pString[currentIndex] != ',')) + currentIndex++; + pString[currentIndex] = '\0'; + vRet.z = std::stof(&pString[startOfFloat]); + startOfFloat = ++currentIndex; + + return vRet; +} + +// var function GetDataTable( asset path ) +template <ScriptContext context> SQRESULT SQ_GetDatatable(HSquirrelVM* sqvm) +{ + const char* pAssetName; + g_pSquirrel<context>->getasset(sqvm, 2, &pAssetName); + + if (strncmp(pAssetName, "datatable/", 10)) + { + g_pSquirrel<context>->raiseerror(sqvm, fmt::format("Asset \"{}\" doesn't start with \"datatable/\"", pAssetName).c_str()); + return SQRESULT_ERROR; + } + else if (!Cvar_ns_prefer_datatable_from_disk->GetBool() && g_pPakLoadManager->LoadFile(pAssetName)) + return g_pSquirrel<context>->m_funcOriginals["GetDataTable"](sqvm); + // either we prefer disk datatables, or we're loading a datatable that wasn't found in rpak + else + { + std::string sAssetPath(fmt::format("scripts/{}", pAssetName)); + + // first, check the cache + if (CSVCache.find(pAssetName) != CSVCache.end()) + { + CSVData** pUserdata = g_pSquirrel<context>->createuserdata<CSVData*>(sqvm, sizeof(CSVData*)); + g_pSquirrel<context>->setuserdatatypeid(sqvm, -1, USERDATA_TYPE_DATATABLE_CUSTOM); + *pUserdata = &CSVCache[pAssetName]; + + return SQRESULT_NOTNULL; + } + + // check files on disk + // we don't use .rpak as the extension for on-disk datatables, so we need to replace .rpak with .csv in the filename we're reading + fs::path diskAssetPath("scripts"); + if (fs::path(pAssetName).extension() == ".rpak") + diskAssetPath /= fs::path(pAssetName).remove_filename() / (fs::path(pAssetName).stem().string() + ".csv"); + else + diskAssetPath /= fs::path(pAssetName); + + std::string sDiskAssetPath(diskAssetPath.string()); + if ((*R2::g_pFilesystem)->m_vtable2->FileExists(&(*R2::g_pFilesystem)->m_vtable2, sDiskAssetPath.c_str(), "GAME")) + { + std::string sTableCSV = R2::ReadVPKFile(sDiskAssetPath.c_str()); + if (!sTableCSV.size()) + { + g_pSquirrel<context>->raiseerror(sqvm, fmt::format("Datatable \"{}\" is empty", pAssetName).c_str()); + return SQRESULT_ERROR; + } + + // somewhat shit, but ensure we end with a newline to make parsing easier + if (sTableCSV[sTableCSV.length() - 1] != '\n') + sTableCSV += '\n'; + + CSVData csv; + csv.m_sAssetName = pAssetName; + csv.m_sCSVString = sTableCSV; + csv.m_nDataBufSize = sTableCSV.size(); + csv.m_pDataBuf = new char[csv.m_nDataBufSize]; + memcpy(csv.m_pDataBuf, &sTableCSV[0], csv.m_nDataBufSize); + + // parse the csv + // csvs are essentially comma and newline-deliniated sets of strings for parsing, only thing we need to worry about is quoted + // entries when we parse an element of the csv, rather than allocating an entry for it, we just convert that element to a + // null-terminated string i.e., store the ptr to the first char of it, then make the comma that delinates it a nullchar + + bool bHasColumns = false; + bool bInQuotes = false; + + std::vector<char*> vCurrentRow; + char* pElemStart = csv.m_pDataBuf; + char* pElemEnd = nullptr; + + for (int i = 0; i < csv.m_nDataBufSize; i++) + { + if (csv.m_pDataBuf[i] == '\r' && csv.m_pDataBuf[i + 1] == '\n') + { + if (!pElemEnd) + pElemEnd = csv.m_pDataBuf + i; + + continue; // next iteration can handle the \n + } + + // newline, end of a row + if (csv.m_pDataBuf[i] == '\n') + { + // shouldn't have newline in string + if (bInQuotes) + { + g_pSquirrel<context>->raiseerror(sqvm, "Unexpected \\n in string"); + return SQRESULT_ERROR; + } + + // push last entry to current row + if (pElemEnd) + *pElemEnd = '\0'; + else + csv.m_pDataBuf[i] = '\0'; + + vCurrentRow.push_back(pElemStart); + + // newline, push last line to csv data and go from there + if (!bHasColumns) + { + bHasColumns = true; + csv.columns = vCurrentRow; + } + else + csv.dataPointers.push_back(vCurrentRow); + + vCurrentRow.clear(); + // put start of current element at char after newline + pElemStart = csv.m_pDataBuf + i + 1; + pElemEnd = nullptr; + } + // we're starting or ending a quoted string + else if (csv.m_pDataBuf[i] == '"') + { + // start quoted string + if (!bInQuotes) + { + // shouldn't have quoted strings in column names + if (!bHasColumns) + { + g_pSquirrel<context>->raiseerror(sqvm, "Unexpected \" in column name"); + return SQRESULT_ERROR; + } + + bInQuotes = true; + // put start of current element at char after string begin + pElemStart = csv.m_pDataBuf + i + 1; + } + // end quoted string + else + { + pElemEnd = csv.m_pDataBuf + i; + bInQuotes = false; + } + } + // don't parse commas in quotes + else if (bInQuotes) + { + continue; + } + // comma, push new entry to current row + else if (csv.m_pDataBuf[i] == ',') + { + if (pElemEnd) + *pElemEnd = '\0'; + else + csv.m_pDataBuf[i] = '\0'; + + vCurrentRow.push_back(pElemStart); + // put start of next element at char after comma + pElemStart = csv.m_pDataBuf + i + 1; + pElemEnd = nullptr; + } + } + + // add to cache and return + CSVData** pUserdata = g_pSquirrel<context>->createuserdata<CSVData*>(sqvm, sizeof(CSVData*)); + g_pSquirrel<context>->setuserdatatypeid(sqvm, -1, USERDATA_TYPE_DATATABLE_CUSTOM); + CSVCache[pAssetName] = csv; + *pUserdata = &CSVCache[pAssetName]; + + return SQRESULT_NOTNULL; + } + // the file doesn't exist on disk, check rpak if we haven't already + else if (Cvar_ns_prefer_datatable_from_disk->GetBool() && g_pPakLoadManager->LoadFile(pAssetName)) + return g_pSquirrel<context>->m_funcOriginals["GetDataTable"](sqvm); + // the file doesn't exist at all, error + else + { + g_pSquirrel<context>->raiseerror(sqvm, fmt::format("Datatable {} not found", pAssetName).c_str()); + return SQRESULT_ERROR; + } + } +} + +// int function GetDataTableRowCount( var datatable, string columnName ) +template <ScriptContext context> SQRESULT SQ_GetDataTableColumnByName(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableColumnByName"](sqvm); + + CSVData* csv = *pData; + const char* pColumnName = g_pSquirrel<context>->getstring(sqvm, 2); + + for (int i = 0; i < csv->columns.size(); i++) + { + if (!strcmp(csv->columns[i], pColumnName)) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + // column not found + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowCount( var datatable ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowCount(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDatatableRowCount"](sqvm); + + CSVData* csv = *pData; + g_pSquirrel<context>->pushinteger(sqvm, csv->dataPointers.size()); + return SQRESULT_NOTNULL; +} + +// string function GetDataTableString( var datatable, int row, int col ) +template <ScriptContext context> SQRESULT SQ_GetDataTableString(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableString"](sqvm); + + CSVData* csv = *pData; + const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3); + if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) + { + g_pSquirrel<context>->raiseerror( + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<context>->pushstring(sqvm, csv->dataPointers[nRow][nCol], -1); + return SQRESULT_NOTNULL; +} + +// asset function GetDataTableAsset( var datatable, int row, int col ) +template <ScriptContext context> SQRESULT SQ_GetDataTableAsset(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableAsset"](sqvm); + + CSVData* csv = *pData; + const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3); + if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) + { + g_pSquirrel<context>->raiseerror( + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<context>->pushasset(sqvm, csv->dataPointers[nRow][nCol], -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableInt( var datatable, int row, int col ) +template <ScriptContext context> SQRESULT SQ_GetDataTableInt(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableInt"](sqvm); + + CSVData* csv = *pData; + const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3); + if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) + { + g_pSquirrel<context>->raiseerror( + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<context>->pushinteger(sqvm, std::stoi(csv->dataPointers[nRow][nCol])); + return SQRESULT_NOTNULL; +} + +// float function GetDataTableFloat( var datatable, int row, int col ) +template <ScriptContext context> SQRESULT SQ_GetDataTableFloat(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableFloat"](sqvm); + + CSVData* csv = *pData; + const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3); + if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) + { + g_pSquirrel<context>->raiseerror( + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<context>->pushfloat(sqvm, std::stof(csv->dataPointers[nRow][nCol])); + return SQRESULT_NOTNULL; +} + +// bool function GetDataTableBool( var datatable, int row, int col ) +template <ScriptContext context> SQRESULT SQ_GetDataTableBool(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableBool"](sqvm); + + CSVData* csv = *pData; + const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3); + if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) + { + g_pSquirrel<context>->raiseerror( + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<context>->pushbool(sqvm, std::stoi(csv->dataPointers[nRow][nCol])); + return SQRESULT_NOTNULL; +} + +// vector function GetDataTableVector( var datatable, int row, int col ) +template <ScriptContext context> SQRESULT SQ_GetDataTableVector(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableVector"](sqvm); + + CSVData* csv = *pData; + const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3); + if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) + { + g_pSquirrel<context>->raiseerror( + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<context>->pushvector(sqvm, StringToVector(csv->dataPointers[nRow][nCol])); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowMatchingStringValue( var datatable, int col, string value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowMatchingStringValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingStringValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const char* pStringVal = g_pSquirrel<context>->getstring(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (!strcmp(csv->dataPointers[i][nCol], pStringVal)) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowMatchingAssetValue( var datatable, int col, asset value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowMatchingAssetValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingAssetValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const char* pStringVal; + g_pSquirrel<context>->getasset(sqvm, 3, &pStringVal); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (!strcmp(csv->dataPointers[i][nCol], pStringVal)) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowMatchingFloatValue( var datatable, int col, float value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowMatchingFloatValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingFloatValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const float flFloatVal = g_pSquirrel<context>->getfloat(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (flFloatVal == std::stof(csv->dataPointers[i][nCol])) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowMatchingIntValue( var datatable, int col, int value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowMatchingIntValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingIntValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nIntVal = g_pSquirrel<context>->getinteger(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (nIntVal == std::stoi(csv->dataPointers[i][nCol])) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowMatchingVectorValue( var datatable, int col, vector value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowMatchingVectorValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingVectorValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const Vector3 vVectorVal = g_pSquirrel<context>->getvector(sqvm, 3); + + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (vVectorVal == StringToVector(csv->dataPointers[i][nCol])) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowGreaterThanOrEqualToIntValue( var datatable, int col, int value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowGreaterThanOrEqualToIntValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowGreaterThanOrEqualToIntValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nIntVal = g_pSquirrel<context>->getinteger(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (nIntVal >= std::stoi(csv->dataPointers[i][nCol])) + { + spdlog::info("datatable not loaded"); + g_pSquirrel<context>->pushinteger(sqvm, 1); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowLessThanOrEqualToIntValue( var datatable, int col, int value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowLessThanOrEqualToIntValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowLessThanOrEqualToIntValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const int nIntVal = g_pSquirrel<context>->getinteger(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (nIntVal <= std::stoi(csv->dataPointers[i][nCol])) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowGreaterThanOrEqualToFloatValue( var datatable, int col, float value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowGreaterThanOrEqualToFloatValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowGreaterThanOrEqualToFloatValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const float flFloatVal = g_pSquirrel<context>->getfloat(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (flFloatVal >= std::stof(csv->dataPointers[i][nCol])) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +// int function GetDataTableRowLessThanOrEqualToFloatValue( var datatable, int col, float value ) +template <ScriptContext context> SQRESULT SQ_GetDataTableRowLessThanOrEqualToFloatValue(HSquirrelVM* sqvm) +{ + CSVData** pData; + uint64_t typeId; + g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId); + + if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM) + return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowLessThanOrEqualToFloatValue"](sqvm); + + CSVData* csv = *pData; + int nCol = g_pSquirrel<context>->getinteger(sqvm, 2); + const float flFloatVal = g_pSquirrel<context>->getfloat(sqvm, 3); + for (int i = 0; i < csv->dataPointers.size(); i++) + { + if (flFloatVal <= std::stof(csv->dataPointers[i][nCol])) + { + g_pSquirrel<context>->pushinteger(sqvm, i); + return SQRESULT_NOTNULL; + } + } + + g_pSquirrel<context>->pushinteger(sqvm, -1); + return SQRESULT_NOTNULL; +} + +std::string DataTableToString(Datatable* datatable) +{ + std::string sCSVString; + + // write columns + bool bShouldComma = false; + for (int i = 0; i < datatable->numColumns; i++) + { + if (bShouldComma) + sCSVString += ','; + else + bShouldComma = true; + + sCSVString += datatable->columnInfo[i].name; + } + + // write rows + for (int row = 0; row < datatable->numRows; row++) + { + sCSVString += '\n'; + + bool bShouldComma = false; + for (int col = 0; col < datatable->numColumns; col++) + { + if (bShouldComma) + sCSVString += ','; + else + bShouldComma = true; + + // output typed data + ColumnInfo column = datatable->columnInfo[col]; + const void* pUntypedVal = datatable->data + column.offset + row * datatable->rowInfo; + switch (column.type) + { + case DatatableType::BOOL: + { + sCSVString += *(bool*)pUntypedVal ? '1' : '0'; + break; + } + + case DatatableType::INT: + { + sCSVString += std::to_string(*(int*)pUntypedVal); + break; + } + + case DatatableType::FLOAT: + { + sCSVString += std::to_string(*(float*)pUntypedVal); + break; + } + + case DatatableType::VECTOR: + { + Vector3 pVector((float*)pUntypedVal); + sCSVString += fmt::format("<{},{},{}>", pVector.x, pVector.y, pVector.z); + break; + } + + case DatatableType::STRING: + case DatatableType::ASSET: + case DatatableType::UNK_STRING: + { + sCSVString += fmt::format("\"{}\"", *(char**)pUntypedVal); + break; + } + } + } + } + + return sCSVString; +} + +void DumpDatatable(const char* pDatatablePath) +{ + Datatable* pDatatable = (Datatable*)g_pPakLoadManager->LoadFile(pDatatablePath); + if (!pDatatable) + { + spdlog::error("couldn't load datatable {} (rpak containing it may not be loaded?)", pDatatablePath); + return; + } + + std::string sOutputPath(fmt::format("{}/scripts/datatable/{}.csv", R2::g_pModName, fs::path(pDatatablePath).stem().string())); + std::string sDatatableContents(DataTableToString(pDatatable)); + + fs::create_directories(fs::path(sOutputPath).remove_filename()); + std::ofstream outputStream(sOutputPath); + outputStream.write(sDatatableContents.c_str(), sDatatableContents.size()); + outputStream.close(); + + spdlog::info("dumped datatable {} {} to {}", pDatatablePath, (void*)pDatatable, sOutputPath); +} + +void ConCommand_dump_datatable(const CCommand& args) +{ + if (args.ArgC() < 2) + { + spdlog::info("usage: dump_datatable datatable/tablename.rpak"); + return; + } + + DumpDatatable(args.Arg(1)); +} + +void ConCommand_dump_datatables(const CCommand& args) +{ + // likely not a comprehensive list, might be missing a couple? + static const std::vector<const char*> VANILLA_DATATABLE_PATHS = { + "datatable/burn_meter_rewards.rpak", + "datatable/burn_meter_store.rpak", + "datatable/calling_cards.rpak", + "datatable/callsign_icons.rpak", + "datatable/camo_skins.rpak", + "datatable/default_pilot_loadouts.rpak", + "datatable/default_titan_loadouts.rpak", + "datatable/faction_leaders.rpak", + "datatable/fd_awards.rpak", + "datatable/features_mp.rpak", + "datatable/non_loadout_weapons.rpak", + "datatable/pilot_abilities.rpak", + "datatable/pilot_executions.rpak", + "datatable/pilot_passives.rpak", + "datatable/pilot_properties.rpak", + "datatable/pilot_weapons.rpak", + "datatable/pilot_weapon_features.rpak", + "datatable/pilot_weapon_mods.rpak", + "datatable/pilot_weapon_mods_common.rpak", + "datatable/playlist_items.rpak", + "datatable/titans_mp.rpak", + "datatable/titan_abilities.rpak", + "datatable/titan_executions.rpak", + "datatable/titan_fd_upgrades.rpak", + "datatable/titan_nose_art.rpak", + "datatable/titan_passives.rpak", + "datatable/titan_primary_mods.rpak", + "datatable/titan_primary_mods_common.rpak", + "datatable/titan_primary_weapons.rpak", + "datatable/titan_properties.rpak", + "datatable/titan_skins.rpak", + "datatable/titan_voices.rpak", + "datatable/unlocks_faction_level.rpak", + "datatable/unlocks_fd_titan_level.rpak", + "datatable/unlocks_player_level.rpak", + "datatable/unlocks_random.rpak", + "datatable/unlocks_titan_level.rpak", + "datatable/unlocks_weapon_level_pilot.rpak", + "datatable/weapon_skins.rpak", + "datatable/xp_per_faction_level.rpak", + "datatable/xp_per_fd_titan_level.rpak", + "datatable/xp_per_player_level.rpak", + "datatable/xp_per_titan_level.rpak", + "datatable/xp_per_weapon_level.rpak", + "datatable/faction_leaders_dropship_anims.rpak", + "datatable/score_events.rpak", + "datatable/startpoints.rpak", + "datatable/sp_levels.rpak", + "datatable/community_entries.rpak", + "datatable/spotlight_images.rpak", + "datatable/death_hints_mp.rpak", + "datatable/flightpath_assets.rpak", + "datatable/earn_meter_mp.rpak", + "datatable/battle_chatter_voices.rpak", + "datatable/battle_chatter.rpak", + "datatable/titan_os_conversations.rpak", + "datatable/faction_dialogue.rpak", + "datatable/grunt_chatter_mp.rpak", + "datatable/spectre_chatter_mp.rpak", + "datatable/pain_death_sounds.rpak", + "datatable/caller_ids_mp.rpak"}; + + for (const char* datatable : VANILLA_DATATABLE_PATHS) + DumpDatatable(datatable); +} + +template <ScriptContext context> void RegisterDataTableFunctions() +{ + g_pSquirrel<context>->AddFuncOverride("GetDataTable", SQ_GetDatatable<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableColumnByName", SQ_GetDataTableColumnByName<context>); + g_pSquirrel<context>->AddFuncOverride("GetDatatableRowCount", SQ_GetDataTableRowCount<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableString", SQ_GetDataTableString<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableInt", SQ_GetDataTableInt<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableFloat", SQ_GetDataTableFloat<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableBool", SQ_GetDataTableBool<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableAsset", SQ_GetDataTableAsset<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableVector", SQ_GetDataTableVector<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableRowMatchingStringValue", SQ_GetDataTableRowMatchingStringValue<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableRowMatchingAssetValue", SQ_GetDataTableRowMatchingAssetValue<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableRowMatchingFloatValue", SQ_GetDataTableRowMatchingFloatValue<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableRowMatchingIntValue", SQ_GetDataTableRowMatchingIntValue<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableRowMatchingVectorValue", SQ_GetDataTableRowMatchingVectorValue<context>); + g_pSquirrel<context>->AddFuncOverride( + "GetDataTableRowLessThanOrEqualToFloatValue", SQ_GetDataTableRowLessThanOrEqualToFloatValue<context>); + g_pSquirrel<context>->AddFuncOverride( + "GetDataTableRowGreaterThanOrEqualToFloatValue", SQ_GetDataTableRowGreaterThanOrEqualToFloatValue<context>); + g_pSquirrel<context>->AddFuncOverride("GetDataTableRowLessThanOrEqualToIntValue", SQ_GetDataTableRowLessThanOrEqualToIntValue<context>); + g_pSquirrel<context>->AddFuncOverride( + "GetDataTableRowGreaterThanOrEqualToFloatValue", SQ_GetDataTableRowGreaterThanOrEqualToIntValue<context>); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerScriptDatatables, ServerSquirrel, (CModule module)) +{ + RegisterDataTableFunctions<ScriptContext::SERVER>(); + + SQ_GetDatatableInternal<ScriptContext::SERVER> = module.Offset(0x1250f0).As<Datatable* (*)(HSquirrelVM*)>(); +} + +ON_DLL_LOAD_RELIESON("client.dll", ClientScriptDatatables, ClientSquirrel, (CModule module)) +{ + RegisterDataTableFunctions<ScriptContext::CLIENT>(); + RegisterDataTableFunctions<ScriptContext::UI>(); + + SQ_GetDatatableInternal<ScriptContext::CLIENT> = module.Offset(0x1C9070).As<Datatable* (*)(HSquirrelVM*)>(); + SQ_GetDatatableInternal<ScriptContext::UI> = SQ_GetDatatableInternal<ScriptContext::CLIENT>; +} + +ON_DLL_LOAD_RELIESON("engine.dll", SharedScriptDataTables, ConVar, (CModule module)) +{ + Cvar_ns_prefer_datatable_from_disk = new ConVar( + "ns_prefer_datatable_from_disk", + IsDedicatedServer() && Tier0::CommandLine()->CheckParm("-nopakdedi") ? "1" : "0", + FCVAR_NONE, + "whether to prefer loading datatables from disk, rather than rpak"); + + RegisterConCommand("dump_datatables", ConCommand_dump_datatables, "dumps all datatables from a hardcoded list", FCVAR_NONE); + RegisterConCommand("dump_datatable", ConCommand_dump_datatable, "dump a datatable", FCVAR_NONE); +} diff --git a/NorthstarDLL/scriptjson.cpp b/NorthstarDLL/scriptjson.cpp new file mode 100644 index 00000000..a9767615 --- /dev/null +++ b/NorthstarDLL/scriptjson.cpp @@ -0,0 +1,282 @@ +#include "pch.h" +#include "squirrel.h" + +#include "rapidjson/error/en.h" +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" + +#ifdef _MSC_VER +#undef GetObject // fuck microsoft developers +#endif + +template <ScriptContext context> void +DecodeJsonArray(HSquirrelVM* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr) +{ + g_pSquirrel<context>->newarray(sqvm, 0); + + for (auto& itr : arr->GetArray()) + { + switch (itr.GetType()) + { + case rapidjson::kObjectType: + DecodeJsonTable<context>(sqvm, &itr); + g_pSquirrel<context>->arrayappend(sqvm, -2); + break; + case rapidjson::kArrayType: + DecodeJsonArray<context>(sqvm, &itr); + g_pSquirrel<context>->arrayappend(sqvm, -2); + break; + case rapidjson::kStringType: + g_pSquirrel<context>->pushstring(sqvm, itr.GetString(), -1); + g_pSquirrel<context>->arrayappend(sqvm, -2); + break; + case rapidjson::kTrueType: + case rapidjson::kFalseType: + g_pSquirrel<context>->pushbool(sqvm, itr.GetBool()); + g_pSquirrel<context>->arrayappend(sqvm, -2); + break; + case rapidjson::kNumberType: + if (itr.IsDouble() || itr.IsFloat()) + g_pSquirrel<context>->pushfloat(sqvm, itr.GetFloat()); + else + g_pSquirrel<context>->pushinteger(sqvm, itr.GetInt()); + g_pSquirrel<context>->arrayappend(sqvm, -2); + break; + } + } +} + +template <ScriptContext context> void +DecodeJsonTable(HSquirrelVM* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj) +{ + g_pSquirrel<context>->newtable(sqvm); + + for (auto itr = obj->MemberBegin(); itr != obj->MemberEnd(); itr++) + { + switch (itr->value.GetType()) + { + case rapidjson::kObjectType: + g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1); + DecodeJsonTable<context>( + sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr->value); + g_pSquirrel<context>->newslot(sqvm, -3, false); + break; + case rapidjson::kArrayType: + g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1); + DecodeJsonArray<context>( + sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr->value); + g_pSquirrel<context>->newslot(sqvm, -3, false); + break; + case rapidjson::kStringType: + g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel<context>->pushstring(sqvm, itr->value.GetString(), -1); + + g_pSquirrel<context>->newslot(sqvm, -3, false); + break; + case rapidjson::kTrueType: + case rapidjson::kFalseType: + g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel<context>->pushbool(sqvm, itr->value.GetBool()); + g_pSquirrel<context>->newslot(sqvm, -3, false); + break; + case rapidjson::kNumberType: + if (itr->value.IsDouble() || itr->value.IsFloat()) + { + g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel<context>->pushfloat(sqvm, itr->value.GetFloat()); + } + else + { + g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel<context>->pushinteger(sqvm, itr->value.GetInt()); + } + g_pSquirrel<context>->newslot(sqvm, -3, false); + break; + } + } +} + +template <ScriptContext context> void EncodeJSONTable( + SQTable* table, + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj, + rapidjson::MemoryPoolAllocator<SourceAllocator>& allocator) +{ + for (int i = 0; i < table->_numOfNodes; i++) + { + tableNode* node = &table->_nodes[i]; + if (node->key._Type == OT_STRING) + { + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newObj(rapidjson::kObjectType); + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newArray(rapidjson::kArrayType); + + switch (node->val._Type) + { + case OT_STRING: + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), rapidjson::StringRef(node->val._VAL.asString->_val), allocator); + break; + case OT_INTEGER: + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>( + (int)node->val._VAL.asInteger), + allocator); + break; + case OT_FLOAT: + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(node->val._VAL.asFloat), + allocator); + break; + case OT_BOOL: + if (node->val._VAL.asInteger) + { + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(true), + allocator); + } + else + { + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(false), + allocator); + } + break; + case OT_TABLE: + EncodeJSONTable<context>(node->val._VAL.asTable, &newObj, allocator); + obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newObj, allocator); + break; + case OT_ARRAY: + EncodeJSONArray<context>(node->val._VAL.asArray, &newArray, allocator); + obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newArray, allocator); + break; + default: + spdlog::warn("SQ_EncodeJSON: squirrel type {} not supported", SQTypeNameFromID(node->val._Type)); + break; + } + } + } +} + +template <ScriptContext context> void EncodeJSONArray( + SQArray* arr, + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj, + rapidjson::MemoryPoolAllocator<SourceAllocator>& allocator) +{ + for (int i = 0; i < arr->_usedSlots; i++) + { + SQObject* node = &arr->_values[i]; + + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newObj(rapidjson::kObjectType); + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newArray(rapidjson::kArrayType); + + switch (node->_Type) + { + case OT_STRING: + obj->PushBack(rapidjson::StringRef(node->_VAL.asString->_val), allocator); + break; + case OT_INTEGER: + obj->PushBack( + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>((int)node->_VAL.asInteger), + allocator); + break; + case OT_FLOAT: + obj->PushBack( + rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(node->_VAL.asFloat), + allocator); + break; + case OT_BOOL: + if (node->_VAL.asInteger) + obj->PushBack(rapidjson::StringRef("true"), allocator); + else + obj->PushBack(rapidjson::StringRef("false"), allocator); + break; + case OT_TABLE: + EncodeJSONTable<context>(node->_VAL.asTable, &newObj, allocator); + obj->PushBack(newObj, allocator); + break; + case OT_ARRAY: + EncodeJSONArray<context>(node->_VAL.asArray, &newArray, allocator); + obj->PushBack(newArray, allocator); + break; + default: + spdlog::info("SQ encode Json type {} not supported", SQTypeNameFromID(node->_Type)); + } + } +} + +// table function DecodeJSON( string json, bool fatalParseErrors = false ) +template <ScriptContext context> SQRESULT SQ_DecodeJSON(HSquirrelVM* sqvm) +{ + const char* pJson = g_pSquirrel<context>->getstring(sqvm, 1); + const bool bFatalParseErrors = g_pSquirrel<context>->getbool(sqvm, 2); + + rapidjson_document doc; + doc.Parse(pJson); + if (doc.HasParseError()) + { + g_pSquirrel<context>->newtable(sqvm); + + std::string sErrorString = fmt::format( + "Failed parsing json file: encountered parse error \"{}\" at offset {}", + GetParseError_En(doc.GetParseError()), + doc.GetErrorOffset()); + + if (bFatalParseErrors) + g_pSquirrel<context>->raiseerror(sqvm, sErrorString.c_str()); + else + spdlog::warn(sErrorString); + + return SQRESULT_NOTNULL; + } + + DecodeJsonTable<context>(sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&doc); +} + +// string function EncodeJSON( table data ) +template <ScriptContext context> SQRESULT SQ_EncodeJSON(HSquirrelVM* sqvm) +{ + rapidjson_document doc; + doc.SetObject(); + + // temp until this is just the func parameter type + HSquirrelVM* vm = (HSquirrelVM*)sqvm; + SQTable* table = vm->_stackOfCurrentFunction[1]._VAL.asTable; + EncodeJSONTable<context>(table, &doc, doc.GetAllocator()); + + rapidjson::StringBuffer buffer; + rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); + doc.Accept(writer); + const char* pJsonString = buffer.GetString(); + + g_pSquirrel<context>->pushstring(sqvm, pJsonString, -1); + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientScriptJSON, ClientSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( + "table", + "DecodeJSON", + "string json, bool fatalParseErrors = false", + "converts a json string to a squirrel table", + SQ_DecodeJSON<ScriptContext::CLIENT>); + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( + "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::CLIENT>); + + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON<ScriptContext::UI>); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::UI>); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerScriptJSON, ServerSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON<ScriptContext::SERVER>); + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::SERVER>); +} diff --git a/NorthstarDLL/scriptmainmenupromos.cpp b/NorthstarDLL/scriptmainmenupromos.cpp new file mode 100644 index 00000000..a1277235 --- /dev/null +++ b/NorthstarDLL/scriptmainmenupromos.cpp @@ -0,0 +1,136 @@ +#include "pch.h" +#include "squirrel.h" +#include "masterserver.h" + +// mirror this in script +enum eMainMenuPromoDataProperty +{ + newInfoTitle1, + newInfoTitle2, + newInfoTitle3, + + largeButtonTitle, + largeButtonText, + largeButtonUrl, + largeButtonImageIndex, + + smallButton1Title, + smallButton1Url, + smallButton1ImageIndex, + + smallButton2Title, + smallButton2Url, + smallButton2ImageIndex +}; + +// void function NSRequestCustomMainMenuPromos() +SQRESULT SQ_RequestCustomMainMenuPromos(HSquirrelVM* sqvm) +{ + g_pMasterServerManager->RequestMainMenuPromos(); + return SQRESULT_NULL; +} + +// bool function NSHasCustomMainMenuPromoData() +SQRESULT SQ_HasCustomMainMenuPromoData(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bHasMainMenuPromoData); + return SQRESULT_NOTNULL; +} + +// var function NSGetCustomMainMenuPromoData( int promoDataKey ) +SQRESULT SQ_GetCustomMainMenuPromoData(HSquirrelVM* sqvm) +{ + if (!g_pMasterServerManager->m_bHasMainMenuPromoData) + return SQRESULT_NULL; + + switch (g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1)) + { + case eMainMenuPromoDataProperty::newInfoTitle1: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle1.c_str()); + break; + } + + case eMainMenuPromoDataProperty::newInfoTitle2: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle2.c_str()); + break; + } + + case eMainMenuPromoDataProperty::newInfoTitle3: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle3.c_str()); + break; + } + + case eMainMenuPromoDataProperty::largeButtonTitle: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonTitle.c_str()); + break; + } + + case eMainMenuPromoDataProperty::largeButtonText: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonText.c_str()); + break; + } + + case eMainMenuPromoDataProperty::largeButtonUrl: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonUrl.c_str()); + break; + } + + case eMainMenuPromoDataProperty::largeButtonImageIndex: + { + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonImageIndex); + break; + } + + case eMainMenuPromoDataProperty::smallButton1Title: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1Title.c_str()); + break; + } + + case eMainMenuPromoDataProperty::smallButton1Url: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1Url.c_str()); + break; + } + + case eMainMenuPromoDataProperty::smallButton1ImageIndex: + { + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1ImageIndex); + break; + } + + case eMainMenuPromoDataProperty::smallButton2Title: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2Title.c_str()); + break; + } + + case eMainMenuPromoDataProperty::smallButton2Url: + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2Url.c_str()); + break; + } + + case eMainMenuPromoDataProperty::smallButton2ImageIndex: + { + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2ImageIndex); + break; + } + } + + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptMainMenuPromos, ClientSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSRequestCustomMainMenuPromos", "", "", SQ_RequestCustomMainMenuPromos); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSHasCustomMainMenuPromoData", "", "", SQ_HasCustomMainMenuPromoData); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "var", "NSGetCustomMainMenuPromoData", "int promoDataKey", "", SQ_GetCustomMainMenuPromoData); +} diff --git a/NorthstarDLL/scriptmodmenu.cpp b/NorthstarDLL/scriptmodmenu.cpp new file mode 100644 index 00000000..d2f35285 --- /dev/null +++ b/NorthstarDLL/scriptmodmenu.cpp @@ -0,0 +1,203 @@ +#include "pch.h" +#include "modmanager.h" +#include "squirrel.h" + +// array<string> function NSGetModNames() +SQRESULT SQ_GetModNames(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->newarray(sqvm, 0); + + for (Mod& mod : g_pModManager->m_LoadedMods) + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, mod.Name.c_str()); + g_pSquirrel<ScriptContext::UI>->arrayappend(sqvm, -2); + } + + return SQRESULT_NOTNULL; +} + +// bool function NSIsModEnabled(string modName) +SQRESULT SQ_IsModEnabled(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, mod.m_bEnabled); + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NULL; +} + +// void function NSSetModEnabled(string modName, bool enabled) +SQRESULT SQ_SetModEnabled(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + const SQBool enabled = g_pSquirrel<ScriptContext::UI>->getbool(sqvm, 2); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + mod.m_bEnabled = enabled; + return SQRESULT_NULL; + } + } + + return SQRESULT_NULL; +} + +// string function NSGetModDescriptionByModName(string modName) +SQRESULT SQ_GetModDescription(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, mod.Description.c_str()); + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NULL; +} + +// string function NSGetModVersionByModName(string modName) +SQRESULT SQ_GetModVersion(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, mod.Version.c_str()); + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NULL; +} + +// string function NSGetModDownloadLinkByModName(string modName) +SQRESULT SQ_GetModDownloadLink(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, mod.DownloadLink.c_str()); + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NULL; +} + +// int function NSGetModLoadPriority(string modName) +SQRESULT SQ_GetModLoadPriority(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, mod.LoadPriority); + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NULL; +} + +// bool function NSIsModRequiredOnClient(string modName) +SQRESULT SQ_IsModRequiredOnClient(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, mod.RequiredOnClient); + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NULL; +} + +// array<string> function NSGetModConvarsByModName(string modName) +SQRESULT SQ_GetModConvars(HSquirrelVM* sqvm) +{ + const SQChar* modName = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 1); + g_pSquirrel<ScriptContext::UI>->newarray(sqvm, 0); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + for (ModConVar* cvar : mod.ConVars) + { + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, cvar->Name.c_str()); + g_pSquirrel<ScriptContext::UI>->arrayappend(sqvm, -2); + } + + return SQRESULT_NOTNULL; + } + } + + return SQRESULT_NOTNULL; // return empty array +} + +// void function NSReloadMods() +SQRESULT SQ_ReloadMods(HSquirrelVM* sqvm) +{ + g_pModManager->LoadMods(); + return SQRESULT_NULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptModMenu, ClientSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "array<string>", "NSGetModNames", "", "Returns the names of all loaded mods", SQ_GetModNames); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "bool", "NSIsModEnabled", "string modName", "Returns whether a given mod is enabled", SQ_IsModEnabled); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "void", "NSSetModEnabled", "string modName, bool enabled", "Sets whether a given mod is enabled", SQ_SetModEnabled); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "string", "NSGetModDescriptionByModName", "string modName", "Returns a given mod's description", SQ_GetModDescription); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "string", "NSGetModVersionByModName", "string modName", "Returns a given mod's version", SQ_GetModVersion); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModDownloadLink); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "bool", + "NSIsModRequiredOnClient", + "string modName", + "Returns whether a given mod is required on connecting clients", + SQ_IsModRequiredOnClient); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "int", "NSGetModLoadPriority", "string modName", "Returns a given mod's load priority", SQ_GetModLoadPriority); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "array<string>", "NSGetModConvarsByModName", "string modName", "Returns the names of all a given mod's cvars", SQ_GetModConvars); + + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSReloadMods", "", "Reloads mods", SQ_ReloadMods); +} diff --git a/NorthstarDLL/scriptserverbrowser.cpp b/NorthstarDLL/scriptserverbrowser.cpp new file mode 100644 index 00000000..a361aeb8 --- /dev/null +++ b/NorthstarDLL/scriptserverbrowser.cpp @@ -0,0 +1,458 @@ +#include "pch.h" +#include "squirrel.h" +#include "masterserver.h" +#include "serverauthentication.h" +#include "r2engine.h" +#include "r2client.h" + +// functions for viewing server browser + +// bool function NSIsMasterServerAuthenticated() +SQRESULT SQ_IsMasterServerAuthenticated(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bOriginAuthWithMasterServerDone); + return SQRESULT_NOTNULL; +} + +// void function NSRequestServerList() +SQRESULT SQ_RequestServerList(HSquirrelVM* sqvm) +{ + g_pMasterServerManager->RequestServerList(); + return SQRESULT_NULL; +} + +// bool function NSIsRequestingServerList() +SQRESULT SQ_IsRequestingServerList(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bScriptRequestingServerList); + return SQRESULT_NOTNULL; +} + +// bool function NSMasterServerConnectionSuccessful() +SQRESULT SQ_MasterServerConnectionSuccessful(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bSuccessfullyConnected); + return SQRESULT_NOTNULL; +} + +// int function NSGetServerCount() +SQRESULT SQ_GetServerCount(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers.size()); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerName( int serverIndex ) +SQRESULT SQ_GetServerName(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get name of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].name); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerDescription( int serverIndex ) +SQRESULT SQ_GetServerDescription(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get description of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].description.c_str()); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerMap( int serverIndex ) +SQRESULT SQ_GetServerMap(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get map of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].map); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerPlaylist( int serverIndex ) +SQRESULT SQ_GetServerPlaylist(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get playlist of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].playlist); + return SQRESULT_NOTNULL; +} + +// int function NSGetServerPlayerCount( int serverIndex ) +SQRESULT SQ_GetServerPlayerCount(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get playercount of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].playerCount); + return SQRESULT_NOTNULL; +} + +// int function NSGetServerMaxPlayerCount( int serverIndex ) +SQRESULT SQ_GetServerMaxPlayerCount(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get max playercount of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].maxPlayers); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerID( int serverIndex ) +SQRESULT SQ_GetServerID(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get id of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].id); + return SQRESULT_NOTNULL; +} + +// bool function NSServerRequiresPassword( int serverIndex ) +SQRESULT SQ_ServerRequiresPassword(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get hasPassword of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiresPassword); + return SQRESULT_NOTNULL; +} + +// int function NSGetServerRequiredModsCount( int serverIndex ) +SQRESULT SQ_GetServerRequiredModsCount(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get required mods count of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerRequiredModName( int serverIndex, int modIndex ) +SQRESULT SQ_GetServerRequiredModName(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + SQInteger modIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 2); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get hasPassword of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + if (modIndex >= g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get required mod name of mod index {} when only {} mod are available", + modIndex, + g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring( + sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Name.c_str()); + return SQRESULT_NOTNULL; +} + +// string function NSGetServerRequiredModVersion( int serverIndex, int modIndex ) +SQRESULT SQ_GetServerRequiredModVersion(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + SQInteger modIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 2); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get required mod version of server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + if (modIndex >= g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to get required mod version of mod index {} when only {} mod are available", + modIndex, + g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods.size()) + .c_str()); + return SQRESULT_ERROR; + } + + g_pSquirrel<ScriptContext::UI>->pushstring( + sqvm, g_pMasterServerManager->m_vRemoteServers[serverIndex].requiredMods[modIndex].Version.c_str()); + return SQRESULT_NOTNULL; +} + +// void function NSClearRecievedServerList() +SQRESULT SQ_ClearRecievedServerList(HSquirrelVM* sqvm) +{ + g_pMasterServerManager->ClearServerList(); + return SQRESULT_NULL; +} + +// functions for authenticating with servers + +// void function NSTryAuthWithServer( int serverIndex, string password = "" ) +SQRESULT SQ_TryAuthWithServer(HSquirrelVM* sqvm) +{ + SQInteger serverIndex = g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1); + const SQChar* password = g_pSquirrel<ScriptContext::UI>->getstring(sqvm, 2); + + if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, + fmt::format( + "Tried to auth with server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); + return SQRESULT_ERROR; + } + + // send off persistent data first, don't worry about server/client stuff, since m_additionalPlayerData should only have entries when + // we're a local server note: this seems like it could create a race condition, test later + for (auto& pair : g_pServerAuthentication->m_PlayerAuthenticationData) + g_pServerAuthentication->WritePersistentData(pair.first); + + // do auth + g_pMasterServerManager->AuthenticateWithServer( + R2::g_pLocalPlayerUserID, + g_pMasterServerManager->m_sOwnClientAuthToken, + g_pMasterServerManager->m_vRemoteServers[serverIndex].id, + (char*)password); + + return SQRESULT_NULL; +} + +// bool function NSIsAuthenticatingWithServer() +SQRESULT SQ_IsAuthComplete(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bScriptAuthenticatingWithGameServer); + return SQRESULT_NOTNULL; +} + +// bool function NSWasAuthSuccessful() +SQRESULT SQ_WasAuthSuccessful(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bSuccessfullyAuthenticatedWithGameServer); + return SQRESULT_NOTNULL; +} + +// void function NSConnectToAuthedServer() +SQRESULT SQ_ConnectToAuthedServer(HSquirrelVM* sqvm) +{ + if (!g_pMasterServerManager->m_bHasPendingConnectionInfo) + { + g_pSquirrel<ScriptContext::UI>->raiseerror( + sqvm, fmt::format("Tried to connect to authed server before any pending connection info was available").c_str()); + return SQRESULT_ERROR; + } + + RemoteServerConnectionInfo info = g_pMasterServerManager->m_pendingConnectionInfo; + + // set auth token, then try to connect + // i'm honestly not entirely sure how silentconnect works regarding ports and encryption so using connect for now + R2::Cbuf_AddText( + R2::Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", info.authToken).c_str(), R2::cmd_source_t::kCommandSrcCode); + R2::Cbuf_AddText( + R2::Cbuf_GetCurrentPlayer(), + fmt::format( + "connect {}.{}.{}.{}:{}", + info.ip.S_un.S_un_b.s_b1, + info.ip.S_un.S_un_b.s_b2, + info.ip.S_un.S_un_b.s_b3, + info.ip.S_un.S_un_b.s_b4, + info.port) + .c_str(), + R2::cmd_source_t::kCommandSrcCode); + + g_pMasterServerManager->m_bHasPendingConnectionInfo = false; + return SQRESULT_NULL; +} + +// void function NSTryAuthWithLocalServer() +SQRESULT SQ_TryAuthWithLocalServer(HSquirrelVM* sqvm) +{ + // do auth request + g_pMasterServerManager->AuthenticateWithOwnServer(R2::g_pLocalPlayerUserID, g_pMasterServerManager->m_sOwnClientAuthToken); + + return SQRESULT_NULL; +} + +// void function NSCompleteAuthWithLocalServer() +SQRESULT SQ_CompleteAuthWithLocalServer(HSquirrelVM* sqvm) +{ + // literally just set serverfilter + // note: this assumes we have no authdata other than our own + R2::Cbuf_AddText( + R2::Cbuf_GetCurrentPlayer(), + fmt::format("serverfilter {}", g_pServerAuthentication->m_RemoteAuthenticationData.begin()->first).c_str(), + R2::cmd_source_t::kCommandSrcCode); + + return SQRESULT_NULL; +} + +// string function NSGetAuthFailReason() +SQRESULT SQ_GetAuthFailReason(HSquirrelVM* sqvm) +{ + g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sAuthFailureReason.c_str(), -1); + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptServerBrowser, ClientSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSIsMasterServerAuthenticated", "", "", SQ_IsMasterServerAuthenticated); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSRequestServerList", "", "", SQ_RequestServerList); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSIsRequestingServerList", "", "", SQ_IsRequestingServerList); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "bool", "NSMasterServerConnectionSuccessful", "", "", SQ_MasterServerConnectionSuccessful); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("int", "NSGetServerCount", "", "", SQ_GetServerCount); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSClearRecievedServerList", "", "", SQ_ClearRecievedServerList); + + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerName", "int serverIndex", "", SQ_GetServerName); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerDescription", "int serverIndex", "", SQ_GetServerDescription); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerMap", "int serverIndex", "", SQ_GetServerMap); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerPlaylist", "int serverIndex", "", SQ_GetServerPlaylist); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("int", "NSGetServerPlayerCount", "int serverIndex", "", SQ_GetServerPlayerCount); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "int", "NSGetServerMaxPlayerCount", "int serverIndex", "", SQ_GetServerMaxPlayerCount); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetServerID", "int serverIndex", "", SQ_GetServerID); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "bool", "NSServerRequiresPassword", "int serverIndex", "", SQ_ServerRequiresPassword); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "int", "NSGetServerRequiredModsCount", "int serverIndex", "", SQ_GetServerRequiredModsCount); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "string", "NSGetServerRequiredModName", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModName); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "string", "NSGetServerRequiredModVersion", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModVersion); + + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "void", "NSTryAuthWithServer", "int serverIndex, string password = \"\"", "", SQ_TryAuthWithServer); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSIsAuthenticatingWithServer", "", "", SQ_IsAuthComplete); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("bool", "NSWasAuthSuccessful", "", "", SQ_WasAuthSuccessful); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSConnectToAuthedServer", "", "", SQ_ConnectToAuthedServer); + + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSTryAuthWithLocalServer", "", "", SQ_TryAuthWithLocalServer); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("void", "NSCompleteAuthWithLocalServer", "", "", SQ_CompleteAuthWithLocalServer); + + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration("string", "NSGetAuthFailReason", "", "", SQ_GetAuthFailReason); +} diff --git a/NorthstarDLL/scriptservertoclientstringcommand.cpp b/NorthstarDLL/scriptservertoclientstringcommand.cpp new file mode 100644 index 00000000..5c116973 --- /dev/null +++ b/NorthstarDLL/scriptservertoclientstringcommand.cpp @@ -0,0 +1,25 @@ +#include "pch.h" +#include "squirrel.h" +#include "convar.h" +#include "concommand.h" + +void ConCommand_ns_script_servertoclientstringcommand(const CCommand& arg) +{ + if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM && + g_pSquirrel<ScriptContext::CLIENT>->setupfunc("NSClientCodeCallback_RecievedServerToClientStringCommand") != SQRESULT_ERROR) + { + g_pSquirrel<ScriptContext::CLIENT>->pushstring(g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, arg.ArgS()); + g_pSquirrel<ScriptContext::CLIENT>->call( + g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm, + 1); // todo: doesn't throw or log errors from within this, probably not great behaviour + } +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptServerToClientStringCommand, ClientSquirrel, (CModule module)) +{ + RegisterConCommand( + "ns_script_servertoclientstringcommand", + ConCommand_ns_script_servertoclientstringcommand, + "", + FCVAR_CLIENTDLL | FCVAR_SERVER_CAN_EXECUTE); +} diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDLL/scriptsrson.cpp index 91a12737..1e0ded27 100644 --- a/NorthstarDedicatedTest/scriptsrson.cpp +++ b/NorthstarDLL/scriptsrson.cpp @@ -12,15 +12,12 @@ void ModManager::BuildScriptsRson() fs::path MOD_SCRIPTS_RSON_PATH = fs::path(GetCompiledAssetsPath() / MOD_SCRIPTS_RSON_SUFFIX); fs::remove(MOD_SCRIPTS_RSON_PATH); - // not really important since it doesn't affect actual functionality at all, but the rson we output is really weird - // has a shitload of newlines added, even in places where we don't modify it at all - - std::string scriptsRson = ReadVPKOriginalFile(VPK_SCRIPTS_RSON_PATH); + std::string scriptsRson = R2::ReadVPKOriginalFile(VPK_SCRIPTS_RSON_PATH); scriptsRson += "\n\n// START MODDED SCRIPT CONTENT\n\n"; // newline before we start custom stuff - for (Mod& mod : m_loadedMods) + for (Mod& mod : m_LoadedMods) { - if (!mod.Enabled) + if (!mod.m_bEnabled) continue; // this isn't needed at all, just nice to have imo @@ -38,7 +35,7 @@ void ModManager::BuildScriptsRson() ]*/ scriptsRson += "When: \""; - scriptsRson += script.RsonRunOn; + scriptsRson += script.RunOn; scriptsRson += "\"\n"; scriptsRson += "Scripts:\n[\n\t"; @@ -54,14 +51,14 @@ void ModManager::BuildScriptsRson() writeStream.close(); ModOverrideFile overrideFile; - overrideFile.owningMod = nullptr; - overrideFile.path = VPK_SCRIPTS_RSON_PATH; + overrideFile.m_pOwningMod = nullptr; + overrideFile.m_Path = VPK_SCRIPTS_RSON_PATH; - if (m_modFiles.find(VPK_SCRIPTS_RSON_PATH) == m_modFiles.end()) - m_modFiles.insert(std::make_pair(VPK_SCRIPTS_RSON_PATH, overrideFile)); + if (m_ModFiles.find(VPK_SCRIPTS_RSON_PATH) == m_ModFiles.end()) + m_ModFiles.insert(std::make_pair(VPK_SCRIPTS_RSON_PATH, overrideFile)); else - m_modFiles[VPK_SCRIPTS_RSON_PATH] = overrideFile; + m_ModFiles[VPK_SCRIPTS_RSON_PATH] = overrideFile; // todo: for preventing dupe scripts in scripts.rson, we could actually parse when conditions with the squirrel vm, just need a way to // get a result out of squirrelmanager.ExecuteCode this would probably be the best way to do this, imo -}
\ No newline at end of file +} diff --git a/NorthstarDedicatedTest/scriptsrson.h b/NorthstarDLL/scriptsrson.h index 140db341..5e1d5684 100644 --- a/NorthstarDedicatedTest/scriptsrson.h +++ b/NorthstarDLL/scriptsrson.h @@ -1,4 +1,4 @@ #pragma once const std::string MOD_SCRIPTS_RSON_SUFFIX = "scripts/vscripts/scripts.rson"; -const char* VPK_SCRIPTS_RSON_PATH = "scripts\\vscripts\\scripts.rson";
\ No newline at end of file +const char* VPK_SCRIPTS_RSON_PATH = "scripts\\vscripts\\scripts.rson"; diff --git a/NorthstarDLL/scriptutility.cpp b/NorthstarDLL/scriptutility.cpp new file mode 100644 index 00000000..7a1936cf --- /dev/null +++ b/NorthstarDLL/scriptutility.cpp @@ -0,0 +1,23 @@ +#include "pch.h" +#include "squirrel.h" + +// asset function StringToAsset( string assetName ) +template <ScriptContext context> SQRESULT SQ_StringToAsset(HSquirrelVM* sqvm) +{ + g_pSquirrel<context>->pushasset(sqvm, g_pSquirrel<context>->getstring(sqvm, 1), -1); + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientSharedScriptUtility, ClientSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( + "asset", "StringToAsset", "string assetName", "converts a given string to an asset", SQ_StringToAsset<ScriptContext::CLIENT>); + g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( + "asset", "StringToAsset", "string assetName", "converts a given string to an asset", SQ_StringToAsset<ScriptContext::UI>); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerSharedScriptUtility, ServerSquirrel, (CModule module)) +{ + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "asset", "StringToAsset", "string assetName", "converts a given string to an asset", SQ_StringToAsset<ScriptContext::SERVER>); +}
\ No newline at end of file diff --git a/NorthstarDLL/serverauthentication.cpp b/NorthstarDLL/serverauthentication.cpp new file mode 100644 index 00000000..98054dd7 --- /dev/null +++ b/NorthstarDLL/serverauthentication.cpp @@ -0,0 +1,401 @@ +#include "pch.h" +#include "serverauthentication.h" +#include "limits.h" +#include "cvar.h" +#include "convar.h" +#include "masterserver.h" +#include "serverpresence.h" +#include "hoststate.h" +#include "maxplayers.h" +#include "bansystem.h" +#include "concommand.h" +#include "dedicated.h" +#include "nsprefix.h" +#include "tier0.h" +#include "r2engine.h" +#include "r2client.h" +#include "r2server.h" + +#include "httplib.h" + +#include <fstream> +#include <filesystem> +#include <thread> + +AUTOHOOK_INIT() + +const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!"; + +// global vars +ServerAuthenticationManager* g_pServerAuthentication; + +void ServerAuthenticationManager::StartPlayerAuthServer() +{ + if (m_bRunningPlayerAuthThread) + { + spdlog::warn("ServerAuthenticationManager::StartPlayerAuthServer was called while m_bRunningPlayerAuthThread is true"); + return; + } + + g_pServerPresence->SetAuthPort(Cvar_ns_player_auth_port->GetInt()); // set auth port for presence + m_bRunningPlayerAuthThread = true; + + // listen is a blocking call so thread this + std::thread serverThread( + [this] + { + // this is just a super basic way to verify that servers have ports open, masterserver will try to read this before ensuring + // server is legit + m_PlayerAuthServer.Get( + "/verify", + [](const httplib::Request& request, httplib::Response& response) + { response.set_content(AUTHSERVER_VERIFY_STRING, "text/plain"); }); + + m_PlayerAuthServer.Post( + "/authenticate_incoming_player", + [this](const httplib::Request& request, httplib::Response& response) + { + if (!request.has_param("id") || !request.has_param("authToken") || request.body.size() >= R2::PERSISTENCE_MAX_SIZE || + !request.has_param("serverAuthToken") || + strcmp(g_pMasterServerManager->m_sOwnServerAuthToken, request.get_param_value("serverAuthToken").c_str())) + { + response.set_content("{\"success\":false}", "application/json"); + return; + } + + RemoteAuthData newAuthData {}; + strncpy_s(newAuthData.uid, sizeof(newAuthData.uid), request.get_param_value("id").c_str(), sizeof(newAuthData.uid) - 1); + strncpy_s( + newAuthData.username, + sizeof(newAuthData.username), + request.get_param_value("username").c_str(), + sizeof(newAuthData.username) - 1); + + newAuthData.pdataSize = request.body.size(); + newAuthData.pdata = new char[newAuthData.pdataSize]; + memcpy(newAuthData.pdata, request.body.c_str(), newAuthData.pdataSize); + + std::lock_guard<std::mutex> guard(m_AuthDataMutex); + m_RemoteAuthenticationData.insert(std::make_pair(request.get_param_value("authToken"), newAuthData)); + + response.set_content("{\"success\":true}", "application/json"); + }); + + m_PlayerAuthServer.listen("0.0.0.0", Cvar_ns_player_auth_port->GetInt()); + }); + + serverThread.detach(); +} + +void ServerAuthenticationManager::StopPlayerAuthServer() +{ + if (!m_bRunningPlayerAuthThread) + { + spdlog::warn("ServerAuthenticationManager::StopPlayerAuthServer was called while m_bRunningPlayerAuthThread is false"); + return; + } + + m_bRunningPlayerAuthThread = false; + m_PlayerAuthServer.stop(); +} + +void ServerAuthenticationManager::AddPlayer(R2::CBaseClient* player, const char* pToken) +{ + PlayerAuthenticationData additionalData; + additionalData.pdataSize = m_RemoteAuthenticationData[pToken].pdataSize; + additionalData.usingLocalPdata = player->m_iPersistenceReady == R2::ePersistenceReady::READY_INSECURE; + + m_PlayerAuthenticationData.insert(std::make_pair(player, additionalData)); +} + +void ServerAuthenticationManager::RemovePlayer(R2::CBaseClient* player) +{ + if (m_PlayerAuthenticationData.count(player)) + m_PlayerAuthenticationData.erase(player); +} + +void ServerAuthenticationManager::VerifyPlayerName(R2::CBaseClient* player, char* authToken, char* name) +{ + std::lock_guard<std::mutex> guard(m_AuthDataMutex); + + if (!m_RemoteAuthenticationData.empty() && m_RemoteAuthenticationData.count(std::string(authToken))) + { + RemoteAuthData authData = m_RemoteAuthenticationData[authToken]; + + bool nameAccepted = (!*authData.username || !strcmp(name, authData.username)); + + if (!nameAccepted && g_pMasterServerManager->m_bRequireClientAuth && !CVar_ns_auth_allow_insecure->GetInt()) + { + // limit name length to 64 characters just in case something changes, this technically shouldn't be needed given the master + // server gets usernames from origin but we have it just in case + strncpy_s(name, 64, authData.username, 63); + } + } +} + +bool ServerAuthenticationManager::CheckDuplicateAccounts(R2::CBaseClient* player) +{ + if (m_bAllowDuplicateAccounts) + return true; + + bool bHasUidPlayer = false; + for (int i = 0; i < R2::GetMaxPlayers(); i++) + if (&R2::g_pClientArray[i] != player && !strcmp(R2::g_pClientArray[i].m_UID, player->m_UID)) + return false; + + return true; +} + +bool ServerAuthenticationManager::AuthenticatePlayer(R2::CBaseClient* player, uint64_t uid, char* authToken) +{ + std::string strUid = std::to_string(uid); + std::lock_guard<std::mutex> guard(m_AuthDataMutex); + + // copy uuid + strcpy(player->m_UID, strUid.c_str()); + + bool authFail = true; + if (!m_RemoteAuthenticationData.empty() && m_RemoteAuthenticationData.count(std::string(authToken))) + { + if (!CheckDuplicateAccounts(player)) + return false; + + // use stored auth data + RemoteAuthData authData = m_RemoteAuthenticationData[authToken]; + + if (!strcmp(strUid.c_str(), authData.uid)) // connecting client's uid is the same as auth's uid + { + // if we're resetting let script handle the reset + if (!m_bForceResetLocalPlayerPersistence || strcmp(authData.uid, R2::g_pLocalPlayerUserID)) + { + // copy pdata into buffer + memcpy(player->m_PersistenceBuffer, authData.pdata, authData.pdataSize); + } + + // set persistent data as ready + player->m_iPersistenceReady = R2::ePersistenceReady::READY_REMOTE; + authFail = false; + } + } + + if (authFail) + { + if (CVar_ns_auth_allow_insecure->GetBool()) + { + // set persistent data as ready + // note: actual placeholder persistent data is populated in script with InitPersistentData() + player->m_iPersistenceReady = R2::ePersistenceReady::READY_INSECURE; + return true; + } + else + return false; + } + + return true; // auth successful, client stays on +} + +bool ServerAuthenticationManager::RemovePlayerAuthData(R2::CBaseClient* player) +{ + if (!Cvar_ns_erase_auth_info->GetBool()) // keep auth data forever + return false; + + // hack for special case where we're on a local server, so we erase our own newly created auth data on disconnect + if (m_bNeedLocalAuthForNewgame && !strcmp(player->m_UID, R2::g_pLocalPlayerUserID)) + return false; + + // we don't have our auth token at this point, so lookup authdata by uid + for (auto& auth : m_RemoteAuthenticationData) + { + if (!strcmp(player->m_UID, auth.second.uid)) + { + // pretty sure this is fine, since we don't iterate after the erase + // i think if we iterated after it'd be undefined behaviour tho + std::lock_guard<std::mutex> guard(m_AuthDataMutex); + + delete[] auth.second.pdata; + m_RemoteAuthenticationData.erase(auth.first); + return true; + } + } + + return false; +} + +void ServerAuthenticationManager::WritePersistentData(R2::CBaseClient* player) +{ + if (player->m_iPersistenceReady == R2::ePersistenceReady::READY_REMOTE) + { + g_pMasterServerManager->WritePlayerPersistentData( + player->m_UID, (const char*)player->m_PersistenceBuffer, m_PlayerAuthenticationData[player].pdataSize); + } + else if (CVar_ns_auth_allow_insecure_write->GetBool()) + { + // todo: write pdata to disk here + } +} + +// auth hooks + +// store these in vars so we can use them in CBaseClient::Connect +// this is fine because ptrs won't decay by the time we use this, just don't use it outside of calls from cbaseclient::connectclient +char* pNextPlayerToken; +uint64_t iNextPlayerUid; + +// clang-format off +AUTOHOOK(CBaseServer__ConnectClient, engine.dll + 0x114430, +void*,, ( + void* server, + void* a2, + void* a3, + uint32_t a4, + uint32_t a5, + int32_t a6, + void* a7, + void* a8, + char* serverFilter, + void* a10, + char a11, + void* a12, + char a13, + char a14, + int64_t uid, + uint32_t a16, + uint32_t a17)) +// clang-format on +{ + // auth tokens are sent with serverfilter, can't be accessed from player struct to my knowledge, so have to do this here + pNextPlayerToken = serverFilter; + iNextPlayerUid = uid; + + return CBaseServer__ConnectClient(server, a2, a3, a4, a5, a6, a7, a8, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17); +} + +// clang-format off +AUTOHOOK(CBaseClient__Connect, engine.dll + 0x101740, +bool,, (R2::CBaseClient* self, char* name, void* netchan_ptr_arg, char b_fake_player_arg, void* a5, char* Buffer, void* a7)) +// clang-format on +{ + // try changing name before all else + g_pServerAuthentication->VerifyPlayerName(self, pNextPlayerToken, name); + + // try to auth player, dc if it fails + // we connect regardless of auth, because returning bad from this function can fuck client state p bad + bool ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7); + if (!ret) + return ret; + + if (!g_pBanSystem->IsUIDAllowed(iNextPlayerUid)) + { + R2::CBaseClient__Disconnect(self, 1, "Banned from server"); + return ret; + } + + if (strlen(name) >= 64) // fix for name overflow bug + R2::CBaseClient__Disconnect(self, 1, "Invalid name"); + else if ( + !g_pServerAuthentication->AuthenticatePlayer(self, iNextPlayerUid, pNextPlayerToken) && + g_pServerAuthentication->m_bRequireClientAuth) + R2::CBaseClient__Disconnect(self, 1, "Authentication Failed"); + + g_pServerAuthentication->AddPlayer(self, pNextPlayerToken); + g_pServerLimits->AddPlayer(self); + + return ret; +} + +// clang-format off +AUTOHOOK(CBaseClient__ActivatePlayer, engine.dll + 0x100F80, +void,, (R2::CBaseClient* self)) +// clang-format on +{ + // if we're authed, write our persistent data + // RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call + // (since this func is called on map loads) + if (self->m_iPersistenceReady >= R2::ePersistenceReady::READY && !g_pServerAuthentication->RemovePlayerAuthData(self)) + { + g_pServerAuthentication->m_bForceResetLocalPlayerPersistence = false; + g_pServerAuthentication->WritePersistentData(self); + g_pServerPresence->SetPlayerCount(g_pServerAuthentication->m_PlayerAuthenticationData.size()); + } + + CBaseClient__ActivatePlayer(self); +} + +// clang-format off +AUTOHOOK(_CBaseClient__Disconnect, engine.dll + 0x1012C0, +void,, (R2::CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...)) +// clang-format on +{ + // have to manually format message because can't pass varargs to original func + char buf[1024]; + + va_list va; + va_start(va, pReason); + vsprintf(buf, pReason, va); + va_end(va); + + // this reason is used while connecting to a local server, hacky, but just ignore it + if (strcmp(pReason, "Connection closing")) + { + spdlog::info("Player {} disconnected: \"{}\"", self->m_Name, buf); + + // dcing, write persistent data + if (g_pServerAuthentication->m_PlayerAuthenticationData[self].needPersistenceWriteOnLeave) + g_pServerAuthentication->WritePersistentData(self); + g_pServerAuthentication->RemovePlayerAuthData(self); // won't do anything 99% of the time, but just in case + } + + g_pServerAuthentication->RemovePlayer(self); + g_pServerLimits->RemovePlayer(self); + + g_pServerPresence->SetPlayerCount(g_pServerAuthentication->m_PlayerAuthenticationData.size()); + + _CBaseClient__Disconnect(self, unknownButAlways1, buf); +} + +void ConCommand_ns_resetpersistence(const CCommand& args) +{ + if (*R2::g_pServerState == R2::server_state_t::ss_active) + { + spdlog::error("ns_resetpersistence must be entered from the main menu"); + return; + } + + spdlog::info("resetting persistence on next lobby load..."); + g_pServerAuthentication->m_bForceResetLocalPlayerPersistence = true; +} + +ON_DLL_LOAD_RELIESON("engine.dll", ServerAuthentication, (ConCommand, ConVar), (CModule module)) +{ + AUTOHOOK_DISPATCH() + + g_pServerAuthentication = new ServerAuthenticationManager; + + g_pServerAuthentication->Cvar_ns_player_auth_port = new ConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, ""); + g_pServerAuthentication->Cvar_ns_erase_auth_info = + new ConVar("ns_erase_auth_info", "1", FCVAR_GAMEDLL, "Whether auth info should be erased from this server on disconnect or crash"); + g_pServerAuthentication->CVar_ns_auth_allow_insecure = + new ConVar("ns_auth_allow_insecure", "0", FCVAR_GAMEDLL, "Whether this server will allow unauthenicated players to connect"); + g_pServerAuthentication->CVar_ns_auth_allow_insecure_write = new ConVar( + "ns_auth_allow_insecure_write", + "0", + FCVAR_GAMEDLL, + "Whether the pdata of unauthenticated clients will be written to disk when changed"); + + RegisterConCommand( + "ns_resetpersistence", ConCommand_ns_resetpersistence, "resets your pdata when you next enter the lobby", FCVAR_NONE); + + // patch to disable kicking based on incorrect serverfilter in connectclient, since we repurpose it for use as an auth token + module.Offset(0x114655).Patch("EB"); + + // patch to disable fairfight marking players as cheaters and kicking them + module.Offset(0x101012).Patch("E9 90 00"); + + if (Tier0::CommandLine()->CheckParm("-allowdupeaccounts")) + { + // patch to allow same of multiple account + module.Offset(0x114510).Patch("EB"); + + g_pServerAuthentication->m_bAllowDuplicateAccounts = true; + } +} diff --git a/NorthstarDLL/serverauthentication.h b/NorthstarDLL/serverauthentication.h new file mode 100644 index 00000000..08854ac0 --- /dev/null +++ b/NorthstarDLL/serverauthentication.h @@ -0,0 +1,57 @@ +#pragma once +#include "convar.h" +#include "httplib.h" +#include "r2engine.h" +#include <unordered_map> +#include <string> + +struct RemoteAuthData +{ + char uid[33]; + char username[64]; + + // pdata + char* pdata; + size_t pdataSize; +}; + +struct PlayerAuthenticationData +{ + bool usingLocalPdata; + size_t pdataSize; + bool needPersistenceWriteOnLeave = true; +}; + +class ServerAuthenticationManager +{ + private: + httplib::Server m_PlayerAuthServer; + + public: + ConVar* Cvar_ns_player_auth_port; + ConVar* Cvar_ns_erase_auth_info; + ConVar* CVar_ns_auth_allow_insecure; + ConVar* CVar_ns_auth_allow_insecure_write; + + std::mutex m_AuthDataMutex; + std::unordered_map<std::string, RemoteAuthData> m_RemoteAuthenticationData; + std::unordered_map<R2::CBaseClient*, PlayerAuthenticationData> m_PlayerAuthenticationData; + bool m_bRequireClientAuth = true; + bool m_bAllowDuplicateAccounts = false; + bool m_bRunningPlayerAuthThread = false; + bool m_bNeedLocalAuthForNewgame = false; + bool m_bForceResetLocalPlayerPersistence = false; + + public: + void StartPlayerAuthServer(); + void StopPlayerAuthServer(); + void AddPlayer(R2::CBaseClient* player, const char* pToken); + void RemovePlayer(R2::CBaseClient* player); + bool CheckDuplicateAccounts(R2::CBaseClient* player); + bool AuthenticatePlayer(R2::CBaseClient* player, uint64_t uid, char* authToken); + void VerifyPlayerName(R2::CBaseClient* player, char* authToken, char* name); + bool RemovePlayerAuthData(R2::CBaseClient* player); + void WritePersistentData(R2::CBaseClient* player); +}; + +extern ServerAuthenticationManager* g_pServerAuthentication; diff --git a/NorthstarDLL/serverchathooks.cpp b/NorthstarDLL/serverchathooks.cpp new file mode 100644 index 00000000..1dd05830 --- /dev/null +++ b/NorthstarDLL/serverchathooks.cpp @@ -0,0 +1,183 @@ +#include "pch.h" +#include "serverchathooks.h" +#include "limits.h" +#include "squirrel.h" +#include "r2server.h" + +#include <rapidjson/document.h> +#include <rapidjson/stringbuffer.h> +#include <rapidjson/writer.h> + +AUTOHOOK_INIT() + +class CServerGameDLL; + +class CRecipientFilter +{ + char unknown[58]; +}; + +CServerGameDLL* g_pServerGameDLL; + +void(__fastcall* CServerGameDLL__OnReceivedSayTextMessage)( + CServerGameDLL* self, unsigned int senderPlayerId, const char* text, int channelId); + +void(__fastcall* CRecipientFilter__Construct)(CRecipientFilter* self); +void(__fastcall* CRecipientFilter__Destruct)(CRecipientFilter* self); +void(__fastcall* CRecipientFilter__AddAllPlayers)(CRecipientFilter* self); +void(__fastcall* CRecipientFilter__AddRecipient)(CRecipientFilter* self, const R2::CBasePlayer* player); +void(__fastcall* CRecipientFilter__MakeReliable)(CRecipientFilter* self); + +void(__fastcall* UserMessageBegin)(CRecipientFilter* filter, const char* messagename); +void(__fastcall* MessageEnd)(); +void(__fastcall* MessageWriteByte)(int iValue); +void(__fastcall* MessageWriteString)(const char* sz); +void(__fastcall* MessageWriteBool)(bool bValue); + +bool bShouldCallSayTextHook = false; +// clang-format off +AUTOHOOK(_CServerGameDLL__OnReceivedSayTextMessage, server.dll + 0x1595C0, +void, __fastcall, (CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam)) +// clang-format on +{ + // MiniHook doesn't allow calling the base function outside of anywhere but the hook function. + // To allow bypassing the hook, isSkippingHook can be set. + if (bShouldCallSayTextHook) + { + bShouldCallSayTextHook = false; + _CServerGameDLL__OnReceivedSayTextMessage(self, senderPlayerId, text, isTeam); + return; + } + + // check chat ratelimits + if (!g_pServerLimits->CheckChatLimits(&R2::g_pClientArray[senderPlayerId - 1])) + return; + + if (g_pSquirrel<ScriptContext::SERVER>->setupfunc("CServerGameDLL_ProcessMessageStartThread") != SQRESULT_ERROR) + { + g_pSquirrel<ScriptContext::SERVER>->pushinteger(g_pSquirrel<ScriptContext::SERVER>->m_pSQVM->sqvm, (int)senderPlayerId - 1); + g_pSquirrel<ScriptContext::SERVER>->pushstring(g_pSquirrel<ScriptContext::SERVER>->m_pSQVM->sqvm, text); + g_pSquirrel<ScriptContext::SERVER>->pushbool(g_pSquirrel<ScriptContext::SERVER>->m_pSQVM->sqvm, isTeam); + g_pSquirrel<ScriptContext::SERVER>->call(g_pSquirrel<ScriptContext::SERVER>->m_pSQVM->sqvm, 3); + } + else + _CServerGameDLL__OnReceivedSayTextMessage(self, senderPlayerId, text, isTeam); +} + +void ChatSendMessage(unsigned int playerIndex, const char* text, bool isTeam) +{ + bShouldCallSayTextHook = true; + CServerGameDLL__OnReceivedSayTextMessage( + g_pServerGameDLL, + // Ensure the first bit isn't set, since this indicates a custom message + (playerIndex + 1) & CUSTOM_MESSAGE_INDEX_MASK, + text, + isTeam); +} + +void ChatBroadcastMessage(int fromPlayerIndex, int toPlayerIndex, const char* text, bool isTeam, bool isDead, CustomMessageType messageType) +{ + R2::CBasePlayer* toPlayer = NULL; + if (toPlayerIndex >= 0) + { + toPlayer = R2::UTIL_PlayerByIndex(toPlayerIndex + 1); + if (toPlayer == NULL) + return; + } + + // Build a new string where the first byte is the message type + char sendText[256]; + sendText[0] = (char)messageType; + strncpy_s(sendText + 1, 255, text, 254); + + // Anonymous custom messages use playerId=0, non-anonymous ones use a player ID with the first bit set + unsigned int fromPlayerId = fromPlayerIndex < 0 ? 0 : ((fromPlayerIndex + 1) | CUSTOM_MESSAGE_INDEX_BIT); + + CRecipientFilter filter; + CRecipientFilter__Construct(&filter); + if (toPlayer == NULL) + { + CRecipientFilter__AddAllPlayers(&filter); + } + else + { + CRecipientFilter__AddRecipient(&filter, toPlayer); + } + CRecipientFilter__MakeReliable(&filter); + + UserMessageBegin(&filter, "SayText"); + MessageWriteByte(fromPlayerId); + MessageWriteString(sendText); + MessageWriteBool(isTeam); + MessageWriteBool(isDead); + MessageEnd(); + + CRecipientFilter__Destruct(&filter); +} + +// void function NSSendMessage( int playerIndex, string text, bool isTeam ) +SQRESULT SQ_SendMessage(HSquirrelVM* sqvm) +{ + int playerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 1); + const char* text = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2); + bool isTeam = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 3); + + ChatSendMessage(playerIndex, text, isTeam); + + return SQRESULT_NULL; +} + +// void function NSBroadcastMessage( int fromPlayerIndex, int toPlayerIndex, string text, bool isTeam, bool isDead, int messageType ) +SQRESULT SQ_BroadcastMessage(HSquirrelVM* sqvm) +{ + int fromPlayerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 1); + int toPlayerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 2); + const char* text = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 3); + bool isTeam = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 4); + bool isDead = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 5); + int messageType = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 6); + + if (messageType < 1) + { + g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, fmt::format("Invalid message type {}", messageType).c_str()); + return SQRESULT_ERROR; + } + + ChatBroadcastMessage(fromPlayerIndex, toPlayerIndex, text, isTeam, isDead, (CustomMessageType)messageType); + + return SQRESULT_NULL; +} + +ON_DLL_LOAD("engine.dll", EngineServerChatHooks, (CModule module)) +{ + g_pServerGameDLL = module.Offset(0x13F0AA98).As<CServerGameDLL*>(); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerChatHooks, ServerSquirrel, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(server.dll) + + CServerGameDLL__OnReceivedSayTextMessage = + module.Offset(0x1595C0).As<void(__fastcall*)(CServerGameDLL*, unsigned int, const char*, int)>(); + CRecipientFilter__Construct = module.Offset(0x1E9440).As<void(__fastcall*)(CRecipientFilter*)>(); + CRecipientFilter__Destruct = module.Offset(0x1E9700).As<void(__fastcall*)(CRecipientFilter*)>(); + CRecipientFilter__AddAllPlayers = module.Offset(0x1E9940).As<void(__fastcall*)(CRecipientFilter*)>(); + CRecipientFilter__AddRecipient = module.Offset(0x1E9B30).As<void(__fastcall*)(CRecipientFilter*, const R2::CBasePlayer*)>(); + CRecipientFilter__MakeReliable = module.Offset(0x1EA4E0).As<void(__fastcall*)(CRecipientFilter*)>(); + + UserMessageBegin = module.Offset(0x15C520).As<void(__fastcall*)(CRecipientFilter*, const char*)>(); + MessageEnd = module.Offset(0x158880).As<void(__fastcall*)()>(); + MessageWriteByte = module.Offset(0x158A90).As<void(__fastcall*)(int)>(); + MessageWriteString = module.Offset(0x158D00).As<void(__fastcall*)(const char*)>(); + MessageWriteBool = module.Offset(0x158A00).As<void(__fastcall*)(bool)>(); + + // Chat sending functions + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "void", "NSSendMessage", "int playerIndex, string text, bool isTeam", "", SQ_SendMessage); + g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( + "void", + "NSBroadcastMessage", + "int fromPlayerIndex, int toPlayerIndex, string text, bool isTeam, bool isDead, int messageType", + "", + SQ_BroadcastMessage); +} diff --git a/NorthstarDedicatedTest/serverchathooks.h b/NorthstarDLL/serverchathooks.h index f3425ae6..1d8a806a 100644 --- a/NorthstarDedicatedTest/serverchathooks.h +++ b/NorthstarDLL/serverchathooks.h @@ -23,7 +23,3 @@ void ChatSendMessage(unsigned int playerIndex, const char* text, bool isteam); // messageType: send a specific message type void ChatBroadcastMessage( int fromPlayerIndex, int toPlayerIndex, const char* text, bool isTeam, bool isDead, CustomMessageType messageType); - -void InitialiseServerChatHooks_Engine(HMODULE baseAddress); - -void InitialiseServerChatHooks_Server(HMODULE baseAddress); diff --git a/NorthstarDLL/serverpresence.cpp b/NorthstarDLL/serverpresence.cpp new file mode 100644 index 00000000..9b7b0f1a --- /dev/null +++ b/NorthstarDLL/serverpresence.cpp @@ -0,0 +1,233 @@ +#include "pch.h" +#include "serverpresence.h" +#include "playlist.h" +#include "tier0.h" +#include "convar.h" + +#include <regex> + +ServerPresenceManager* g_pServerPresence; + +ConVar* Cvar_hostname; + +// Convert a hex digit char to integer. +inline int hctod(char c) +{ + if (c >= 'A' && c <= 'F') + { + return c - 'A' + 10; + } + else if (c >= 'a' && c <= 'f') + { + return c - 'a' + 10; + } + else + { + return c - '0'; + } +} + +// This function interprets all 4-hexadecimal-digit unicode codepoint characters like \u4E2D to UTF-8 encoding. +std::string UnescapeUnicode(const std::string& str) +{ + std::string result; + + std::regex r("\\\\u([a-f\\d]{4})", std::regex::icase); + auto matches_begin = std::sregex_iterator(str.begin(), str.end(), r); + auto matches_end = std::sregex_iterator(); + std::smatch last_match; + + for (std::sregex_iterator i = matches_begin; i != matches_end; ++i) + { + last_match = *i; + result.append(last_match.prefix()); + unsigned int cp = 0; + for (int i = 2; i <= 5; ++i) + { + cp *= 16; + cp += hctod(last_match.str()[i]); + } + if (cp <= 0x7F) + { + result.push_back(cp); + } + else if (cp <= 0x7FF) + { + result.push_back((cp >> 6) | 0b11000000 & (~(1 << 5))); + result.push_back(cp & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); + } + else if (cp <= 0xFFFF) + { + result.push_back((cp >> 12) | 0b11100000 & (~(1 << 4))); + result.push_back((cp >> 6) & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); + result.push_back(cp & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); + } + } + + if (!last_match.ready()) + return str; + else + result.append(last_match.suffix()); + + return result; +} + +ServerPresenceManager::ServerPresenceManager() +{ + // clang-format off + // register convars + Cvar_ns_server_presence_update_rate = new ConVar( + "ns_server_presence_update_rate", "5000", FCVAR_GAMEDLL, "How often we update our server's presence on server lists in ms"); + + Cvar_ns_server_name = new ConVar("ns_server_name", "Unnamed Northstar Server", FCVAR_GAMEDLL, "This server's description", false, 0, false, 0, [](ConVar* cvar, const char* pOldValue, float flOldValue) { + g_pServerPresence->SetName(UnescapeUnicode(g_pServerPresence->Cvar_ns_server_name->GetString())); + + // update engine hostname cvar + Cvar_hostname->SetValue(g_pServerPresence->Cvar_ns_server_name->GetString()); + }); + + Cvar_ns_server_desc = new ConVar("ns_server_desc", "Default server description", FCVAR_GAMEDLL, "This server's name", false, 0, false, 0, [](ConVar* cvar, const char* pOldValue, float flOldValue) { + g_pServerPresence->SetDescription(UnescapeUnicode(g_pServerPresence->Cvar_ns_server_desc->GetString())); + }); + + Cvar_ns_server_password = new ConVar("ns_server_password", "", FCVAR_GAMEDLL, "This server's password", false, 0, false, 0, [](ConVar* cvar, const char* pOldValue, float flOldValue) { + g_pServerPresence->SetPassword(g_pServerPresence->Cvar_ns_server_password->GetString()); + }); + + Cvar_ns_report_server_to_masterserver = new ConVar("ns_report_server_to_masterserver", "1", FCVAR_GAMEDLL, "Whether we should report this server to the masterserver"); + Cvar_ns_report_sp_server_to_masterserver = new ConVar("ns_report_sp_server_to_masterserver", "0", FCVAR_GAMEDLL, "Whether we should report this server to the masterserver, when started in singleplayer"); + // clang-format on +} + +void ServerPresenceManager::AddPresenceReporter(ServerPresenceReporter* reporter) +{ + m_vPresenceReporters.push_back(reporter); +} + +void ServerPresenceManager::CreatePresence() +{ + // reset presence fields that rely on runtime server state + // these being: port/auth port, map/playlist name, and playercount/maxplayers + m_ServerPresence.m_iPort = 0; + m_ServerPresence.m_iAuthPort = 0; + + m_ServerPresence.m_iPlayerCount = 0; // this should actually be 0 at this point, so shouldn't need updating later + m_ServerPresence.m_iMaxPlayers = 0; + + memset(m_ServerPresence.m_MapName, 0, sizeof(m_ServerPresence.m_MapName)); + memset(m_ServerPresence.m_PlaylistName, 0, sizeof(m_ServerPresence.m_PlaylistName)); + m_ServerPresence.m_bIsSingleplayerServer = false; + + m_bHasPresence = true; + m_bFirstPresenceUpdate = true; + + // code that's calling this should set up the reset fields at this point +} + +void ServerPresenceManager::DestroyPresence() +{ + m_bHasPresence = false; + + for (ServerPresenceReporter* reporter : m_vPresenceReporters) + reporter->DestroyPresence(&m_ServerPresence); +} + +void ServerPresenceManager::RunFrame(double flCurrentTime) +{ + if (!m_bHasPresence || !Cvar_ns_report_server_to_masterserver->GetBool()) // don't run until we actually have server presence + return; + + // don't run if we're sp and don't want to report sp + if (m_ServerPresence.m_bIsSingleplayerServer && !Cvar_ns_report_sp_server_to_masterserver->GetBool()) + return; + + // run on a specified delay + if ((flCurrentTime - m_flLastPresenceUpdate) * 1000 < Cvar_ns_server_presence_update_rate->GetFloat()) + return; + + // is this the first frame we're updating this presence? + if (m_bFirstPresenceUpdate) + { + // let reporters setup/clear any state + for (ServerPresenceReporter* reporter : m_vPresenceReporters) + reporter->CreatePresence(&m_ServerPresence); + + m_bFirstPresenceUpdate = false; + } + + m_flLastPresenceUpdate = flCurrentTime; + + for (ServerPresenceReporter* reporter : m_vPresenceReporters) + reporter->ReportPresence(&m_ServerPresence); +} + +void ServerPresenceManager::SetPort(const int iPort) +{ + // update port + m_ServerPresence.m_iPort = iPort; +} + +void ServerPresenceManager::SetAuthPort(const int iAuthPort) +{ + // update authport + m_ServerPresence.m_iAuthPort = iAuthPort; +} + +void ServerPresenceManager::SetName(const std::string sServerNameUnicode) +{ + // update name + m_ServerPresence.m_sServerName = sServerNameUnicode; +} + +void ServerPresenceManager::SetDescription(const std::string sServerDescUnicode) +{ + // update desc + m_ServerPresence.m_sServerDesc = sServerDescUnicode; +} + +void ServerPresenceManager::SetPassword(const char* pPassword) +{ + // update password + strncpy_s(m_ServerPresence.m_Password, sizeof(m_ServerPresence.m_Password), pPassword, sizeof(m_ServerPresence.m_Password) - 1); +} + +void ServerPresenceManager::SetMap(const char* pMapName, bool isInitialising) +{ + // if the server is initialising (i.e. this is first map) on sp, set the server to sp + if (isInitialising) + m_ServerPresence.m_bIsSingleplayerServer = !strncmp(pMapName, "sp_", 3); + + // update map + strncpy_s(m_ServerPresence.m_MapName, sizeof(m_ServerPresence.m_MapName), pMapName, sizeof(m_ServerPresence.m_MapName) - 1); +} + +void ServerPresenceManager::SetPlaylist(const char* pPlaylistName) +{ + // update playlist + strncpy_s( + m_ServerPresence.m_PlaylistName, + sizeof(m_ServerPresence.m_PlaylistName), + pPlaylistName, + sizeof(m_ServerPresence.m_PlaylistName) - 1); + + // update maxplayers + const char* pMaxPlayers = R2::GetCurrentPlaylistVar("max_players", true); + + // can be null in some situations, so default 6 + if (pMaxPlayers) + m_ServerPresence.m_iMaxPlayers = std::stoi(pMaxPlayers); + else + m_ServerPresence.m_iMaxPlayers = 6; +} + +void ServerPresenceManager::SetPlayerCount(const int iPlayerCount) +{ + m_ServerPresence.m_iPlayerCount = iPlayerCount; +} + +ON_DLL_LOAD_RELIESON("engine.dll", ServerPresence, ConVar, (CModule module)) +{ + g_pServerPresence = new ServerPresenceManager; + + Cvar_hostname = module.Offset(0x1315BAE8).Deref().As<ConVar*>(); +} diff --git a/NorthstarDLL/serverpresence.h b/NorthstarDLL/serverpresence.h new file mode 100644 index 00000000..f27c9393 --- /dev/null +++ b/NorthstarDLL/serverpresence.h @@ -0,0 +1,91 @@ +#pragma once +#include "convar.h" + +struct ServerPresence +{ + int m_iPort; + int m_iAuthPort; + + std::string m_sServerName; + std::string m_sServerDesc; + char m_Password[256]; // probably bigger than will ever be used in practice, lol + + char m_MapName[32]; + char m_PlaylistName[64]; + bool m_bIsSingleplayerServer; // whether the server started in sp + + int m_iPlayerCount; + int m_iMaxPlayers; + + ServerPresence() + { + memset(this, 0, sizeof(this)); + } + + ServerPresence(const ServerPresence* obj) + { + m_iPort = obj->m_iPort; + m_iAuthPort = obj->m_iAuthPort; + + m_sServerName = obj->m_sServerName; + m_sServerDesc = obj->m_sServerDesc; + memcpy(m_Password, obj->m_Password, sizeof(m_Password)); + + memcpy(m_MapName, obj->m_MapName, sizeof(m_MapName)); + memcpy(m_PlaylistName, obj->m_PlaylistName, sizeof(m_PlaylistName)); + + m_iPlayerCount = obj->m_iPlayerCount; + m_iMaxPlayers = obj->m_iMaxPlayers; + } +}; + +class ServerPresenceReporter +{ + public: + virtual void CreatePresence(const ServerPresence* pServerPresence) {} + virtual void ReportPresence(const ServerPresence* pServerPresence) {} + virtual void DestroyPresence(const ServerPresence* pServerPresence) {} +}; + +class ServerPresenceManager +{ + private: + ServerPresence m_ServerPresence; + + bool m_bHasPresence = false; + bool m_bFirstPresenceUpdate = false; + + std::vector<ServerPresenceReporter*> m_vPresenceReporters; + + double m_flLastPresenceUpdate = 0; + ConVar* Cvar_ns_server_presence_update_rate; + + ConVar* Cvar_ns_server_name; + ConVar* Cvar_ns_server_desc; + ConVar* Cvar_ns_server_password; + + ConVar* Cvar_ns_report_server_to_masterserver; + ConVar* Cvar_ns_report_sp_server_to_masterserver; + + public: + ServerPresenceManager(); + + void AddPresenceReporter(ServerPresenceReporter* reporter); + + void CreatePresence(); + void DestroyPresence(); + void RunFrame(double flCurrentTime); + + void SetPort(const int iPort); + void SetAuthPort(const int iPort); + + void SetName(const std::string sServerNameUnicode); + void SetDescription(const std::string sServerDescUnicode); + void SetPassword(const char* pPassword); + + void SetMap(const char* pMapName, bool isInitialising = false); + void SetPlaylist(const char* pPlaylistName); + void SetPlayerCount(const int iPlayerCount); +}; + +extern ServerPresenceManager* g_pServerPresence; diff --git a/NorthstarDLL/sourceconsole.cpp b/NorthstarDLL/sourceconsole.cpp new file mode 100644 index 00000000..ad31e09d --- /dev/null +++ b/NorthstarDLL/sourceconsole.cpp @@ -0,0 +1,73 @@ +#include "pch.h" +#include "convar.h" +#include "sourceconsole.h" +#include "sourceinterface.h" +#include "concommand.h" +#include "printcommand.h" + +SourceInterface<CGameConsole>* g_pSourceGameConsole; + +void ConCommand_toggleconsole(const CCommand& arg) +{ + if ((*g_pSourceGameConsole)->IsConsoleVisible()) + (*g_pSourceGameConsole)->Hide(); + else + (*g_pSourceGameConsole)->Activate(); +} + +void ConCommand_showconsole(const CCommand& arg) +{ + (*g_pSourceGameConsole)->Activate(); +} + +void ConCommand_hideconsole(const CCommand& arg) +{ + (*g_pSourceGameConsole)->Hide(); +} + +void SourceConsoleSink::sink_it_(const spdlog::details::log_msg& msg) +{ + if (!(*g_pSourceGameConsole)->m_bInitialized) + return; + + spdlog::memory_buf_t formatted; + spdlog::sinks::base_sink<std::mutex>::formatter_->format(msg, formatted); + (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->ColorPrint(m_LogColours[msg.level], fmt::to_string(formatted).c_str()); +} + +void SourceConsoleSink::flush_() {} + +// clang-format off +HOOK(OnCommandSubmittedHook, OnCommandSubmitted, +void, __fastcall, (CConsoleDialog* consoleDialog, const char* pCommand)) +// clang-format on +{ + consoleDialog->m_pConsolePanel->Print("] "); + consoleDialog->m_pConsolePanel->Print(pCommand); + consoleDialog->m_pConsolePanel->Print("\n"); + + TryPrintCvarHelpForCommand(pCommand); + + OnCommandSubmitted(consoleDialog, pCommand); +} + +// called from sourceinterface.cpp in client createinterface hooks, on GameClientExports001 +void InitialiseConsoleOnInterfaceCreation() +{ + (*g_pSourceGameConsole)->Initialize(); + // hook OnCommandSubmitted so we print inputted commands + OnCommandSubmittedHook.Dispatch((*g_pSourceGameConsole)->m_pConsole->m_vtable->OnCommandSubmitted); + + auto consoleLogger = std::make_shared<SourceConsoleSink>(); + consoleLogger->set_pattern("[%l] %v"); + spdlog::default_logger()->sinks().push_back(consoleLogger); +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", SourceConsole, ConCommand, (CModule module)) +{ + g_pSourceGameConsole = new SourceInterface<CGameConsole>("client.dll", "GameConsole004"); + + RegisterConCommand("toggleconsole", ConCommand_toggleconsole, "Show/hide the console.", FCVAR_DONTRECORD); + RegisterConCommand("showconsole", ConCommand_showconsole, "Show the console.", FCVAR_DONTRECORD); + RegisterConCommand("hideconsole", ConCommand_hideconsole, "Hide the console.", FCVAR_DONTRECORD); +} diff --git a/NorthstarDedicatedTest/sourceconsole.h b/NorthstarDLL/sourceconsole.h index cf65cbd3..e811f523 100644 --- a/NorthstarDedicatedTest/sourceconsole.h +++ b/NorthstarDLL/sourceconsole.h @@ -86,21 +86,24 @@ class CGameConsole CConsoleDialog* m_pConsole; }; -extern SourceInterface<CGameConsole>* g_SourceGameConsole; +extern SourceInterface<CGameConsole>* g_pSourceGameConsole; // spdlog logger class SourceConsoleSink : public spdlog::sinks::base_sink<std::mutex> { private: - std::map<spdlog::level::level_enum, SourceColor> logColours; - - public: - SourceConsoleSink(); + std::map<spdlog::level::level_enum, SourceColor> m_LogColours = { + {spdlog::level::trace, SourceColor(0, 255, 255, 255)}, + {spdlog::level::debug, SourceColor(0, 255, 255, 255)}, + {spdlog::level::info, SourceColor(255, 255, 255, 255)}, + {spdlog::level::warn, SourceColor(255, 255, 0, 255)}, + {spdlog::level::err, SourceColor(255, 0, 0, 255)}, + {spdlog::level::critical, SourceColor(255, 0, 0, 255)}, + {spdlog::level::off, SourceColor(0, 0, 0, 0)}}; protected: void sink_it_(const spdlog::details::log_msg& msg) override; void flush_() override; }; -void InitialiseSourceConsole(HMODULE baseAddress); -void InitialiseConsoleOnInterfaceCreation();
\ No newline at end of file +void InitialiseConsoleOnInterfaceCreation(); diff --git a/NorthstarDLL/sourceinterface.cpp b/NorthstarDLL/sourceinterface.cpp new file mode 100644 index 00000000..d5f7b7cd --- /dev/null +++ b/NorthstarDLL/sourceinterface.cpp @@ -0,0 +1,49 @@ +#include "pch.h" +#include "sourceinterface.h" +#include "sourceconsole.h" + +AUTOHOOK_INIT() + +// really wanted to do a modular callback system here but honestly couldn't be bothered so hardcoding stuff for now: todo later + +// clang-format off +AUTOHOOK_PROCADDRESS(ClientCreateInterface, client.dll, CreateInterface, +void*, __fastcall, (const char* pName, const int* pReturnCode)) +// clang-format on +{ + void* ret = ClientCreateInterface(pName, pReturnCode); + spdlog::info("CreateInterface CLIENT {}", pName); + + if (!strcmp(pName, "GameClientExports001")) + InitialiseConsoleOnInterfaceCreation(); + + return ret; +} + +// clang-format off +AUTOHOOK_PROCADDRESS(ServerCreateInterface, server.dll, CreateInterface, +void*, __fastcall, (const char* pName, const int* pReturnCode)) +// clang-format on +{ + void* ret = ServerCreateInterface(pName, pReturnCode); + spdlog::info("CreateInterface SERVER {}", pName); + + return ret; +} + +// clang-format off +AUTOHOOK_PROCADDRESS(EngineCreateInterface, engine.dll, CreateInterface, +void*, __fastcall, (const char* pName, const int* pReturnCode)) +// clang-format on +{ + void* ret = EngineCreateInterface(pName, pReturnCode); + spdlog::info("CreateInterface ENGINE {}", pName); + + return ret; +} + +// clang-format off +ON_DLL_LOAD("client.dll", ClientInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(client.dll)} +ON_DLL_LOAD("server.dll", ServerInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(server.dll)} +ON_DLL_LOAD("engine.dll", EngineInterface, (CModule module)) {AUTOHOOK_DISPATCH_MODULE(engine.dll)} +// clang-format on diff --git a/NorthstarDedicatedTest/sourceinterface.h b/NorthstarDLL/sourceinterface.h index 05318963..474e961b 100644 --- a/NorthstarDedicatedTest/sourceinterface.h +++ b/NorthstarDLL/sourceinterface.h @@ -29,6 +29,3 @@ template <typename T> class SourceInterface return m_interface; } }; - -// functions for interface creation callbacks -void InitialiseInterfaceCreationHooks();
\ No newline at end of file diff --git a/NorthstarDLL/squirrel.cpp b/NorthstarDLL/squirrel.cpp new file mode 100644 index 00000000..5c2d8b1b --- /dev/null +++ b/NorthstarDLL/squirrel.cpp @@ -0,0 +1,592 @@ +#include "pch.h" +#include "squirrel.h" +#include "concommand.h" +#include "modmanager.h" +#include "dedicated.h" +#include "r2engine.h" +#include "tier0.h" + +AUTOHOOK_INIT() + +const char* GetContextName(ScriptContext context) +{ + switch (context) + { + case ScriptContext::CLIENT: + return "CLIENT"; + case ScriptContext::SERVER: + return "SERVER"; + case ScriptContext::UI: + return "UI"; + default: + return "UNKNOWN"; + } +} + +eSQReturnType SQReturnTypeFromString(const char* pReturnType) +{ + static const std::map<std::string, eSQReturnType> sqReturnTypeNameToString = { + {"bool", eSQReturnType::Boolean}, + {"float", eSQReturnType::Float}, + {"vector", eSQReturnType::Vector}, + {"int", eSQReturnType::Integer}, + {"entity", eSQReturnType::Entity}, + {"string", eSQReturnType::String}, + {"array", eSQReturnType::Arrays}, + {"asset", eSQReturnType::Asset}, + {"table", eSQReturnType::Table}}; + + if (sqReturnTypeNameToString.find(pReturnType) != sqReturnTypeNameToString.end()) + return sqReturnTypeNameToString.at(pReturnType); + else + return eSQReturnType::Default; // previous default value +} + +const char* SQTypeNameFromID(int type) +{ + switch (type) + { + case OT_ASSET: + return "asset"; + case OT_INTEGER: + return "int"; + case OT_BOOL: + return "bool"; + case SQOBJECT_NUMERIC: + return "float or int"; + case OT_NULL: + return "null"; + case OT_VECTOR: + return "vector"; + case 0: + return "var"; + case OT_USERDATA: + return "userdata"; + case OT_FLOAT: + return "float"; + case OT_STRING: + return "string"; + case OT_ARRAY: + return "array"; + case 0x8000200: + return "function"; + case 0x8100000: + return "structdef"; + case OT_THREAD: + return "thread"; + case OT_FUNCPROTO: + return "function"; + case OT_CLAAS: + return "class"; + case OT_WEAKREF: + return "weakref"; + case 0x8080000: + return "unimplemented function"; + case 0x8200000: + return "struct instance"; + case OT_TABLE: + return "table"; + case 0xA008000: + return "instance"; + case OT_ENTITY: + return "entity"; + } + return ""; +} + +// needed to define implementations for squirrelmanager outside of squirrel.h without compiler errors +template class SquirrelManager<ScriptContext::SERVER>; +template class SquirrelManager<ScriptContext::CLIENT>; +template class SquirrelManager<ScriptContext::UI>; + +template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquirrelVM* newSqvm) +{ + m_pSQVM = newSqvm; + + for (SQFuncRegistration* funcReg : m_funcRegistrations) + { + spdlog::info("Registering {} function {}", GetContextName(context), funcReg->squirrelFuncName); + RegisterSquirrelFunc(m_pSQVM, funcReg, 1); + } + + for (auto& pair : g_pModManager->m_DependencyConstants) + { + bool bWasFound = false; + for (Mod& dependency : g_pModManager->m_LoadedMods) + { + if (!dependency.m_bEnabled) + continue; + + if (dependency.Name == pair.second) + { + bWasFound = true; + break; + } + } + + defconst(m_pSQVM, pair.first.c_str(), bWasFound); + } +} + +template <ScriptContext context> void SquirrelManager<context>::VMDestroyed() +{ + m_pSQVM = nullptr; +} + +template <ScriptContext context> void SquirrelManager<context>::ExecuteCode(const char* pCode) +{ + if (!m_pSQVM || !m_pSQVM->sqvm) + { + spdlog::error("Cannot execute code, {} squirrel vm is not initialised", GetContextName(context)); + return; + } + + spdlog::info("Executing {} script code {} ", GetContextName(context), pCode); + + std::string strCode(pCode); + CompileBufferState bufferState = CompileBufferState(strCode); + + SQRESULT compileResult = compilebuffer(&bufferState, "console"); + spdlog::info("sq_compilebuffer returned {}", PrintSQRESULT.at(compileResult)); + + if (compileResult != SQRESULT_ERROR) + { + pushroottable(m_pSQVM->sqvm); + SQRESULT callResult = call(m_pSQVM->sqvm, 0); + spdlog::info("sq_call returned {}", PrintSQRESULT.at(callResult)); + } +} + +template <ScriptContext context> void SquirrelManager<context>::AddFuncRegistration( + std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func) +{ + SQFuncRegistration* reg = new SQFuncRegistration; + + reg->squirrelFuncName = new char[name.size() + 1]; + strcpy((char*)reg->squirrelFuncName, name.c_str()); + reg->cppFuncName = reg->squirrelFuncName; + + reg->helpText = new char[helpText.size() + 1]; + strcpy((char*)reg->helpText, helpText.c_str()); + + reg->returnTypeString = new char[returnType.size() + 1]; + strcpy((char*)reg->returnTypeString, returnType.c_str()); + reg->returnType = SQReturnTypeFromString(returnType.c_str()); + + reg->argTypes = new char[argTypes.size() + 1]; + strcpy((char*)reg->argTypes, argTypes.c_str()); + + reg->funcPtr = func; + + m_funcRegistrations.push_back(reg); +} + +template <ScriptContext context> SQRESULT SquirrelManager<context>::setupfunc(const SQChar* funcname) +{ + pushroottable(m_pSQVM->sqvm); + pushstring(m_pSQVM->sqvm, funcname, -1); + + SQRESULT result = get(m_pSQVM->sqvm, -2); + if (result != SQRESULT_ERROR) + pushroottable(m_pSQVM->sqvm); + + return result; +} + +template <ScriptContext context> void SquirrelManager<context>::AddFuncOverride(std::string name, SQFunction func) +{ + m_funcOverrides[name] = func; +} + +// hooks +bool IsUIVM(ScriptContext context, HSquirrelVM* pSqvm) +{ + return context != ScriptContext::SERVER && g_pSquirrel<ScriptContext::UI>->m_pSQVM && + g_pSquirrel<ScriptContext::UI>->m_pSQVM->sqvm == pSqvm; +} + +template <ScriptContext context> void* (*__fastcall sq_compiler_create)(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError); +template <ScriptContext context> void* __fastcall sq_compiler_createHook(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError) +{ + // store whether errors generated from this compile should be fatal + if (IsUIVM(context, sqvm)) + g_pSquirrel<ScriptContext::UI>->m_bFatalCompilationErrors = bShouldThrowError; + else + g_pSquirrel<context>->m_bFatalCompilationErrors = bShouldThrowError; + + return sq_compiler_create<context>(sqvm, a2, a3, bShouldThrowError); +} + +template <ScriptContext context> SQInteger (*SQPrint)(HSquirrelVM* sqvm, const char* fmt); +template <ScriptContext context> SQInteger SQPrintHook(HSquirrelVM* sqvm, const char* fmt, ...) +{ + va_list va; + va_start(va, fmt); + + SQChar buf[1024]; + int charsWritten = vsnprintf_s(buf, _TRUNCATE, fmt, va); + + if (charsWritten > 0) + { + if (buf[charsWritten - 1] == '\n') + buf[charsWritten - 1] = '\0'; + + spdlog::info("[{} SCRIPT] {}", GetContextName(context), buf); + } + + va_end(va); + return 0; +} + +template <ScriptContext context> CSquirrelVM* (*__fastcall CreateNewVM)(void* a1, ScriptContext realContext); +template <ScriptContext context> CSquirrelVM* __fastcall CreateNewVMHook(void* a1, ScriptContext realContext) +{ + CSquirrelVM* sqvm = CreateNewVM<context>(a1, realContext); + if (realContext == ScriptContext::UI) + g_pSquirrel<ScriptContext::UI>->VMCreated(sqvm); + else + g_pSquirrel<context>->VMCreated(sqvm); + + spdlog::info("CreateNewVM {} {}", GetContextName(realContext), (void*)sqvm); + return sqvm; +} + +template <ScriptContext context> void (*__fastcall DestroyVM)(void* a1, HSquirrelVM* sqvm); +template <ScriptContext context> void __fastcall DestroyVMHook(void* a1, HSquirrelVM* sqvm) +{ + ScriptContext realContext = context; // ui and client use the same function so we use this for prints + if (IsUIVM(context, sqvm)) + { + realContext = ScriptContext::UI; + g_pSquirrel<ScriptContext::UI>->VMDestroyed(); + } + else + DestroyVM<context>(a1, sqvm); + + spdlog::info("DestroyVM {} {}", GetContextName(realContext), (void*)sqvm); +} + +template <ScriptContext context> +void (*__fastcall SQCompileError)(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column); +template <ScriptContext context> +void __fastcall ScriptCompileErrorHook(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column) +{ + bool bIsFatalError = g_pSquirrel<context>->m_bFatalCompilationErrors; + ScriptContext realContext = context; // ui and client use the same function so we use this for prints + if (IsUIVM(context, sqvm)) + { + realContext = ScriptContext::UI; + bIsFatalError = g_pSquirrel<ScriptContext::UI>->m_bFatalCompilationErrors; + } + + spdlog::error("{} SCRIPT COMPILE ERROR {}", GetContextName(realContext), error); + spdlog::error("{} line [{}] column [{}]", file, line, column); + + // use disconnect to display an error message for the compile error, but only if the compilation error was fatal + // todo, we could get this from sqvm itself probably, rather than hooking sq_compiler_create + if (bIsFatalError) + { + // kill dedicated server if we hit this + if (IsDedicatedServer()) + abort(); + else + { + R2::Cbuf_AddText( + R2::Cbuf_GetCurrentPlayer(), + fmt::format("disconnect \"Encountered {} script compilation error, see console for details.\"", GetContextName(realContext)) + .c_str(), + R2::cmd_source_t::kCommandSrcCode); + + // likely temp: show console so user can see any errors, as error message wont display if ui is dead + // maybe we could disable all mods other than the coremods and try a reload before doing this? + // could also maybe do some vgui bullshit to show something visually rather than console + if (realContext == ScriptContext::UI) + R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "showconsole", R2::cmd_source_t::kCommandSrcCode); + } + } + + // dont call the original function since it kills game lol +} + +template <ScriptContext context> +int64_t (*__fastcall RegisterSquirrelFunction)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); +template <ScriptContext context> +int64_t __fastcall RegisterSquirrelFunctionHook(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown) +{ + if (IsUIVM(context, sqvm->sqvm)) + { + if (g_pSquirrel<ScriptContext::UI>->m_funcOverrides.count(funcReg->squirrelFuncName)) + { + g_pSquirrel<ScriptContext::UI>->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr; + funcReg->funcPtr = g_pSquirrel<ScriptContext::UI>->m_funcOverrides[funcReg->squirrelFuncName]; + spdlog::info("Replacing {} in UI", std::string(funcReg->squirrelFuncName)); + } + + return g_pSquirrel<ScriptContext::UI>->RegisterSquirrelFunc(sqvm, funcReg, unknown); + } + + if (g_pSquirrel<context>->m_funcOverrides.find(funcReg->squirrelFuncName) != g_pSquirrel<context>->m_funcOverrides.end()) + { + g_pSquirrel<context>->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr; + funcReg->funcPtr = g_pSquirrel<context>->m_funcOverrides[funcReg->squirrelFuncName]; + spdlog::info("Replacing {} in Client", std::string(funcReg->squirrelFuncName)); + } + + return g_pSquirrel<context>->RegisterSquirrelFunc(sqvm, funcReg, unknown); +} + +template <ScriptContext context> bool (*__fastcall CallScriptInitCallback)(void* sqvm, const char* callback); +template <ScriptContext context> bool __fastcall CallScriptInitCallbackHook(void* sqvm, const char* callback) +{ + ScriptContext realContext = context; + bool bShouldCallCustomCallbacks = true; + + if (context == ScriptContext::CLIENT) + { + if (!strcmp(callback, "UICodeCallback_UIInit")) + realContext = ScriptContext::UI; + else if (strcmp(callback, "ClientCodeCallback_MapSpawn")) + bShouldCallCustomCallbacks = false; + } + else if (context == ScriptContext::SERVER) + bShouldCallCustomCallbacks = !strcmp(callback, "CodeCallback_MapSpawn"); + + if (bShouldCallCustomCallbacks) + { + for (Mod mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + for (ModScript script : mod.Scripts) + { + for (ModScriptCallback modCallback : script.Callbacks) + { + if (modCallback.Context == realContext && modCallback.BeforeCallback.length()) + { + spdlog::info("Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.BeforeCallback); + CallScriptInitCallback<context>(sqvm, modCallback.BeforeCallback.c_str()); + } + } + } + } + } + + spdlog::info("{} CodeCallback {} called", GetContextName(realContext), callback); + if (!bShouldCallCustomCallbacks) + spdlog::info("Not executing custom callbacks for CodeCallback {}", callback); + bool ret = CallScriptInitCallback<context>(sqvm, callback); + + // run after callbacks + if (bShouldCallCustomCallbacks) + { + for (Mod mod : g_pModManager->m_LoadedMods) + { + if (!mod.m_bEnabled) + continue; + + for (ModScript script : mod.Scripts) + { + for (ModScriptCallback modCallback : script.Callbacks) + { + if (modCallback.Context == realContext && modCallback.AfterCallback.length()) + { + spdlog::info("Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.AfterCallback); + CallScriptInitCallback<context>(sqvm, modCallback.AfterCallback.c_str()); + } + } + } + } + } + + return ret; +} + +template <ScriptContext context> void ConCommand_script(const CCommand& args) +{ + g_pSquirrel<context>->ExecuteCode(args.ArgS()); +} + +// literal class type that wraps a constant expression string +template <size_t N> struct TemplateStringLiteral +{ + constexpr TemplateStringLiteral(const char (&str)[N]) + { + std::copy_n(str, N, value); + } + + char value[N]; +}; + +template <ScriptContext context, TemplateStringLiteral funcName> SQRESULT SQ_StubbedFunc(HSquirrelVM* sqvm) +{ + spdlog::info("Blocking call to stubbed function {} in {}", funcName.value, GetContextName(context)); + return SQRESULT_NULL; +} + +template <ScriptContext context> void StubUnsafeSQFuncs() +{ + if (!Tier0::CommandLine()->CheckParm("-allowunsafesqfuncs")) + { + g_pSquirrel<context>->AddFuncOverride("DevTextBufferWrite", SQ_StubbedFunc<context, "DevTextBufferWrite">); + g_pSquirrel<context>->AddFuncOverride("DevTextBufferClear", SQ_StubbedFunc<context, "DevTextBufferClear">); + g_pSquirrel<context>->AddFuncOverride("DevTextBufferDumpToFile", SQ_StubbedFunc<context, "DevTextBufferDumpToFile">); + g_pSquirrel<context>->AddFuncOverride("Dev_CommandLineAddParam", SQ_StubbedFunc<context, "Dev_CommandLineAddParam">); + g_pSquirrel<context>->AddFuncOverride("DevP4Checkout", SQ_StubbedFunc<context, "DevP4Checkout">); + g_pSquirrel<context>->AddFuncOverride("DevP4Add", SQ_StubbedFunc<context, "DevP4Add">); + } +} + +ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(client.dll) + + g_pSquirrel<ScriptContext::CLIENT> = new SquirrelManager<ScriptContext::CLIENT>; + g_pSquirrel<ScriptContext::UI> = new SquirrelManager<ScriptContext::UI>; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst = module.Offset(0x12120).As<sq_defconstType>(); + g_pSquirrel<ScriptContext::UI>->__sq_defconst = g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_compilebuffer = module.Offset(0x3110).As<sq_compilebufferType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushroottable = module.Offset(0x5860).As<sq_pushroottableType>(); + g_pSquirrel<ScriptContext::UI>->__sq_compilebuffer = g_pSquirrel<ScriptContext::CLIENT>->__sq_compilebuffer; + g_pSquirrel<ScriptContext::UI>->__sq_pushroottable = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushroottable; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_call = module.Offset(0x8650).As<sq_callType>(); + g_pSquirrel<ScriptContext::UI>->__sq_call = g_pSquirrel<ScriptContext::CLIENT>->__sq_call; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_newarray = module.Offset(0x39F0).As<sq_newarrayType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_arrayappend = module.Offset(0x3C70).As<sq_arrayappendType>(); + g_pSquirrel<ScriptContext::UI>->__sq_newarray = g_pSquirrel<ScriptContext::CLIENT>->__sq_newarray; + g_pSquirrel<ScriptContext::UI>->__sq_arrayappend = g_pSquirrel<ScriptContext::CLIENT>->__sq_arrayappend; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_newtable = module.Offset(0x3960).As<sq_newtableType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_newslot = module.Offset(0x70B0).As<sq_newslotType>(); + g_pSquirrel<ScriptContext::UI>->__sq_newtable = g_pSquirrel<ScriptContext::CLIENT>->__sq_newtable; + g_pSquirrel<ScriptContext::UI>->__sq_newslot = g_pSquirrel<ScriptContext::CLIENT>->__sq_newslot; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushstring = module.Offset(0x3440).As<sq_pushstringType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushinteger = module.Offset(0x36A0).As<sq_pushintegerType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushfloat = module.Offset(0x3800).As<sq_pushfloatType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushbool = module.Offset(0x3710).As<sq_pushboolType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushasset = module.Offset(0x3560).As<sq_pushassetType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushvector = module.Offset(0x3780).As<sq_pushvectorType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_raiseerror = module.Offset(0x8470).As<sq_raiseerrorType>(); + g_pSquirrel<ScriptContext::UI>->__sq_pushstring = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushstring; + g_pSquirrel<ScriptContext::UI>->__sq_pushinteger = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushinteger; + g_pSquirrel<ScriptContext::UI>->__sq_pushfloat = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushfloat; + g_pSquirrel<ScriptContext::UI>->__sq_pushbool = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushbool; + g_pSquirrel<ScriptContext::UI>->__sq_pushvector = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushvector; + g_pSquirrel<ScriptContext::UI>->__sq_pushasset = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushasset; + g_pSquirrel<ScriptContext::UI>->__sq_raiseerror = g_pSquirrel<ScriptContext::CLIENT>->__sq_raiseerror; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_getstring = module.Offset(0x60C0).As<sq_getstringType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_getinteger = module.Offset(0x60E0).As<sq_getintegerType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_getfloat = module.Offset(0x6100).As<sq_getfloatType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_getbool = module.Offset(0x6130).As<sq_getboolType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_get = module.Offset(0x7C30).As<sq_getType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_getasset = module.Offset(0x6010).As<sq_getassetType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_getuserdata = module.Offset(0x63D0).As<sq_getuserdataType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_getvector = module.Offset(0x6140).As<sq_getvectorType>(); + g_pSquirrel<ScriptContext::UI>->__sq_getstring = g_pSquirrel<ScriptContext::CLIENT>->__sq_getstring; + g_pSquirrel<ScriptContext::UI>->__sq_getinteger = g_pSquirrel<ScriptContext::CLIENT>->__sq_getinteger; + g_pSquirrel<ScriptContext::UI>->__sq_getfloat = g_pSquirrel<ScriptContext::CLIENT>->__sq_getfloat; + g_pSquirrel<ScriptContext::UI>->__sq_getbool = g_pSquirrel<ScriptContext::CLIENT>->__sq_getbool; + g_pSquirrel<ScriptContext::UI>->__sq_get = g_pSquirrel<ScriptContext::CLIENT>->__sq_get; + g_pSquirrel<ScriptContext::UI>->__sq_getasset = g_pSquirrel<ScriptContext::CLIENT>->__sq_getasset; + g_pSquirrel<ScriptContext::UI>->__sq_getuserdata = g_pSquirrel<ScriptContext::CLIENT>->__sq_getuserdata; + g_pSquirrel<ScriptContext::UI>->__sq_getvector = g_pSquirrel<ScriptContext::CLIENT>->__sq_getvector; + + g_pSquirrel<ScriptContext::CLIENT>->__sq_createuserdata = module.Offset(0x38D0).As<sq_createuserdataType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_setuserdatatypeid = module.Offset(0x6490).As<sq_setuserdatatypeidType>(); + g_pSquirrel<ScriptContext::UI>->__sq_createuserdata = g_pSquirrel<ScriptContext::CLIENT>->__sq_createuserdata; + g_pSquirrel<ScriptContext::UI>->__sq_setuserdatatypeid = g_pSquirrel<ScriptContext::CLIENT>->__sq_setuserdatatypeid; + + MAKEHOOK( + module.Offset(0x108E0), + &RegisterSquirrelFunctionHook<ScriptContext::CLIENT>, + &g_pSquirrel<ScriptContext::CLIENT>->RegisterSquirrelFunc); + g_pSquirrel<ScriptContext::UI>->RegisterSquirrelFunc = g_pSquirrel<ScriptContext::CLIENT>->RegisterSquirrelFunc; + + // uiscript_reset concommand: don't loop forever if compilation fails + module.Offset(0x3C6E4C).NOP(6); + + MAKEHOOK(module.Offset(0x8AD0), &sq_compiler_createHook<ScriptContext::CLIENT>, &sq_compiler_create<ScriptContext::CLIENT>); + + MAKEHOOK(module.Offset(0x12B00), &SQPrintHook<ScriptContext::CLIENT>, &SQPrint<ScriptContext::CLIENT>); + MAKEHOOK(module.Offset(0x12BA0), &SQPrintHook<ScriptContext::UI>, &SQPrint<ScriptContext::UI>); + + MAKEHOOK(module.Offset(0x26130), &CreateNewVMHook<ScriptContext::CLIENT>, &CreateNewVM<ScriptContext::CLIENT>); + MAKEHOOK(module.Offset(0x26E70), &DestroyVMHook<ScriptContext::CLIENT>, &DestroyVM<ScriptContext::CLIENT>); + MAKEHOOK(module.Offset(0x79A50), &ScriptCompileErrorHook<ScriptContext::CLIENT>, &SQCompileError<ScriptContext::CLIENT>); + + MAKEHOOK(module.Offset(0x10190), &CallScriptInitCallbackHook<ScriptContext::CLIENT>, &CallScriptInitCallback<ScriptContext::CLIENT>); + + RegisterConCommand("script_client", ConCommand_script<ScriptContext::CLIENT>, "Executes script code on the client vm", FCVAR_CLIENTDLL); + RegisterConCommand("script_ui", ConCommand_script<ScriptContext::UI>, "Executes script code on the ui vm", FCVAR_CLIENTDLL); + + StubUnsafeSQFuncs<ScriptContext::CLIENT>(); + StubUnsafeSQFuncs<ScriptContext::UI>(); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) +{ + AUTOHOOK_DISPATCH_MODULE(server.dll) + + g_pSquirrel<ScriptContext::SERVER> = new SquirrelManager<ScriptContext::SERVER>; + + g_pSquirrel<ScriptContext::SERVER>->__sq_defconst = module.Offset(0x1F550).As<sq_defconstType>(); + + g_pSquirrel<ScriptContext::SERVER>->__sq_compilebuffer = module.Offset(0x3110).As<sq_compilebufferType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushroottable = module.Offset(0x5840).As<sq_pushroottableType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_call = module.Offset(0x8620).As<sq_callType>(); + + g_pSquirrel<ScriptContext::SERVER>->__sq_newarray = module.Offset(0x39F0).As<sq_newarrayType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_arrayappend = module.Offset(0x3C70).As<sq_arrayappendType>(); + + g_pSquirrel<ScriptContext::SERVER>->__sq_newtable = module.Offset(0x3960).As<sq_newtableType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_newslot = module.Offset(0x7080).As<sq_newslotType>(); + + g_pSquirrel<ScriptContext::SERVER>->__sq_pushstring = module.Offset(0x3440).As<sq_pushstringType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushinteger = module.Offset(0x36A0).As<sq_pushintegerType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushfloat = module.Offset(0x3800).As<sq_pushfloatType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushbool = module.Offset(0x3710).As<sq_pushboolType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushasset = module.Offset(0x3560).As<sq_pushassetType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushvector = module.Offset(0x3780).As<sq_pushvectorType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_raiseerror = module.Offset(0x8440).As<sq_raiseerrorType>(); + + g_pSquirrel<ScriptContext::SERVER>->__sq_getstring = module.Offset(0x60A0).As<sq_getstringType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getinteger = module.Offset(0x60C0).As<sq_getintegerType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getfloat = module.Offset(0x60E0).As<sq_getfloatType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getbool = module.Offset(0x6110).As<sq_getboolType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getasset = module.Offset(0x5FF0).As<sq_getassetType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getuserdata = module.Offset(0x63B0).As<sq_getuserdataType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getvector = module.Offset(0x6120).As<sq_getvectorType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_get = module.Offset(0x7C00).As<sq_getType>(); + + g_pSquirrel<ScriptContext::SERVER>->__sq_createuserdata = module.Offset(0x38D0).As<sq_createuserdataType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_setuserdatatypeid = module.Offset(0x6470).As<sq_setuserdatatypeidType>(); + + MAKEHOOK( + module.Offset(0x1DD10), + &RegisterSquirrelFunctionHook<ScriptContext::SERVER>, + &g_pSquirrel<ScriptContext::SERVER>->RegisterSquirrelFunc); + + MAKEHOOK(module.Offset(0x8AA0), &sq_compiler_createHook<ScriptContext::SERVER>, &sq_compiler_create<ScriptContext::SERVER>); + + MAKEHOOK(module.Offset(0x1FE90), &SQPrintHook<ScriptContext::SERVER>, &SQPrint<ScriptContext::SERVER>); + MAKEHOOK(module.Offset(0x260E0), &CreateNewVMHook<ScriptContext::SERVER>, &CreateNewVM<ScriptContext::SERVER>); + MAKEHOOK(module.Offset(0x26E20), &DestroyVMHook<ScriptContext::SERVER>, &DestroyVM<ScriptContext::SERVER>); + MAKEHOOK(module.Offset(0x799E0), &ScriptCompileErrorHook<ScriptContext::SERVER>, &SQCompileError<ScriptContext::SERVER>); + MAKEHOOK(module.Offset(0x1D5C0), &CallScriptInitCallbackHook<ScriptContext::SERVER>, &CallScriptInitCallback<ScriptContext::SERVER>); + + // FCVAR_CHEAT and FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS allows clients to execute this, but since it's unsafe we only allow it when cheats + // are enabled for script_client and script_ui, we don't use cheats, so clients can execute them on themselves all they want + RegisterConCommand( + "script", + ConCommand_script<ScriptContext::SERVER>, + "Executes script code on the server vm", + FCVAR_GAMEDLL | FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS | FCVAR_CHEAT); + + StubUnsafeSQFuncs<ScriptContext::SERVER>(); +} diff --git a/NorthstarDLL/squirrel.h b/NorthstarDLL/squirrel.h new file mode 100644 index 00000000..4f644703 --- /dev/null +++ b/NorthstarDLL/squirrel.h @@ -0,0 +1,318 @@ +#pragma once + +#include "squirreldatatypes.h" +#include "vector.h" + +// stolen from ttf2sdk: sqvm types +typedef float SQFloat; +typedef long SQInteger; +typedef unsigned long SQUnsignedInteger; +typedef char SQChar; +typedef SQUnsignedInteger SQBool; + +enum SQRESULT : SQInteger +{ + SQRESULT_ERROR = -1, + SQRESULT_NULL = 0, + SQRESULT_NOTNULL = 1, +}; + +typedef SQRESULT (*SQFunction)(HSquirrelVM* sqvm); + +enum class eSQReturnType +{ + Float = 0x1, + Vector = 0x3, + Integer = 0x5, + Boolean = 0x6, + Entity = 0xD, + String = 0x21, + Default = 0x20, + Arrays = 0x25, + Asset = 0x28, + Table = 0x26, +}; + +const std::map<SQRESULT, const char*> PrintSQRESULT = { + {SQRESULT_ERROR, "SQRESULT_ERROR"}, {SQRESULT_NULL, "SQRESULT_NULL"}, {SQRESULT_NOTNULL, "SQRESULT_NOTNULL"}}; + +struct CompileBufferState +{ + const SQChar* buffer; + const SQChar* bufferPlusLength; + const SQChar* bufferAgain; + + CompileBufferState(const std::string& code) + { + buffer = code.c_str(); + bufferPlusLength = code.c_str() + code.size(); + bufferAgain = code.c_str(); + } +}; + +struct SQFuncRegistration +{ + const char* squirrelFuncName; + const char* cppFuncName; + const char* helpText; + const char* returnTypeString; + const char* argTypes; + uint32_t unknown1; + uint32_t devLevel; + const char* shortNameMaybe; + uint32_t unknown2; + eSQReturnType returnType; + uint32_t* externalBufferPointer; + uint64_t externalBufferSize; + uint64_t unknown3; + uint64_t unknown4; + SQFunction funcPtr; + + SQFuncRegistration() + { + memset(this, 0, sizeof(SQFuncRegistration)); + this->returnType = eSQReturnType::Default; + } +}; + +enum class ScriptContext : int +{ + SERVER, + CLIENT, + UI, +}; + +const char* GetContextName(ScriptContext context); +eSQReturnType SQReturnTypeFromString(const char* pReturnType); +const char* SQTypeNameFromID(const int iTypeId); + +// core sqvm funcs +typedef int64_t (*RegisterSquirrelFuncType)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); +typedef void (*sq_defconstType)(CSquirrelVM* sqvm, const SQChar* name, int value); + +typedef SQRESULT (*sq_compilebufferType)( + HSquirrelVM* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, SQBool bShouldThrowError); +typedef SQRESULT (*sq_callType)(HSquirrelVM* sqvm, SQInteger iArgs, SQBool bShouldReturn, SQBool bThrowError); +typedef SQInteger (*sq_raiseerrorType)(HSquirrelVM* sqvm, const SQChar* pError); + +// sq stack array funcs +typedef void (*sq_newarrayType)(HSquirrelVM* sqvm, SQInteger iStackpos); +typedef SQRESULT (*sq_arrayappendType)(HSquirrelVM* sqvm, SQInteger iStackpos); + +// sq table funcs +typedef SQRESULT (*sq_newtableType)(HSquirrelVM* sqvm); +typedef SQRESULT (*sq_newslotType)(HSquirrelVM* sqvm, SQInteger idx, SQBool bStatic); + +// sq stack push funcs +typedef void (*sq_pushroottableType)(HSquirrelVM* sqvm); +typedef void (*sq_pushstringType)(HSquirrelVM* sqvm, const SQChar* pStr, SQInteger iLength); +typedef void (*sq_pushintegerType)(HSquirrelVM* sqvm, SQInteger i); +typedef void (*sq_pushfloatType)(HSquirrelVM* sqvm, SQFloat f); +typedef void (*sq_pushboolType)(HSquirrelVM* sqvm, SQBool b); +typedef void (*sq_pushassetType)(HSquirrelVM* sqvm, const SQChar* str, SQInteger iLength); +typedef void (*sq_pushvectorType)(HSquirrelVM* sqvm, const SQFloat* pVec); + +// sq stack get funcs +typedef const SQChar* (*sq_getstringType)(HSquirrelVM* sqvm, SQInteger iStackpos); +typedef SQInteger (*sq_getintegerType)(HSquirrelVM* sqvm, SQInteger iStackpos); +typedef SQFloat (*sq_getfloatType)(HSquirrelVM*, SQInteger iStackpos); +typedef SQBool (*sq_getboolType)(HSquirrelVM*, SQInteger iStackpos); +typedef SQRESULT (*sq_getType)(HSquirrelVM* sqvm, SQInteger iStackpos); +typedef SQRESULT (*sq_getassetType)(HSquirrelVM* sqvm, SQInteger iStackpos, const char** pResult); +typedef SQRESULT (*sq_getuserdataType)(HSquirrelVM* sqvm, SQInteger iStackpos, void** pData, uint64_t* pTypeId); +typedef SQFloat* (*sq_getvectorType)(HSquirrelVM* sqvm, SQInteger iStackpos); + +// sq stack userpointer funcs +typedef void* (*sq_createuserdataType)(HSquirrelVM* sqvm, SQInteger iSize); +typedef SQRESULT (*sq_setuserdatatypeidType)(HSquirrelVM* sqvm, SQInteger iStackpos, uint64_t iTypeId); + +template <ScriptContext context> class SquirrelManager +{ + private: + std::vector<SQFuncRegistration*> m_funcRegistrations; + + public: + CSquirrelVM* m_pSQVM; + std::map<std::string, SQFunction> m_funcOverrides = {}; + std::map<std::string, SQFunction> m_funcOriginals = {}; + + bool m_bFatalCompilationErrors = false; + +#pragma region SQVM funcs + RegisterSquirrelFuncType RegisterSquirrelFunc; + sq_defconstType __sq_defconst; + + sq_compilebufferType __sq_compilebuffer; + sq_callType __sq_call; + sq_raiseerrorType __sq_raiseerror; + + sq_newarrayType __sq_newarray; + sq_arrayappendType __sq_arrayappend; + + sq_newtableType __sq_newtable; + sq_newslotType __sq_newslot; + + sq_pushroottableType __sq_pushroottable; + sq_pushstringType __sq_pushstring; + sq_pushintegerType __sq_pushinteger; + sq_pushfloatType __sq_pushfloat; + sq_pushboolType __sq_pushbool; + sq_pushassetType __sq_pushasset; + sq_pushvectorType __sq_pushvector; + + sq_getstringType __sq_getstring; + sq_getintegerType __sq_getinteger; + sq_getfloatType __sq_getfloat; + sq_getboolType __sq_getbool; + sq_getType __sq_get; + sq_getassetType __sq_getasset; + sq_getuserdataType __sq_getuserdata; + sq_getvectorType __sq_getvector; + + sq_createuserdataType __sq_createuserdata; + sq_setuserdatatypeidType __sq_setuserdatatypeid; +#pragma endregion + + public: + SquirrelManager() : m_pSQVM(nullptr) {} + + void VMCreated(CSquirrelVM* newSqvm); + void VMDestroyed(); + void ExecuteCode(const char* code); + void AddFuncRegistration(std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func); + SQRESULT setupfunc(const SQChar* funcname); + void AddFuncOverride(std::string name, SQFunction func); + +#pragma region SQVM func wrappers + inline void defconst(CSquirrelVM* sqvm, const SQChar* pName, int nValue) + { + __sq_defconst(sqvm, pName, nValue); + } + + inline SQRESULT + compilebuffer(CompileBufferState* bufferState, const SQChar* bufferName = "unnamedbuffer", const SQBool bShouldThrowError = false) + { + return __sq_compilebuffer(m_pSQVM->sqvm, bufferState, bufferName, -1, bShouldThrowError); + } + + inline SQRESULT call(HSquirrelVM* sqvm, const SQInteger args) + { + return __sq_call(sqvm, args + 1, false, false); + } + + inline SQInteger raiseerror(HSquirrelVM* sqvm, const const SQChar* sError) + { + return __sq_raiseerror(sqvm, sError); + } + + inline void newarray(HSquirrelVM* sqvm, const SQInteger stackpos = 0) + { + __sq_newarray(sqvm, stackpos); + } + + inline SQRESULT arrayappend(HSquirrelVM* sqvm, const SQInteger stackpos) + { + return __sq_arrayappend(sqvm, stackpos); + } + + inline SQRESULT newtable(HSquirrelVM* sqvm) + { + return __sq_newtable(sqvm); + } + + inline SQRESULT newslot(HSquirrelVM* sqvm, SQInteger idx, SQBool bStatic) + { + return __sq_newslot(sqvm, idx, bStatic); + } + + inline void pushroottable(HSquirrelVM* sqvm) + { + __sq_pushroottable(sqvm); + } + + inline void pushstring(HSquirrelVM* sqvm, const SQChar* sVal, int length = -1) + { + __sq_pushstring(sqvm, sVal, length); + } + + inline void pushinteger(HSquirrelVM* sqvm, const SQInteger iVal) + { + __sq_pushinteger(sqvm, iVal); + } + + inline void pushfloat(HSquirrelVM* sqvm, const SQFloat flVal) + { + __sq_pushfloat(sqvm, flVal); + } + + inline void pushbool(HSquirrelVM* sqvm, const SQBool bVal) + { + __sq_pushbool(sqvm, bVal); + } + + inline void pushasset(HSquirrelVM* sqvm, const SQChar* sVal, int length = -1) + { + __sq_pushasset(sqvm, sVal, length); + } + + inline void pushvector(HSquirrelVM* sqvm, const Vector3 pVal) + { + __sq_pushvector(sqvm, *(float**)&pVal); + } + + inline const SQChar* getstring(HSquirrelVM* sqvm, const SQInteger stackpos) + { + return __sq_getstring(sqvm, stackpos); + } + + inline SQInteger getinteger(HSquirrelVM* sqvm, const SQInteger stackpos) + { + return __sq_getinteger(sqvm, stackpos); + } + + inline SQFloat getfloat(HSquirrelVM* sqvm, const SQInteger stackpos) + { + return __sq_getfloat(sqvm, stackpos); + } + + inline SQBool getbool(HSquirrelVM* sqvm, const SQInteger stackpos) + { + return __sq_getbool(sqvm, stackpos); + } + + inline SQRESULT get(HSquirrelVM* sqvm, const SQInteger stackpos) + { + return __sq_get(sqvm, stackpos); + } + + inline Vector3 getvector(HSquirrelVM* sqvm, const SQInteger stackpos) + { + float* pRet = __sq_getvector(sqvm, stackpos); + return *(Vector3*)&pRet; + } + + inline SQRESULT getasset(HSquirrelVM* sqvm, const SQInteger stackpos, const char** result) + { + return __sq_getasset(sqvm, stackpos, result); + } + + template <typename T> inline SQRESULT getuserdata(HSquirrelVM* sqvm, const SQInteger stackpos, T* data, uint64_t* typeId) + { + return __sq_getuserdata(sqvm, stackpos, (void**)data, typeId); // this sometimes crashes idk + } + + template <typename T> inline T* createuserdata(HSquirrelVM* sqvm, SQInteger size) + { + void* ret = __sq_createuserdata(sqvm, size); + memset(ret, 0, size); + return (T*)ret; + } + + inline SQRESULT setuserdatatypeid(HSquirrelVM* sqvm, const SQInteger stackpos, uint64_t typeId) + { + return __sq_setuserdatatypeid(sqvm, stackpos, typeId); + } +#pragma endregion +}; + +template <ScriptContext context> SquirrelManager<context>* g_pSquirrel; diff --git a/NorthstarDLL/squirreldatatypes.h b/NorthstarDLL/squirreldatatypes.h new file mode 100644 index 00000000..818ce2a4 --- /dev/null +++ b/NorthstarDLL/squirreldatatypes.h @@ -0,0 +1,484 @@ +#pragma once +/* + This file has been generated by IDA. + It contains local type definitions from + the type library 'server.dll' +*/ + +struct HSquirrelVM; +struct CallInfo; +struct SQTable; +struct SQString; +struct SQFunctionProto; +struct SQClosure; +struct SQSharedState; +struct StringTable; +struct SQStructInstance; +struct SQStructDef; +struct SQNativeClosure; +struct SQArray; +struct tableNode; +struct SQUserData; + +typedef void (*releasehookType)(void* val, int size); + +/* 127 */ +enum SQObjectType : int +{ + _RT_NULL = 0x1, + _RT_INTEGER = 0x2, + _RT_FLOAT = 0x4, + _RT_BOOL = 0x8, + _RT_STRING = 0x10, + _RT_TABLE = 0x20, + _RT_ARRAY = 0x40, + _RT_USERDATA = 0x80, + _RT_CLOSURE = 0x100, + _RT_NATIVECLOSURE = 0x200, + _RT_GENERATOR = 0x400, + OT_USERPOINTER = 0x800, + _RT_USERPOINTER = 0x800, + _RT_THREAD = 0x1000, + _RT_FUNCPROTO = 0x2000, + _RT_CLASS = 0x4000, + _RT_INSTANCE = 0x8000, + _RT_WEAKREF = 0x10000, + OT_VECTOR = 0x40000, + SQOBJECT_CANBEFALSE = 0x1000000, + OT_NULL = 0x1000001, + OT_BOOL = 0x1000008, + SQOBJECT_DELEGABLE = 0x2000000, + SQOBJECT_NUMERIC = 0x4000000, + OT_INTEGER = 0x5000002, + OT_FLOAT = 0x5000004, + SQOBJECT_REF_COUNTED = 0x8000000, + OT_STRING = 0x8000010, + OT_ARRAY = 0x8000040, + OT_CLOSURE = 0x8000100, + OT_NATIVECLOSURE = 0x8000200, + OT_ASSET = 0x8000400, + OT_THREAD = 0x8001000, + OT_FUNCPROTO = 0x8002000, + OT_CLAAS = 0x8004000, + OT_STRUCT = 0x8200000, + OT_WEAKREF = 0x8010000, + OT_TABLE = 0xA000020, + OT_USERDATA = 0xA000080, + OT_INSTANCE = 0xA008000, + OT_ENTITY = 0xA400000, +}; + +/* 156 */ +union SQObjectValue +{ + SQString* asString; + SQTable* asTable; + SQClosure* asClosure; + SQFunctionProto* asFuncProto; + SQStructDef* asStructDef; + long long as64Integer; + SQNativeClosure* asNativeClosure; + SQArray* asArray; + HSquirrelVM* asThread; + float asFloat; + int asInteger; + SQUserData* asUserdata; +}; + +/* 160 */ +struct SQVector +{ + SQObjectType _Type; + float x; + float y; + float z; +}; + +/* 128 */ +struct SQObject +{ + SQObjectType _Type; + int structNumber; + SQObjectValue _VAL; +}; + +/* 138 */ +struct alignas(8) SQString +{ + void* vftable; + int uiRef; + int padding; + SQString* _next_maybe; + SQSharedState* sharedState; + int length; + unsigned char gap_24[4]; + char _hash[8]; + char _val[1]; +}; + +/* 137 */ +struct alignas(8) SQTable +{ + void* vftable; + unsigned char gap_08[4]; + int uiRef; + unsigned char gap_10[8]; + void* pointer_18; + void* pointer_20; + void* _sharedState; + long long field_30; + tableNode* _nodes; + int _numOfNodes; + int size; + int field_48; + int _usedNodes; + unsigned char _gap_50[20]; + int field_64; + unsigned char _gap_68[80]; +}; + +/* 140 */ +struct alignas(8) SQClosure +{ + void* vftable; + unsigned char gap_08[4]; + int uiRef; + void* pointer_10; + void* pointer_18; + void* pointer_20; + void* sharedState; + SQObject obj_30; + SQObject _function; + SQObject* _outervalues; + unsigned char gap_58[8]; + unsigned char gap_60[96]; + SQObject* objectPointer_C0; + unsigned char gap_C8[16]; +}; + +/* 139 */ +struct alignas(8) SQFunctionProto +{ + void* vftable; + unsigned char gap_08[4]; + int uiRef; + unsigned char gap_10[8]; + void* pointer_18; + void* pointer_20; + void* sharedState; + void* pointer_30; + SQObjectType _fileNameType; + SQString* _fileName; + SQObjectType _funcNameType; + SQString* _funcName; + SQObject obj_58; + unsigned char gap_68[12]; + int _stacksize; + unsigned char gap_78[48]; + int nParameters; + unsigned char gap_AC[60]; + int nDefaultParams; + unsigned char gap_EC[200]; +}; + +/* 152 */ +struct SQStructDef +{ + void* vtable; + int uiRef; + unsigned char padding_C[4]; + unsigned char unknown[24]; + SQSharedState* sharedState; + SQObjectType _nameType; + SQString* _name; + unsigned char gap_38[16]; + SQObjectType _variableNamesType; + SQTable* _variableNames; + unsigned char gap_[32]; +}; + +/* 157 */ +struct alignas(8) SQNativeClosure +{ + void* vftable; + int uiRef; + unsigned char gap_C[4]; + long long value_10; + long long value_18; + long long value_20; + SQSharedState* sharedState; + char unknown_30; + unsigned char padding_34[7]; + long long value_38; + long long value_40; + long long value_48; + long long value_50; + long long value_58; + SQObjectType _nameType; + SQString* _name; + long long value_70; + long long value_78; + unsigned char justInCaseGap_80[300]; +}; + +/* 162 */ +struct SQArray +{ + void* vftable; + int uiRef; + unsigned char gap_24[36]; + SQObject* _values; + int _usedSlots; + int _allocated; +}; + +/* 129 */ +struct alignas(8) HSquirrelVM +{ + void* vftable; + int uiRef; + unsigned char gap_8[12]; + void* _toString; + void* _roottable_pointer; + void* pointer_28; + CallInfo* ci; + CallInfo* _callstack; + int _callsstacksize; + int _stackbase; + SQObject* _stackOfCurrentFunction; + SQSharedState* sharedState; + void* pointer_58; + void* pointer_60; + int _top; + SQObject* _stack; + unsigned char gap_78[8]; + SQObject* _vargvstack; + unsigned char gap_88[8]; + SQObject temp_reg; + unsigned char gapA0[8]; + void* pointer_A8; + unsigned char gap_B0[8]; + SQObject _roottable_object; + SQObject _lasterror; + SQObject _errorHandler; + long long field_E8; + int traps; + unsigned char gap_F4[12]; + int _nnativecalls; + int _suspended; + int _suspended_root; + int _callstacksize; + int _suspended_target; + int trapAmount; + int _suspend_varargs; + int unknown_field_11C; + SQObject object_120; +}; + +/* 150 */ +struct SQStructInstance +{ + void* vftable; + unsigned char gap_8[16]; + void* pointer_18; + unsigned char gap_20[8]; + SQSharedState* _sharedState; + unsigned char gap[8]; + SQObject data[20]; +}; + +/* 148 */ +struct SQSharedState +{ + unsigned char gap_0[72]; + void* unknown; + unsigned char gap_50[16344]; + SQObjectType _unknownTableType00; + long long _unknownTableValue00; + unsigned char gap_4038[16]; + StringTable* _stringTable; + unsigned char gap_4050[32]; + SQObjectType _unknownTableType0; + long long _unknownTableValue0; + SQObjectType _unknownObjectType1; + long long _unknownObjectValue1; + unsigned char gap_4090[8]; + SQObjectType _unknownArrayType2; + long long _unknownArrayValue2; + SQObjectType _gobalsArrayType; + SQStructInstance* _globalsArray; + unsigned char gap_40B8[16]; + SQObjectType _nativeClosuresType; + SQTable* _nativeClosures; + SQObjectType _typedConstantsType; + SQTable* _typedConstants; + SQObjectType _untypedConstantsType; + SQTable* _untypedConstants; + SQObjectType _globalsMaybeType; + SQTable* _globals; + SQObjectType _functionsType; + SQTable* _functions; + SQObjectType _structsType; + SQTable* _structs; + SQObjectType _typeDefsType; + SQTable* _typeDefs; + SQObjectType unknownTableType; + SQTable* unknownTable; + SQObjectType _squirrelFilesType; + SQTable* _squirrelFiles; + unsigned char gap_4158[80]; + SQObjectType _nativeClosures2Type; + SQTable* _nativeClosures2; + SQObjectType _entityTypesMaybeType; + SQTable* _entityTypesMaybe; + SQObjectType unknownTable2Type; + SQTable* unknownTable2; + unsigned char gap_41D8[72]; + SQObjectType _compilerKeywordsType; + SQTable* _compilerKeywords; + HSquirrelVM* _currentThreadMaybe; + unsigned char gap_4238[8]; + SQObjectType unknownTable3Type; + SQTable* unknownTable3; + unsigned char gap_4250[16]; + SQObjectType unknownThreadType; + SQTable* unknownThread; + SQObjectType _tableNativeFunctionsType; + SQTable* _tableNativeFunctions; + SQObjectType _unknownTableType4; + long long _unknownObjectValue4; + SQObjectType _unknownObjectType5; + long long _unknownObjectValue5; + SQObjectType _unknownObjectType6; + long long _unknownObjectValue6; + SQObjectType _unknownObjectType7; + long long _unknownObjectValue7; + SQObjectType _unknownObjectType8; + long long _unknownObjectValue8; + SQObjectType _unknownObjectType9; + long long _unknownObjectValue9; + SQObjectType _unknownObjectType10; + long long _unknownObjectValue10; + SQObjectType _unknownObjectType11; + long long _unknownObjectValue11; + SQObjectType _unknownObjectType12; + long long _unknownObjectValue12; + SQObjectType _unknownObjectType13; + long long _unknownObjectValue13; + SQObjectType _unknownObjectType14; + long long _unknownObjectValue14; + SQObjectType _unknownObjectType15; + long long _unknownObjectValue15; + unsigned char gap_4340[16]; + void* printFunction; + unsigned char gap_4358[16]; + void* logEntityFunction; + unsigned char gap_4370[40]; + SQObjectType _waitStringType; + SQString* _waitStringValue; + SQObjectType _SpinOffAndWaitForStringType; + SQString* _SpinOffAndWaitForStringValue; + SQObjectType _SpinOffAndWaitForSoloStringType; + SQString* _SpinOffAndWaitForSoloStringValue; + SQObjectType _SpinOffStringType; + SQString* _SpinOffStringValue; + SQObjectType _SpinOffDelayedStringType; + SQString* _SpinOffDelayedStringValue; + unsigned char gap_43E8[8]; + bool enableDebugInfo; // functionality stripped + unsigned char gap_43F1[23]; +}; + +/* 165 */ +struct tableNode +{ + SQObject val; + SQObject key; + tableNode* next; +}; + +/* 136 */ +struct alignas(8) CallInfo +{ + long long ip; + SQObject* _literals; + SQObject obj10; + SQObject closure; + int _etraps[4]; + int _root; + short _vargs_size; + short _vargs_base; + unsigned char gap[16]; +}; + +/* 149 */ +struct StringTable +{ + unsigned char gap_0[12]; + int _numofslots; + unsigned char gap_10[200]; +}; + +/* 141 */ +struct alignas(8) SQStackInfos +{ + char* _name; + char* _sourceName; + int _line; +}; + +/* 151 */ +struct alignas(4) SQInstruction +{ + int op; + int arg1; + int output; + short arg2; + short arg3; +}; + +/* 154 */ +struct SQLexer +{ + unsigned char gap_0[112]; +}; + +/* 153 */ +struct SQCompiler +{ + unsigned char gap_0[4]; + int _token; + unsigned char gap_8[8]; + SQObject object_10; + SQLexer lexer; + unsigned char gap_90[752]; + HSquirrelVM* sqvm; + unsigned char gap_288[8]; +}; + +/* 155 */ +struct CSquirrelVM +{ + unsigned char gap_0[8]; + HSquirrelVM* sqvm; + unsigned char gap_10[44]; + int loadEnumFromFileMaybe; + unsigned char gap_40[200]; +}; + +struct SQUserData +{ + void* vftable; + int uiRef; + char gap_12[4]; + long long unknown_10; + long long unknown_18; + long long unknown_20; + long long sharedState; + long long unknown_30; + int size; + char padding1[4]; + releasehookType releaseHook; + long long typeId; + char data[1]; +}; diff --git a/NorthstarDLL/tier0.cpp b/NorthstarDLL/tier0.cpp new file mode 100644 index 00000000..61ad7783 --- /dev/null +++ b/NorthstarDLL/tier0.cpp @@ -0,0 +1,37 @@ +#include "pch.h" +#include "tier0.h" + +// use the Tier0 namespace for tier0 funcs +namespace Tier0 +{ + IMemAlloc* g_pMemAllocSingleton; + + ErrorType Error; + CommandLineType CommandLine; + Plat_FloatTimeType Plat_FloatTime; + ThreadInServerFrameThreadType ThreadInServerFrameThread; +} // namespace Tier0 + +typedef Tier0::IMemAlloc* (*CreateGlobalMemAllocType)(); +CreateGlobalMemAllocType CreateGlobalMemAlloc; + +// needs to be a seperate function, since memalloc.cpp calls it +void TryCreateGlobalMemAlloc() +{ + // init memalloc stuff + CreateGlobalMemAlloc = + reinterpret_cast<CreateGlobalMemAllocType>(GetProcAddress(GetModuleHandleA("tier0.dll"), "CreateGlobalMemAlloc")); + Tier0::g_pMemAllocSingleton = CreateGlobalMemAlloc(); // if it already exists, this returns the preexisting IMemAlloc instance +} + +ON_DLL_LOAD("tier0.dll", Tier0GameFuncs, (CModule module)) +{ + // shouldn't be necessary, but do this just in case + TryCreateGlobalMemAlloc(); + + // setup tier0 funcs + Tier0::Error = module.GetExport("Error").As<Tier0::ErrorType>(); + Tier0::CommandLine = module.GetExport("CommandLine").As<Tier0::CommandLineType>(); + Tier0::Plat_FloatTime = module.GetExport("Plat_FloatTime").As<Tier0::Plat_FloatTimeType>(); + Tier0::ThreadInServerFrameThread = module.GetExport("ThreadInServerFrameThread").As<Tier0::ThreadInServerFrameThreadType>(); +} diff --git a/NorthstarDLL/tier0.h b/NorthstarDLL/tier0.h new file mode 100644 index 00000000..92a63027 --- /dev/null +++ b/NorthstarDLL/tier0.h @@ -0,0 +1,68 @@ +#pragma once +namespace Tier0 +{ + class IMemAlloc + { + public: + struct VTable + { + void* unknown[1]; // alloc debug + void* (*Alloc)(IMemAlloc* memAlloc, size_t nSize); + void* unknown2[1]; // realloc debug + void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize); + void* unknown3[1]; // free #1 + void (*Free)(IMemAlloc* memAlloc, void* pMem); + void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag + size_t (*GetSize)(IMemAlloc* memAlloc, void* pMem); + void* unknown5[9]; // they all do literally nothing + void (*DumpStats)(IMemAlloc* memAlloc); + void (*DumpStatsFileBase)(IMemAlloc* memAlloc, const char* pchFileBase); + void* unknown6[4]; + int (*heapchk)(IMemAlloc* memAlloc); + }; + + VTable* m_vtable; + }; + + class CCommandLine + { + public: + // based on the defs in the 2013 source sdk, but for some reason has an extra function (may be another CreateCmdLine overload?) + // these seem to line up with what they should be though + virtual void CreateCmdLine(const char* commandline) {} + virtual void CreateCmdLine(int argc, char** argv) {} + virtual void unknown() {} + virtual const char* GetCmdLine(void) const {} + + virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const {} + virtual void RemoveParm() const {} + virtual void AppendParm(const char* pszParm, const char* pszValues) {} + + virtual const char* ParmValue(const char* psz, const char* pDefaultVal = 0) const {} + virtual int ParmValue(const char* psz, int nDefaultVal) const {} + virtual float ParmValue(const char* psz, float flDefaultVal) const {} + + virtual int ParmCount() const {} + virtual int FindParm(const char* psz) const {} + virtual const char* GetParm(int nIndex) const {} + virtual void SetParm(int nIndex, char const* pParm) {} + + // virtual const char** GetParms() const {} + }; + + extern IMemAlloc* g_pMemAllocSingleton; + + typedef void (*ErrorType)(const char* fmt, ...); + extern ErrorType Error; + + typedef CCommandLine* (*CommandLineType)(); + extern CommandLineType CommandLine; + + typedef double (*Plat_FloatTimeType)(); + extern Plat_FloatTimeType Plat_FloatTime; + + typedef bool (*ThreadInServerFrameThreadType)(); + extern ThreadInServerFrameThreadType ThreadInServerFrameThread; +} // namespace Tier0 + +void TryCreateGlobalMemAlloc(); diff --git a/NorthstarDLL/vector.h b/NorthstarDLL/vector.h new file mode 100644 index 00000000..c06e0bba --- /dev/null +++ b/NorthstarDLL/vector.h @@ -0,0 +1,52 @@ +#pragma once
+
+union Vector3
+{
+ struct
+ {
+ float x;
+ float y;
+ float z;
+ };
+
+ float raw[3];
+
+ Vector3() : x(0), y(0), z(0) {}
+ Vector3(float x, float y, float z) : x(x), y(y), z(z) {}
+ Vector3(float* pRawFloats) // assumes float[3] => vector
+ {
+ memcpy(raw, pRawFloats, sizeof(this));
+ }
+
+ void MakeValid()
+ {
+ for (auto& fl : raw)
+ if (isnan(fl))
+ fl = 0;
+ }
+
+ // todo: more operators maybe
+ bool operator==(const Vector3& other)
+ {
+ return x == other.x && y == other.y && z == other.z;
+ }
+};
+
+union QAngle
+{
+ struct
+ {
+ float x;
+ float y;
+ float z;
+ float w;
+ };
+
+ float raw[4];
+
+ // todo: more operators maybe
+ bool operator==(const QAngle& other)
+ {
+ return x == other.x && y == other.y && z == other.z && w == other.w;
+ }
+};
diff --git a/NorthstarDedicatedTest/version.cpp b/NorthstarDLL/version.cpp index 3755e4c4..3755e4c4 100644 --- a/NorthstarDedicatedTest/version.cpp +++ b/NorthstarDLL/version.cpp diff --git a/NorthstarDedicatedTest/version.h b/NorthstarDLL/version.h index d9d29fec..261a4cf1 100644 --- a/NorthstarDedicatedTest/version.h +++ b/NorthstarDLL/version.h @@ -3,4 +3,4 @@ extern char version[16]; extern char NSUserAgent[32]; -void InitialiseVersion();
\ No newline at end of file +void InitialiseVersion(); diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp deleted file mode 100644 index db754ad5..00000000 --- a/NorthstarDedicatedTest/ExploitFixes.cpp +++ /dev/null @@ -1,419 +0,0 @@ -#include "pch.h" - -#include "ExploitFixes.h" -#include "ExploitFixes_UTF8Parser.h" -#include "NSMem.h" -#include "cvar.h" - -ConVar* ns_exploitfixes_log; -#define SHOULD_LOG (ns_exploitfixes_log->m_Value.m_nValue > 0) -#define BLOCKED_INFO(s) \ - ( \ - [=]() -> bool \ - { \ - if (SHOULD_LOG) \ - { \ - std::stringstream stream; \ - stream << "ExploitFixes.cpp: " << BLOCK_PREFIX << s; \ - spdlog::error(stream.str()); \ - } \ - return false; \ - }()) - -// Make sure 3 or less floats are valid -bool ValidateFloats(float a, float b = 0, float c = 0) -{ - return !isnan(a) && !isnan(b) && !isnan(c); -} - -struct Vector -{ - float x, y, z; - - Vector(float x = 0, float y = 0, float z = 0) : x(x), y(y), z(z) {} - - bool IsValid() - { - return ValidateFloats(x, y, z); - } -}; - -struct Angle -{ - float pitch, yaw, roll; - - Angle(float pitch = 0, float yaw = 0, float roll = 0) : pitch(pitch), yaw(yaw), roll(roll) {} - - bool IsInvalid() - { - if (!ValidateFloats(pitch, yaw, roll)) - return false; - - return (pitch > 90 || pitch < -90) || (yaw > 180 || yaw < -180) || (roll > 180 || roll < -180); - } -}; - -#define BLOCK_NETMSG_FUNC(name, pattern) \ - KHOOK(name, ("engine.dll", pattern), bool, __fastcall, (void* thisptr, void* buffer)) \ - { \ - return false; \ - } - -// Servers can literally request a screenshot from any client, yeah no -BLOCK_NETMSG_FUNC(CLC_Screenshot_WriteToBuffer, "48 89 5C 24 ? 57 48 83 EC 20 8B 42 10"); -BLOCK_NETMSG_FUNC(CLC_Screenshot_ReadFromBuffer, "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B DA 48 8B 52 38"); - -// This is unused ingame and a big exploit vector -BLOCK_NETMSG_FUNC(Base_CmdKeyValues_ReadFromBuffer, "40 55 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 5D 70"); - -KHOOK(CClient_ProcessSetConVar, ("engine.dll", "48 8B D1 48 8B 49 18 48 8B 01 48 FF 60 10"), bool, __fastcall, (void* pMsg)) -{ - - constexpr int ENTRY_STR_LEN = 260; - struct SetConVarEntry - { - char name[ENTRY_STR_LEN]; - char val[ENTRY_STR_LEN]; - }; - - struct NET_SetConVar - { - void* vtable; - void* unk1; - void* unk2; - void* m_pMessageHandler; - SetConVarEntry* m_ConVars; // convar entry array - void* unk5; // these 2 unks are just vector capacity or whatever - void* unk6; - int m_ConVars_count; // amount of cvar entries in array (this will not be out of bounds) - }; - - auto msg = (NET_SetConVar*)pMsg; - - bool areWeServer; - - { - // Figure out of we are the client or the server - // To do this, we utilize the msg's m_pMessageHandler pointer - // m_pMessageHandler points to a virtual class that handles all net messages - // The first virtual table function of our m_pMessageHandler will differ if it is IServerMessageHandler or IClientMessageHandler - void* msgHandlerVTableFirstFunc = **(void****)(msg->m_pMessageHandler); - static auto engineBaseAddress = (uintptr_t)GetModuleHandleA("engine.dll"); - auto offset = uintptr_t(msgHandlerVTableFirstFunc) - engineBaseAddress; - - constexpr uintptr_t CLIENTSTATE_FIRST_VFUNC_OFFSET = 0x8A15C; - areWeServer = offset != CLIENTSTATE_FIRST_VFUNC_OFFSET; - } - - std::string BLOCK_PREFIX = std::string {"NET_SetConVar ("} + (areWeServer ? "server" : "client") + "): Blocked dangerous/invalid msg: "; - - if (areWeServer) - { - constexpr int SETCONVAR_SANITY_AMOUNT_LIMIT = 69; - if (msg->m_ConVars_count < 1 || msg->m_ConVars_count > SETCONVAR_SANITY_AMOUNT_LIMIT) - { - return BLOCKED_INFO("Invalid m_ConVars_count (" << msg->m_ConVars_count << ")"); - } - } - - for (int i = 0; i < msg->m_ConVars_count; i++) - { - auto entry = msg->m_ConVars + i; - - // Safety check for memory access - if (NSMem::IsMemoryReadable(entry, sizeof(*entry))) - { - - // Find null terminators - bool nameValid = false, valValid = false; - for (int i = 0; i < ENTRY_STR_LEN; i++) - { - if (!entry->name[i]) - nameValid = true; - if (!entry->val[i]) - valValid = true; - } - - if (!nameValid || !valValid) - return BLOCKED_INFO("Missing null terminators"); - - auto realVar = g_pCVar->FindVar(entry->name); - - if (realVar) - memcpy( - entry->name, - realVar->m_ConCommandBase.m_pszName, - strlen(realVar->m_ConCommandBase.m_pszName) + 1); // Force name to match case - - bool isValidFlags = true; - if (areWeServer) - { - if (realVar) - isValidFlags = ConVar::IsFlagSet(realVar, FCVAR_USERINFO); // ConVar MUST be userinfo var - } - else - { - // TODO: Should probably have some sanity checks, but can't find any that are consistent - } - - if (!isValidFlags) - { - if (!realVar) - { - return BLOCKED_INFO("Invalid flags on nonexistant cvar (how tho???)"); - } - else - { - return BLOCKED_INFO( - "Invalid flags (" << std::hex << "0x" << realVar->m_ConCommandBase.m_nFlags << "), var is " << entry->name); - } - } - } - else - { - return BLOCKED_INFO("Unreadable memory at " << (void*)entry); // Not risking that one, they all gotta be readable - } - } - - return oCClient_ProcessSetConVar(msg); -} - -// Purpose: prevent invalid user CMDs -KHOOK(CClient_ProcessUsercmds, ("engine.dll", "40 55 56 48 83 EC 58"), bool, __fastcall, (void* thisptr, void* pMsg)) -{ - struct CLC_Move - { - BYTE gap0[24]; - void* m_pMessageHandler; - int m_nBackupCommands; - int m_nNewCommands; - int m_nLength; - // bf_read m_DataIn; - // bf_write m_DataOut; - }; - - auto msg = (CLC_Move*)pMsg; - - const char* BLOCK_PREFIX = "ProcessUserCmds: "; - - if (msg->m_nBackupCommands < 0) - { - return BLOCKED_INFO("Invalid m_nBackupCommands (" << msg->m_nBackupCommands << ")"); - } - - if (msg->m_nNewCommands < 0) - { - return BLOCKED_INFO("Invalid m_nNewCommands (" << msg->m_nNewCommands << ")"); - } - - constexpr int NUMCMD_SANITY_LIMIT = 16; - if ((msg->m_nNewCommands + msg->m_nBackupCommands) > NUMCMD_SANITY_LIMIT) - { - return BLOCKED_INFO("Command count is too high (new: " << msg->m_nNewCommands << ", backup: " << msg->m_nBackupCommands << ")"); - } - - if (msg->m_nLength <= 0) - return BLOCKED_INFO("Invalid message length (" << msg->m_nLength << ")"); - - return oCClient_ProcessUsercmds(thisptr, pMsg); -} - -KHOOK(ReadUsercmd, ("server.dll", "4C 89 44 24 ? 53 55 56 57"), void, __fastcall, (void* buf, void* pCmd_move, void* pCmd_from)) -{ - // Let normal usercmd read happen first, it's safe - oReadUsercmd(buf, pCmd_move, pCmd_from); - - // Now let's make sure the CMD we read isnt messed up to prevent numerous exploits (including server crashing) - struct __declspec(align(4)) SV_CUserCmd - { - DWORD command_number; - DWORD tick_count; - float command_time; - Angle worldViewAngles; - BYTE gap18[4]; - Angle localViewAngles; - Angle attackangles; - Vector move; - DWORD buttons; - BYTE impulse; - short weaponselect; - DWORD meleetarget; - BYTE gap4C[24]; - char headoffset; - BYTE gap65[11]; - Vector cameraPos; - Angle cameraAngles; - BYTE gap88[4]; - int tickSomething; - DWORD dword90; - DWORD predictedServerEventAck; - DWORD dword98; - float frameTime; - }; - - auto cmd = (SV_CUserCmd*)pCmd_move; - auto fromCmd = (SV_CUserCmd*)pCmd_from; - - std::string BLOCK_PREFIX = - "ReadUsercmd (command_number delta: " + std::to_string(cmd->command_number - fromCmd->command_number) + "): "; - - if (cmd->worldViewAngles.IsInvalid()) - { - BLOCKED_INFO("CMD has invalid worldViewAngles"); - goto INVALID_CMD; - } - - if (cmd->attackangles.IsInvalid()) - { - BLOCKED_INFO("CMD has invalid attackangles"); - goto INVALID_CMD; - } - - if (cmd->localViewAngles.IsInvalid()) - { - BLOCKED_INFO("CMD has invalid localViewAngles"); - goto INVALID_CMD; - } - - if (cmd->cameraAngles.IsInvalid()) - { - BLOCKED_INFO("CMD has invalid cameraAngles"); - goto INVALID_CMD; - } - - if (cmd->frameTime <= 0 || cmd->tick_count == 0 || cmd->command_time <= 0) - { - BLOCKED_INFO( - "Bogus cmd timing (tick_count: " << cmd->tick_count << ", frameTime: " << cmd->frameTime - << ", commandTime : " << cmd->command_time << ")"); - goto INVALID_CMD; // No simulation of bogus-timed cmds - } - - if (!cmd->move.IsValid()) - { - BLOCKED_INFO("Invalid move vector"); - goto INVALID_CMD; - } - - if (!cmd->cameraPos.IsValid()) - { - BLOCKED_INFO("Invalid cameraPos"); // IIRC this can crash spectating clients or anyone watching replays - goto INVALID_CMD; - } - - return; -INVALID_CMD: - - // Fix any gameplay-affecting cmd properties - // NOTE: Currently tickcount/frametime is set to 0, this ~shouldn't~ cause any problems - cmd->worldViewAngles = cmd->localViewAngles = cmd->attackangles = cmd->cameraAngles = Angle(0, 0, 0); - cmd->tick_count = cmd->frameTime = 0; - cmd->move = cmd->cameraPos = Vector(0, 0, 0); - cmd->buttons = 0; - cmd->meleetarget = 0; -} - -// basically: by default r2 isn't set as a valve mod, meaning that m_bRestrictServerCommands is false -// this is HORRIBLE for security, because it means servers can run arbitrary concommands on clients -// especially since we have script commands this could theoretically be awful -#include "gameutils.h" -KHOOK(IsValveMod, ("engine.dll", "48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? E8 ? ? ? ? 85 C0 74 63"), bool, __fastcall, ()) -{ - return !CommandLine()->CheckParm("-norestrictservercommands"); -} - -// Fix respawn's crappy UTF8 parser so it doesn't crash -_- -// This also means you can launch multiplayer with "communities_enabled 1" and not crash, you're welcome -KHOOK( - CrashFunc_ParseUTF8, - ("engine.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC 20 8B 1A"), - bool, - __fastcall, - (INT64 * a1, DWORD* a2, char* strData)) -{ - - static void* targetRetAddr = NSMem::PatternScan("engine.dll", "84 C0 75 2C 49 8B 16"); - - if (_ReturnAddress() == targetRetAddr) - { - if (!ExploitFixes_UTF8Parser::CheckValid(a1, a2, strData)) - { - const char* BLOCK_PREFIX = "ParseUTF8 Hook: "; - BLOCKED_INFO("Ignoring potentially-crashing utf8 string"); - return false; - } - } - - return oCrashFunc_ParseUTF8(a1, a2, strData); -} - -////////////////////////////////////////////////// - -void DoBytePatches() -{ - uintptr_t engineBase = (uintptr_t)GetModuleHandleA("engine.dll"); - uintptr_t serverBase = (uintptr_t)GetModuleHandleA("server.dll"); - - // patches to make commands run from client/ui script still work - // note: this is likely preventable in a nicer way? test prolly - NSMem::BytePatch(engineBase + 0x4FB65, "EB 11"); - NSMem::BytePatch(engineBase + 0x4FBAC, "EB 16"); - - // disconnect concommand - { - uintptr_t addr = engineBase + 0x5ADA2D; - int val = *(int*)addr | FCVAR_SERVER_CAN_EXECUTE; - NSMem::BytePatch(addr, (BYTE*)&val, sizeof(int)); - } - - { // Dumb ANTITAMPER patches (they negatively impact performance and security) - - constexpr const char* ANTITAMPER_EXPORTS[] = { - "ANTITAMPER_SPOTCHECK_CODEMARKER", - "ANTITAMPER_TESTVALUE_CODEMARKER", - "ANTITAMPER_TRIGGER_CODEMARKER", - }; - - // Prevent thesefrom actually doing anything - for (auto exportName : ANTITAMPER_EXPORTS) - { - - auto address = (uintptr_t)GetProcAddress(GetModuleHandleA("server.dll"), exportName); - if (!address) - { - spdlog::warn("Failed to find AntiTamper function export \"{}\"", exportName); - } - else - { - // Just return, none of them have any args or are userpurge - NSMem::BytePatch(address, "C3"); - - spdlog::info("Patched AntiTamper function export \"{}\"", exportName); - } - } - } -} - -void ExploitFixes::LoadCallback(HMODULE unused) -{ - spdlog::info("ExploitFixes::LoadCallback ..."); - - spdlog::info("\tByte patching..."); - DoBytePatches(); - - if (KHook::InitAllHooks()) - { - spdlog::info("\tInitialized " + std::to_string(KHook::_allHooks.size()) + " exploit-patch hooks."); - } - else - { - spdlog::critical("\tFAILED to initialize all exploit patches."); - - // Force exit? - MessageBoxA(0, "FAILED to initialize all exploit patches.", "Northstar", MB_ICONERROR); - exit(0); - } - - ns_exploitfixes_log = - new ConVar("ns_exploitfixes_log", "1", FCVAR_GAMEDLL, "Whether to log whenever ExploitFixes.cpp blocks/corrects something"); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/ExploitFixes.h b/NorthstarDedicatedTest/ExploitFixes.h deleted file mode 100644 index 7a407a3d..00000000 --- a/NorthstarDedicatedTest/ExploitFixes.h +++ /dev/null @@ -1,9 +0,0 @@ -// KittenPopo's exploit fix hooks, feel free to add more here - -#pragma once -#include "pch.h" - -namespace ExploitFixes -{ - void LoadCallback(HMODULE unused); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/ExploitFixes_UTF8Parser.h b/NorthstarDedicatedTest/ExploitFixes_UTF8Parser.h deleted file mode 100644 index 41242655..00000000 --- a/NorthstarDedicatedTest/ExploitFixes_UTF8Parser.h +++ /dev/null @@ -1,175 +0,0 @@ -// Reimplementation of a exploitable UTF decoding function in titanfall - -#include "NSMem.h" - -#pragma once - -namespace ExploitFixes_UTF8Parser -{ - bool __fastcall CheckValid(INT64* a1, DWORD* a2, char* strData) - { - static auto sub_F1320 = (INT64(__fastcall*)(DWORD a1, char* a2))NSMem::PatternScan("engine.dll", "83 F9 7F 77 08 88 0A"); - - DWORD v3; // eax - char* v4; // rbx - char v5; // si - char* _strData; // rdi - char* v7; // rbp - char v11; // al - DWORD v12; // er9 - DWORD v13; // ecx - DWORD v14; // edx - DWORD v15; // er8 - int v16; // eax - DWORD v17; // er9 - int v18; // eax - DWORD v19; // er9 - DWORD v20; // ecx - int v21; // eax - int v22; // er9 - DWORD v23; // edx - int v24; // eax - int v25; // er9 - DWORD v26; // er9 - DWORD v27; // er10 - DWORD v28; // ecx - DWORD v29; // edx - DWORD v30; // er8 - int v31; // eax - DWORD v32; // er10 - int v33; // eax - DWORD v34; // er10 - DWORD v35; // ecx - int v36; // eax - int v37; // er10 - DWORD v38; // edx - int v39; // eax - int v40; // er10 - DWORD v41; // er10 - INT64 v43; // r8 - INT64 v44; // rdx - INT64 v45; // rcx - INT64 v46; // rax - INT64 v47; // rax - char v48; // al - INT64 v49; // r8 - INT64 v50; // rdx - INT64 v51; // rcx - INT64 v52; // rax - INT64 v53; // rax - - v3 = a2[2]; - v4 = (char*)(a1[1] + *a2); - v5 = 0; - _strData = strData; - v7 = &v4[*((UINT16*)a2 + 2)]; - if (v3 >= 2) - { - ++v4; - --v7; - if (v3 != 2) - { - while (1) - { - - if (!NSMem::IsMemoryReadable(v4, 1)) - return false; // INVALID - - v11 = *v4++; // crash potential - if (v11 != 92) - goto LABEL_6; - v11 = *v4++; - if (v11 == 110) - break; - switch (v11) - { - case 't': - v11 = 9; - goto LABEL_6; - case 'r': - v11 = 13; - goto LABEL_6; - case 'b': - v11 = 8; - goto LABEL_6; - case 'f': - v11 = 12; - goto LABEL_6; - } - if (v11 != 117) - goto LABEL_6; - v12 = *v4 | 0x20; - v13 = v4[1] | 0x20; - v14 = v4[2] | 0x20; - v15 = v4[3] | 0x20; - v16 = 87; - if (v12 <= 0x39) - v16 = 48; - v17 = v12 - v16; - v18 = 87; - v19 = v17 << 12; - if (v13 <= 0x39) - v18 = 48; - v20 = v13 - v18; - v21 = 87; - v22 = (v20 << 8) | v19; - if (v14 <= 0x39) - v21 = 48; - v23 = v14 - v21; - v24 = 87; - v25 = (16 * v23) | v22; - if (v15 <= 0x39) - v24 = 48; - v4 += 4; - v26 = (v15 - v24) | v25; - if (v26 - 55296 <= 0x7FF) - { - if (v26 >= 0xDC00) - return true; - if (*v4 != 92 || v4[1] != 117) - return true; - - v27 = v4[2] | 0x20; - v28 = v4[3] | 0x20; - v29 = v4[4] | 0x20; - v30 = v4[5] | 0x20; - v31 = 87; - if (v27 <= 0x39) - v31 = 48; - v32 = v27 - v31; - v33 = 87; - v34 = v32 << 12; - if (v28 <= 0x39) - v33 = 48; - v35 = v28 - v33; - v36 = 87; - v37 = (v35 << 8) | v34; - if (v29 <= 0x39) - v36 = 48; - v38 = v29 - v36; - v39 = 87; - v40 = (16 * v38) | v37; - if (v30 <= 0x39) - v39 = 48; - v4 += 6; - v41 = ((v30 - v39) | v40) - 56320; - if (v41 > 0x3FF) - return true; - v26 = v41 | ((v26 - 55296) << 10); - } - _strData += (DWORD)sub_F1320(v26, _strData); - LABEL_7: - if (v4 == v7) - goto LABEL_48; - } - v11 = 10; - LABEL_6: - v5 |= v11; - *_strData++ = v11; - goto LABEL_7; - } - } - LABEL_48: - return true; - } -} // namespace ExploitFixes_UTF8Parser
\ No newline at end of file diff --git a/NorthstarDedicatedTest/NSMem.h b/NorthstarDedicatedTest/NSMem.h deleted file mode 100644 index 74df3a84..00000000 --- a/NorthstarDedicatedTest/NSMem.h +++ /dev/null @@ -1,211 +0,0 @@ -#pragma once -#include "pch.h" - -// KittenPopo's memory stuff, made for northstar (because I really can't handle working with northstar's original memory stuff tbh) - -#pragma region Pattern Scanning -namespace NSMem -{ - inline std::vector<int> HexBytesToString(const char* str) - { - std::vector<int> patternNums; - int size = strlen(str); - for (int i = 0; i < size; i++) - { - char c = str[i]; - - // If this is a space character, ignore it - if (c == ' ' || c == '\t') - continue; - - if (c == '?') - { - // Add a wildcard (-1) - patternNums.push_back(-1); - } - else if (i < size - 1) - { - BYTE result = 0; - for (int j = 0; j < 2; j++) - { - int val = 0; - char c = *(str + i + j); - if (c >= 'a') - { - val = c - 'a' + 0xA; - } - else if (c >= 'A') - { - val = c - 'A' + 0xA; - } - else if (isdigit(c)) - { - val = c - '0'; - } - else - { - assert(false, "Failed to parse invalid hex string."); - val = -1; - } - - result += (j == 0) ? val * 16 : val; - } - patternNums.push_back(result); - } - - i++; - } - - return patternNums; - } - - inline void* PatternScan(void* module, const int* pattern, int patternSize, int offset) - { - if (!module) - return NULL; - - auto dosHeader = (PIMAGE_DOS_HEADER)module; - auto ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)module + dosHeader->e_lfanew); - - auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage; - - auto scanBytes = (BYTE*)module; - - for (auto i = 0; i < sizeOfImage - patternSize; ++i) - { - bool found = true; - for (auto j = 0; j < patternSize; ++j) - { - if (scanBytes[i + j] != pattern[j] && pattern[j] != -1) - { - found = false; - break; - } - } - - if (found) - { - uintptr_t addressInt = (uintptr_t)(&scanBytes[i]) + offset; - return (uint8_t*)addressInt; - } - } - - return nullptr; - } - - inline void* PatternScan(const char* moduleName, const char* pattern, int offset = 0) - { - std::vector<int> patternNums = HexBytesToString(pattern); - - return PatternScan(GetModuleHandleA(moduleName), &patternNums[0], patternNums.size(), offset); - } - - inline void BytePatch(uintptr_t address, const BYTE* vals, int size) - { - WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, vals, size, NULL); - } - - inline void BytePatch(uintptr_t address, std::initializer_list<BYTE> vals) - { - std::vector<BYTE> bytes = vals; - if (!bytes.empty()) - BytePatch(address, &bytes[0], bytes.size()); - } - - inline void BytePatch(uintptr_t address, const char* bytesStr) - { - std::vector<int> byteInts = HexBytesToString(bytesStr); - std::vector<BYTE> bytes; - for (int v : byteInts) - bytes.push_back(v); - - if (!bytes.empty()) - BytePatch(address, &bytes[0], bytes.size()); - } - - inline void NOP(uintptr_t address, int size) - { - BYTE* buf = (BYTE*)malloc(size); - memset(buf, 0x90, size); - BytePatch(address, buf, size); - free(buf); - } - - inline bool IsMemoryReadable(void* ptr, size_t size) - { - static SYSTEM_INFO sysInfo; - if (!sysInfo.dwPageSize) - GetSystemInfo(&sysInfo); // This should always be 4096 unless ur playing on NES or some shit but whatever - - MEMORY_BASIC_INFORMATION memInfo; - - if (!VirtualQuery(ptr, &memInfo, sizeof(memInfo))) - return false; - - if (memInfo.RegionSize < size) - return false; - - return (memInfo.State & MEM_COMMIT) && !(memInfo.Protect & PAGE_NOACCESS); - } -} // namespace NSMem - -#pragma region KHOOK -struct KHookPatternInfo -{ - const char *moduleName, *pattern; - int offset = 0; - - KHookPatternInfo(const char* moduleName, const char* pattern, int offset = 0) : moduleName(moduleName), pattern(pattern), offset(offset) - { - } -}; - -struct KHook -{ - KHookPatternInfo targetFunc; - void* targetFuncAddr; - void* hookFunc; - void** original; - - static inline std::vector<KHook*> _allHooks; - - KHook(KHookPatternInfo targetFunc, void* hookFunc, void** original) : targetFunc(targetFunc) - { - this->hookFunc = hookFunc; - this->original = original; - _allHooks.push_back(this); - } - - bool Setup() - { - targetFuncAddr = NSMem::PatternScan(targetFunc.moduleName, targetFunc.pattern, targetFunc.offset); - if (!targetFuncAddr) - return false; - - return MH_CreateHook(targetFuncAddr, hookFunc, original) == MH_OK; - } - - // Returns true if succeeded - static bool InitAllHooks() - { - for (KHook* hook : _allHooks) - { - if (hook->Setup()) - { - spdlog::info("KHook hooked at {}", hook->targetFuncAddr); - } - else - { - return false; - } - } - - return MH_EnableHook(MH_ALL_HOOKS) == MH_OK; - } -}; -#define KHOOK(name, funcPatternInfo, returnType, convention, args) \ - returnType convention hk##name args; \ - auto o##name = (returnType(convention*) args)0; \ - KHook k##name = KHook(KHookPatternInfo funcPatternInfo, &hk##name, (void**)&o##name); \ - returnType convention hk##name args -#pragma endregion
\ No newline at end of file diff --git a/NorthstarDedicatedTest/bansystem.cpp b/NorthstarDedicatedTest/bansystem.cpp deleted file mode 100644 index 93cf9c65..00000000 --- a/NorthstarDedicatedTest/bansystem.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once -#include "pch.h" -#include "bansystem.h" -#include "serverauthentication.h" -#include "concommand.h" -#include "miscserverscript.h" -#include <filesystem> -#include "configurables.h" - -const char* BANLIST_PATH_SUFFIX = "/banlist.txt"; - -ServerBanSystem* g_ServerBanSystem; - -void ServerBanSystem::OpenBanlist() -{ - std::ifstream enabledModsStream(GetNorthstarPrefix() + "/banlist.txt"); - std::stringstream enabledModsStringStream; - - if (!enabledModsStream.fail()) - { - std::string line; - while (std::getline(enabledModsStream, line)) - m_vBannedUids.push_back(strtoll(line.c_str(), nullptr, 10)); - - enabledModsStream.close(); - } - - // open write stream for banlist - m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary | std::ofstream::app); -} - -void ServerBanSystem::ClearBanlist() -{ - m_vBannedUids.clear(); - - // reopen the file, don't provide std::ofstream::app so it clears on open - m_sBanlistStream.close(); - m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary); -} - -void ServerBanSystem::BanUID(uint64_t uid) -{ - m_vBannedUids.push_back(uid); - m_sBanlistStream << std::to_string(uid) << std::endl; - spdlog::info("{} was banned", uid); -} - -void ServerBanSystem::UnbanUID(uint64_t uid) -{ - auto findResult = std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid); - if (findResult == m_vBannedUids.end()) - return; - - m_vBannedUids.erase(findResult); - spdlog::info("{} was unbanned", uid); - // todo: this needs to erase from the banlist file - // atm unsure how to do this aside from just clearing and fully rewriting the file -} - -bool ServerBanSystem::IsUIDAllowed(uint64_t uid) -{ - return std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid) == m_vBannedUids.end(); -} - -void BanPlayerCommand(const CCommand& args) -{ - if (args.ArgC() < 2) - return; - - // assuming maxplayers 32 - for (int i = 0; i < 32; i++) - { - void* player = GetPlayerByIndex(i); - - if (!strcmp((char*)player + 0x16, args.Arg(1)) || !strcmp((char*)player + 0xF500, args.Arg(1))) - { - g_ServerBanSystem->BanUID(strtoll((char*)player + 0xF500, nullptr, 10)); - CBaseClient__Disconnect(player, 1, "Banned from server"); - break; - } - } -} - -void UnbanPlayerCommand(const CCommand& args) -{ - if (args.ArgC() < 2) - return; - - // assumedly the player being unbanned here wasn't already connected, so don't need to iterate over players or anything - g_ServerBanSystem->UnbanUID(strtoll(args.Arg(1), nullptr, 10)); -} - -void ClearBanlistCommand(const CCommand& args) -{ - g_ServerBanSystem->ClearBanlist(); -} - -void InitialiseBanSystem(HMODULE baseAddress) -{ - g_ServerBanSystem = new ServerBanSystem; - g_ServerBanSystem->OpenBanlist(); - - RegisterConCommand("ban", BanPlayerCommand, "bans a given player by uid or name", FCVAR_GAMEDLL); - RegisterConCommand("unban", UnbanPlayerCommand, "unbans a given player by uid", FCVAR_NONE); - RegisterConCommand("clearbanlist", ClearBanlistCommand, "clears all uids on the banlist", FCVAR_NONE); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/buildainfile.h b/NorthstarDedicatedTest/buildainfile.h deleted file mode 100644 index a3c0e090..00000000 --- a/NorthstarDedicatedTest/buildainfile.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseBuildAINFileHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/chatcommand.h b/NorthstarDedicatedTest/chatcommand.h deleted file mode 100644 index 546d0126..00000000 --- a/NorthstarDedicatedTest/chatcommand.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseChatCommands(HMODULE baseAddress); diff --git a/NorthstarDedicatedTest/clientauthhooks.h b/NorthstarDedicatedTest/clientauthhooks.h deleted file mode 100644 index e40a68a5..00000000 --- a/NorthstarDedicatedTest/clientauthhooks.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void InitialiseClientAuthHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/clientchathooks.cpp b/NorthstarDedicatedTest/clientchathooks.cpp deleted file mode 100644 index 74418c06..00000000 --- a/NorthstarDedicatedTest/clientchathooks.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "pch.h" -#include "clientchathooks.h" -#include <rapidjson/document.h> -#include "squirrel.h" -#include "serverchathooks.h" -#include "localchatwriter.h" - -typedef void(__fastcall* CHudChat__AddGameLineType)(void* self, const char* message, int fromPlayerId, bool isteam, bool isdead); -CHudChat__AddGameLineType CHudChat__AddGameLine; - -struct ChatTags -{ - bool whisper; - bool team; - bool dead; -}; - -static void CHudChat__AddGameLineHook(void* self, const char* message, int inboxId, bool isTeam, bool isDead) -{ - // This hook is called for each HUD, but we only want our logic to run once. - if (self != *CHudChat::allHuds) - { - return; - } - - if (g_ClientSquirrelManager->setupfunc("CHudChat_ProcessMessageStartThread") != SQRESULT_ERROR) - { - int senderId = inboxId & CUSTOM_MESSAGE_INDEX_MASK; - bool isAnonymous = senderId == 0; - bool isCustom = isAnonymous || (inboxId & CUSTOM_MESSAGE_INDEX_BIT); - - // Type is set to 0 for non-custom messages, custom messages have a type encoded as the first byte - int type = 0; - const char* payload = message; - if (isCustom) - { - type = message[0]; - payload = message + 1; - } - - g_ClientSquirrelManager->pusharg((int)senderId - 1); - g_ClientSquirrelManager->pusharg(payload); - g_ClientSquirrelManager->pusharg(isTeam); - g_ClientSquirrelManager->pusharg(isDead); - g_ClientSquirrelManager->pusharg(type); - g_ClientSquirrelManager->call(5); - } - else - { - for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next) - { - CHudChat__AddGameLine(hud, message, inboxId, isTeam, isDead); - } - } -} - -// void NSChatWrite( int context, string str ) -static SQRESULT SQ_ChatWrite(void* sqvm) -{ - int context = ClientSq_getinteger(sqvm, 1); - const char* str = ClientSq_getstring(sqvm, 2); - - LocalChatWriter((LocalChatWriter::Context)context).Write(str); - return SQRESULT_NOTNULL; -} - -// void NSChatWriteRaw( int context, string str ) -static SQRESULT SQ_ChatWriteRaw(void* sqvm) -{ - int context = ClientSq_getinteger(sqvm, 1); - const char* str = ClientSq_getstring(sqvm, 2); - - LocalChatWriter((LocalChatWriter::Context)context).InsertText(str); - return SQRESULT_NOTNULL; -} - -// void NSChatWriteLine( int context, string str ) -static SQRESULT SQ_ChatWriteLine(void* sqvm) -{ - int context = ClientSq_getinteger(sqvm, 1); - const char* str = ClientSq_getstring(sqvm, 2); - - LocalChatWriter((LocalChatWriter::Context)context).WriteLine(str); - return SQRESULT_NOTNULL; -} - -void InitialiseClientChatHooks(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x22E580, &CHudChat__AddGameLineHook, reinterpret_cast<LPVOID*>(&CHudChat__AddGameLine)); - - g_ClientSquirrelManager->AddFuncRegistration("void", "NSChatWrite", "int context, string text", "", SQ_ChatWrite); - g_ClientSquirrelManager->AddFuncRegistration("void", "NSChatWriteRaw", "int context, string text", "", SQ_ChatWriteRaw); - g_ClientSquirrelManager->AddFuncRegistration("void", "NSChatWriteLine", "int context, string text", "", SQ_ChatWriteLine); -} diff --git a/NorthstarDedicatedTest/clientchathooks.h b/NorthstarDedicatedTest/clientchathooks.h deleted file mode 100644 index 79a1b3e2..00000000 --- a/NorthstarDedicatedTest/clientchathooks.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include "pch.h" -#include "serverchathooks.h" - -void InitialiseClientChatHooks(HMODULE baseAddress); diff --git a/NorthstarDedicatedTest/clientruihooks.cpp b/NorthstarDedicatedTest/clientruihooks.cpp deleted file mode 100644 index bc6c7aa7..00000000 --- a/NorthstarDedicatedTest/clientruihooks.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "pch.h" -#include "clientruihooks.h" -#include "convar.h" - -ConVar* Cvar_rui_drawEnable; - -typedef char (*DrawRUIFuncType)(void* a1, float* a2); -DrawRUIFuncType DrawRUIFunc; - -char DrawRUIFuncHook(void* a1, float* a2) -{ - if (!Cvar_rui_drawEnable->GetBool()) - return 0; - - return DrawRUIFunc(a1, a2); -} - -void InitialiseEngineClientRUIHooks(HMODULE baseAddress) -{ - Cvar_rui_drawEnable = new ConVar("rui_drawEnable", "1", FCVAR_CLIENTDLL, "Controls whether RUI should be drawn"); - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xFC500, &DrawRUIFuncHook, reinterpret_cast<LPVOID*>(&DrawRUIFunc)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/clientruihooks.h b/NorthstarDedicatedTest/clientruihooks.h deleted file mode 100644 index 967ccefe..00000000 --- a/NorthstarDedicatedTest/clientruihooks.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void InitialiseEngineClientRUIHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/clientvideooverrides.cpp b/NorthstarDedicatedTest/clientvideooverrides.cpp deleted file mode 100644 index d5674f51..00000000 --- a/NorthstarDedicatedTest/clientvideooverrides.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "pch.h" -#include "clientvideooverrides.h" -#include "modmanager.h" - -typedef void* (*BinkOpenType)(const char* path, uint32_t flags); -BinkOpenType BinkOpen; - -void* BinkOpenHook(const char* path, uint32_t flags) -{ - std::string filename(fs::path(path).filename().string()); - spdlog::info("BinkOpen {}", filename); - - // figure out which mod is handling the bink - Mod* fileOwner = nullptr; - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - if (std::find(mod.BinkVideos.begin(), mod.BinkVideos.end(), filename) != mod.BinkVideos.end()) - fileOwner = &mod; - } - - if (fileOwner) - { - // create new path - fs::path binkPath(fileOwner->ModDirectory / "media" / filename); - return BinkOpen(binkPath.string().c_str(), flags); - } - else - return BinkOpen(path, flags); -} - -void InitialiseClientVideoOverrides(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, GetProcAddress(GetModuleHandleA("bink2w64.dll"), "BinkOpen"), &BinkOpenHook, reinterpret_cast<LPVOID*>(&BinkOpen)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/clientvideooverrides.h b/NorthstarDedicatedTest/clientvideooverrides.h deleted file mode 100644 index 8819e404..00000000 --- a/NorthstarDedicatedTest/clientvideooverrides.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void InitialiseClientVideoOverrides(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/context.cpp b/NorthstarDedicatedTest/context.cpp deleted file mode 100644 index 7478faa3..00000000 --- a/NorthstarDedicatedTest/context.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "pch.h" -#include "context.h" - -const char* GetContextName(ScriptContext context) -{ - if (context == ScriptContext::CLIENT) - return "CLIENT"; - else if (context == ScriptContext::SERVER) - return "SERVER"; - else if (context == ScriptContext::UI) - return "UI"; - - return ""; -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/context.h b/NorthstarDedicatedTest/context.h deleted file mode 100644 index b6097780..00000000 --- a/NorthstarDedicatedTest/context.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -enum class ScriptContext : int -{ - SERVER, - CLIENT, - UI, - NONE -}; - -const char* GetContextName(ScriptContext context);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/debugoverlay.h b/NorthstarDedicatedTest/debugoverlay.h deleted file mode 100644 index a300018c..00000000 --- a/NorthstarDedicatedTest/debugoverlay.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseDebugOverlay(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp deleted file mode 100644 index 5099a6d2..00000000 --- a/NorthstarDedicatedTest/dedicated.cpp +++ /dev/null @@ -1,329 +0,0 @@ -#include "pch.h" -#include "dedicated.h" -#include "hookutils.h" -#include "gameutils.h" -#include "serverauthentication.h" -#include "masterserver.h" - -bool IsDedicated() -{ - static bool result = strstr(GetCommandLineA(), "-dedicated"); - return result; -} - -// CDedidcatedExports defs -struct CDedicatedExports; // forward declare - -typedef void (*DedicatedSys_PrintfType)(CDedicatedExports* dedicated, const char* msg); -typedef void (*DedicatedRunServerType)(CDedicatedExports* dedicated); - -// would've liked to just do this as a class but have not been able to get it to work -struct CDedicatedExports -{ - void* vtable; // because it's easier, we just set this to &this, since CDedicatedExports has no props we care about other than funcs - - char unused[56]; - - DedicatedSys_PrintfType Sys_Printf; - DedicatedRunServerType RunServer; -}; - -void Sys_Printf(CDedicatedExports* dedicated, const char* msg) -{ - spdlog::info("[DEDICATED PRINT] {}", msg); -} - -typedef void (*CHostState__InitType)(CHostState* self); - -void RunServer(CDedicatedExports* dedicated) -{ - spdlog::info("CDedicatedExports::RunServer(): starting"); - spdlog::info(CommandLine()->GetCmdLine()); - - // initialise engine - g_pEngine->Frame(); - - // add +map if not present - // don't manually execute this from cbuf as users may have it in their startup args anyway, easier just to run from stuffcmds if present - if (!CommandLine()->CheckParm("+map")) - CommandLine()->AppendParm("+map", g_pCVar->FindVar("match_defaultMap")->GetString()); - - // run server autoexec and re-run commandline - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", cmd_source_t::kCommandSrcCode); - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "stuffcmds", cmd_source_t::kCommandSrcCode); - Cbuf_Execute(); - - // ensure playlist initialises right, if we've not explicitly called setplaylist - SetCurrentPlaylist(GetCurrentPlaylistName()); - - // note: we no longer manually set map and hoststate to start server in g_pHostState, we just use +map which seems to initialise stuff - // better - - // get tickinterval - ConVar* Cvar_base_tickinterval_mp = g_pCVar->FindVar("base_tickinterval_mp"); - - // main loop - double frameTitle = 0; - while (g_pEngine->m_nQuitting == EngineQuitState::QUIT_NOTQUITTING) - { - double frameStart = Plat_FloatTime(); - g_pEngine->Frame(); - - // only update the title after at least 500ms since the last update - if ((frameStart - frameTitle) > 0.5) - { - frameTitle = frameStart; - - // this way of getting playercount/maxplayers honestly really sucks, but not got any other methods of doing it rn - const char* maxPlayers = GetCurrentPlaylistVar("max_players", false); - if (!maxPlayers) - maxPlayers = "6"; - - SetConsoleTitleA(fmt::format( - "{} - {} {}/{} players ({})", - g_MasterServerManager->ns_auth_srvName, - g_pHostState->m_levelName, - g_ServerAuthenticationManager->m_additionalPlayerData.size(), - maxPlayers, - GetCurrentPlaylistName()) - .c_str()); - } - - std::this_thread::sleep_for(std::chrono::duration<double, std::ratio<1>>( - Cvar_base_tickinterval_mp->GetFloat() - fmin(Plat_FloatTime() - frameStart, 0.25))); - } -} - -typedef bool (*IsGameActiveWindowType)(); -IsGameActiveWindowType IsGameActiveWindow; -bool IsGameActiveWindowHook() -{ - return true; -} - -HANDLE consoleInputThreadHandle = NULL; - -DWORD WINAPI ConsoleInputThread(PVOID pThreadParameter) -{ - while (!g_pEngine || !g_pHostState || g_pHostState->m_iCurrentState != HostState_t::HS_RUN) - Sleep(1000); - - // Bind stdin to receive console input. - FILE* fp = nullptr; - freopen_s(&fp, "CONIN$", "r", stdin); - - spdlog::info("Ready to receive console commands."); - - { - // Process console input - std::string input; - while (g_pEngine && g_pEngine->m_nQuitting == EngineQuitState::QUIT_NOTQUITTING && std::getline(std::cin, input)) - { - input += "\n"; - Cbuf_AddText(Cbuf_GetCurrentPlayer(), input.c_str(), cmd_source_t::kCommandSrcCode); - } - } - - return 0; -} - -#include "NSMem.h" -void InitialiseDedicated(HMODULE engineAddress) -{ - spdlog::info("InitialiseDedicated"); - - uintptr_t ea = (uintptr_t)engineAddress; - - { - // Host_Init - // prevent a particle init that relies on client dll - NSMem::NOP(ea + 0x156799, 5); - } - - { - // CModAppSystemGroup::Create - // force the engine into dedicated mode by changing the first comparison to IsServerOnly to an assignment - auto ptr = ea + 0x1C4EBD; - - // cmp => mov - NSMem::BytePatch(ptr + 1, "C6 87"); - - // 00 => 01 - NSMem::BytePatch(ptr + 7, "01"); - } - - { - // Some init that i'm not sure of that crashes - // nop the call to it - NSMem::NOP(ea + 0x156A63, 5); - } - - { - // runframeserver - // nop some access violations - NSMem::NOP(ea + 0x159819, 17); - } - - { - NSMem::NOP(ea + 0x156B4C, 7); - - // previously patched these, took me a couple weeks to figure out they were the issue - // removing these will mess up register state when this function is over, so we'll write HS_RUN to the wrong address - // so uhh, don't do that - // NSMem::NOP(ea + 0x156B4C + 7, 8); - - NSMem::NOP(ea + 0x156B4C + 15, 9); - } - - { - // HostState_State_NewGame - // nop an access violation - NSMem::NOP(ea + 0xB934C, 9); - } - - { - // CEngineAPI::Connect - // remove call to Shader_Connect - NSMem::NOP(ea + 0x1C4D7D, 5); - } - - // currently does not work, crashes stuff, likely gotta keep this here - //{ - // // CEngineAPI::Connect - // // remove calls to register ui rpak asset types - // NSMem::NOP(ea + 0x1C4E07, 5); - //} - - { - // Host_Init - // remove call to ui loading stuff - NSMem::NOP(ea + 0x156595, 5); - } - - { - // some function that gets called from RunFrameServer - // nop a function that makes requests to stryder, this will eventually access violation if left alone and isn't necessary anyway - NSMem::NOP(ea + 0x15A0BB, 5); - } - - { - // RunFrameServer - // nop a function that access violations - NSMem::NOP(ea + 0x159BF3, 5); - } - - { - // func that checks if origin is inited - // always return 1 - NSMem::BytePatch( - ea + 0x183B70, - { - 0xB0, - 0x01, // mov al,01 - 0xC3 // ret - }); - } - - { - // HostState_State_ChangeLevel - // nop clientinterface call - NSMem::NOP(ea + 0x1552ED, 16); - } - - { - // HostState_State_ChangeLevel - // nop clientinterface call - NSMem::NOP(ea + 0x155363, 16); - } - - // note: previously had DisableDedicatedWindowCreation patches here, but removing those rn since they're all shit and unstable and bad - // and such check commit history if any are needed for reimplementation - { - // IVideoMode::CreateGameWindow - // nop call to ShowWindow - NSMem::NOP(ea + 0x1CD146, 5); - } - - CDedicatedExports* dedicatedExports = new CDedicatedExports; - dedicatedExports->vtable = dedicatedExports; - dedicatedExports->Sys_Printf = Sys_Printf; - dedicatedExports->RunServer = RunServer; - - CDedicatedExports** exports = (CDedicatedExports**)((char*)engineAddress + 0x13F0B668); - *exports = dedicatedExports; - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)engineAddress + 0x1CDC80, &IsGameActiveWindowHook, reinterpret_cast<LPVOID*>(&IsGameActiveWindow)); - - // extra potential patches: - // nop engine.dll+1c67d1 and +1c67d8 to skip videomode creategamewindow - // also look into launcher.dll+d381, seems to cause renderthread to get made - // this crashes HARD if no window which makes sense tbh - // also look into materialsystem + 5B344 since it seems to be the base of all the renderthread stuff - - // big note: datatable gets registered in window creation - // make sure it still gets registered - - // add cmdline args that are good for dedi - CommandLine()->AppendParm("-nomenuvid", 0); - CommandLine()->AppendParm("-nosound", 0); - CommandLine()->AppendParm("-windowed", 0); - CommandLine()->AppendParm("-nomessagebox", 0); - CommandLine()->AppendParm("+host_preload_shaders", "0"); - CommandLine()->AppendParm("+net_usesocketsforloopback", "1"); - - // Disable Quick Edit mode to reduce chance of user unintentionally hanging their server by selecting something. - if (!CommandLine()->CheckParm("-bringbackquickedit")) - { - HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE); - DWORD mode = 0; - - if (GetConsoleMode(stdIn, &mode)) - { - if (mode & ENABLE_QUICK_EDIT_MODE) - { - mode &= ~ENABLE_QUICK_EDIT_MODE; - mode &= ~ENABLE_MOUSE_INPUT; - - mode |= ENABLE_PROCESSED_INPUT; - - SetConsoleMode(stdIn, mode); - } - } - } - else - spdlog::info("Quick Edit enabled by user request"); - - // create console input thread - if (!CommandLine()->CheckParm("-noconsoleinput")) - consoleInputThreadHandle = CreateThread(0, 0, ConsoleInputThread, 0, 0, NULL); - else - spdlog::info("Console input disabled by user request"); -} - -void InitialiseDedicatedOrigin(HMODULE baseAddress) -{ - // disable origin on dedicated - // for any big ea lawyers, this can't be used to play the game without origin, game will throw a fit if you try to do anything without - // an origin id as a client for dedi it's fine though, game doesn't care if origin is disabled as long as there's only a server - - NSMem::BytePatch( - (uintptr_t)GetProcAddress(GetModuleHandleA("tier0.dll"), "Tier0_InitOrigin"), - { - 0xC3 // ret - }); -} - -typedef void (*PrintFatalSquirrelErrorType)(void* sqvm); -PrintFatalSquirrelErrorType PrintFatalSquirrelError; -void PrintFatalSquirrelErrorHook(void* sqvm) -{ - PrintFatalSquirrelError(sqvm); - g_pEngine->m_nQuitting = EngineQuitState::QUIT_TODESKTOP; -} - -void InitialiseDedicatedServerGameDLL(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK(hook, baseAddress + 0x794D0, &PrintFatalSquirrelErrorHook, reinterpret_cast<LPVOID*>(&PrintFatalSquirrelError)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/dedicated.h b/NorthstarDedicatedTest/dedicated.h deleted file mode 100644 index 0b4d9188..00000000 --- a/NorthstarDedicatedTest/dedicated.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -bool IsDedicated(); - -void InitialiseDedicated(HMODULE moduleAddress); -void InitialiseDedicatedOrigin(HMODULE baseAddress); -void InitialiseDedicatedServerGameDLL(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp deleted file mode 100644 index f1a91e22..00000000 --- a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once -#include "pch.h" -#include "dedicated.h" -#include "dedicatedmaterialsystem.h" -#include "hookutils.h" -#include "gameutils.h" -#include "NSMem.h" - -typedef HRESULT (*__stdcall D3D11CreateDeviceType)( - void* pAdapter, - int DriverType, - HMODULE Software, - UINT Flags, - int* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - void** ppDevice, - int* pFeatureLevel, - void** ppImmediateContext); -D3D11CreateDeviceType D3D11CreateDevice; - -HRESULT __stdcall D3D11CreateDeviceHook( - void* pAdapter, - int DriverType, - HMODULE Software, - UINT Flags, - int* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - void** ppDevice, - int* pFeatureLevel, - void** ppImmediateContext) -{ - // note: this is super duper temp pretty much just messing around with it - // does run surprisingly well on dedi for a software driver tho if you ignore the +1gb ram usage at times, seems like dedi doesn't - // really call gpu much even with renderthread still being a thing will be using this hook for actual d3d stubbing and stuff later - - // atm, i think the play might be to run d3d in software, and then just stub out any calls that allocate memory/use alot of resources - // (e.g. createtexture and that sorta thing) - // note: this has been succeeded by the d3d11 and gfsdk stubs, and is only being kept around for posterity and as a fallback option - if (CommandLine()->CheckParm("-softwared3d11")) - DriverType = 5; // D3D_DRIVER_TYPE_WARP - - return D3D11CreateDevice( - pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext); -} - -void InitialiseDedicatedMaterialSystem(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xD9A0E, &D3D11CreateDeviceHook, reinterpret_cast<LPVOID*>(&D3D11CreateDevice)); - - // not using these for now since they're related to nopping renderthread/gamewindow i.e. very hard - //{ - // // function that launches renderthread - // char* ptr = (char*)baseAddress + 0x87047; - // TempReadWrite rw(ptr); - // - // // make it not launch renderthread - // *ptr = (char)0x90; - // *(ptr + 1) = (char)0x90; - // *(ptr + 2) = (char)0x90; - // *(ptr + 3) = (char)0x90; - // *(ptr + 4) = (char)0x90; - // *(ptr + 5) = (char)0x90; - //} - // - //{ - // // some function that waits on renderthread job - // char* ptr = (char*)baseAddress + 0x87d00; - // TempReadWrite rw(ptr); - // - // // return immediately - // *ptr = (char)0xC3; - //} - - { - // CMaterialSystem::FindMaterial - // make the game always use the error material - NSMem::BytePatch((uintptr_t)baseAddress + 0x5F0F1, {0xE9, 0x34, 0x03, 0x00}); - } - - // previously had DisableDedicatedWindowCreation stuff here, removing for now since shit and unstable - // check commit history if needed -} - -typedef void* (*PakLoadAPI__LoadRpakType)(char* filename, void* unknown, int flags); -PakLoadAPI__LoadRpakType PakLoadAPI__LoadRpak; - -void* PakLoadAPI__LoadRpakHook(char* filename, void* unknown, int flags) -{ - spdlog::info("PakLoadAPI__LoadRpakHook {}", filename); - - // on dedi, don't load any paks that aren't required - if (strncmp(filename, "common", 6)) - return 0; - - return PakLoadAPI__LoadRpak(filename, unknown, flags); -} - -typedef void* (*PakLoadAPI__LoadRpak2Type)(char* filename, void* unknown, int flags, void* callback, void* callback2); -PakLoadAPI__LoadRpak2Type PakLoadAPI__LoadRpak2; - -void* PakLoadAPI__LoadRpak2Hook(char* filename, void* unknown, int flags, void* callback, void* callback2) -{ - spdlog::info("PakLoadAPI__LoadRpak2Hook {}", filename); - - // on dedi, don't load any paks that aren't required - if (strncmp(filename, "common", 6)) - return 0; - - return PakLoadAPI__LoadRpak2(filename, unknown, flags, callback, callback2); -} - -void InitialiseDedicatedRtechGame(HMODULE baseAddress) -{ - baseAddress = GetModuleHandleA("rtech_game.dll"); - - HookEnabler hook; - // unfortunately this is unstable, seems to freeze when changing maps - // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xB0F0, &PakLoadAPI__LoadRpakHook, reinterpret_cast<LPVOID*>(&PakLoadAPI__LoadRpak)); - // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0xB170, &PakLoadAPI__LoadRpak2Hook, reinterpret_cast<LPVOID*>(&PakLoadAPI__LoadRpak2)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.h b/NorthstarDedicatedTest/dedicatedmaterialsystem.h deleted file mode 100644 index 38343d17..00000000 --- a/NorthstarDedicatedTest/dedicatedmaterialsystem.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -void InitialiseDedicatedMaterialSystem(HMODULE baseAddress); -void InitialiseDedicatedRtechGame(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp deleted file mode 100644 index 62094b4e..00000000 --- a/NorthstarDedicatedTest/dllmain.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include "pch.h" -#include "hooks.h" -#include "main.h" -#include "squirrel.h" -#include "dedicated.h" -#include "dedicatedmaterialsystem.h" -#include "sourceconsole.h" -#include "logging.h" -#include "concommand.h" -#include "modmanager.h" -#include "filesystem.h" -#include "serverauthentication.h" -#include "scriptmodmenu.h" -#include "scriptserverbrowser.h" -#include "keyvalues.h" -#include "masterserver.h" -#include "gameutils.h" -#include "chatcommand.h" -#include "modlocalisation.h" -#include "playlist.h" -#include "miscserverscript.h" -#include "clientauthhooks.h" -#include "latencyflex.h" -#include "scriptbrowserhooks.h" -#include "scriptmainmenupromos.h" -#include "miscclientfixes.h" -#include "miscserverfixes.h" -#include "rpakfilesystem.h" -#include "bansystem.h" -#include "memalloc.h" -#include "maxplayers.h" -#include "languagehooks.h" -#include "audio.h" -#include "buildainfile.h" -#include "configurables.h" -#include "serverchathooks.h" -#include "clientchathooks.h" -#include "localchatwriter.h" -#include "scriptservertoclientstringcommand.h" -#include "plugin_abi.h" -#include "plugins.h" -#include "debugoverlay.h" -#include "clientvideooverrides.h" -#include "clientruihooks.h" -#include <string.h> -#include "version.h" -#include "pch.h" - -#include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" -#include "rapidjson/error/en.h" -#include "ExploitFixes.h" -#include "emit_blocker.h" - -typedef void (*initPluginFuncPtr)(void* getPluginObject); - -bool initialised = false; - -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - - return TRUE; -} - -void WaitForDebugger(HMODULE baseAddress) -{ - // earlier waitfordebugger call than is in vanilla, just so we can debug stuff a little easier - if (CommandLine()->CheckParm("-waitfordebugger")) - { - spdlog::info("waiting for debugger..."); - - while (!IsDebuggerPresent()) - Sleep(100); - } -} - -void freeLibrary(HMODULE hLib) -{ - if (!FreeLibrary(hLib)) - { - spdlog::error("There was an error while trying to free library"); - } -} - -bool LoadPlugins() -{ - - std::vector<fs::path> paths; - - std::string pluginPath = GetNorthstarPrefix() + "/plugins"; - if (!fs::exists(pluginPath)) - { - spdlog::warn("Could not find a plugins directory. Skipped loading plugins"); - return false; - } - // ensure dirs exist - fs::recursive_directory_iterator iterator(pluginPath); - if (std::filesystem::begin(iterator) == std::filesystem::end(iterator)) - { - spdlog::warn("Could not find any plugins. Skipped loading plugins"); - return false; - } - for (auto const& entry : iterator) - { - if (fs::is_regular_file(entry) && entry.path().extension() == ".dll") - paths.emplace_back(entry.path().filename()); - } - initGameState(); - for (fs::path path : paths) - { - std::string pathstring = (pluginPath / path).string(); - std::wstring wpath = (pluginPath / path).wstring(); - - LPCWSTR wpptr = wpath.c_str(); - HMODULE datafile = - LoadLibraryExW(wpptr, 0, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); // Load the DLL as a data file - if (datafile == NULL) - { - spdlog::info("Failed to load library {}: ", std::system_category().message(GetLastError())); - continue; - } - HRSRC manifestResource = FindResourceW(datafile, MAKEINTRESOURCE(101), MAKEINTRESOURCE(RT_RCDATA)); - - if (manifestResource == NULL) - { - spdlog::info("Could not find manifest for library {}", pathstring); - freeLibrary(datafile); - continue; - } - spdlog::info("Loading resource from library"); - HGLOBAL myResourceData = LoadResource(datafile, manifestResource); - if (myResourceData == NULL) - { - spdlog::error("Failed to load resource from library"); - freeLibrary(datafile); - continue; - } - int manifestSize = SizeofResource(datafile, manifestResource); - std::string manifest = std::string((const char*)LockResource(myResourceData), 0, manifestSize); - freeLibrary(datafile); - - rapidjson_document manifestJSON; - manifestJSON.Parse(manifest.c_str()); - - if (manifestJSON.HasParseError()) - { - spdlog::error("Manifest for {} was invalid", pathstring); - continue; - } - if (!manifestJSON.HasMember("api_version")) - { - spdlog::error("{} does not have a version number in its manifest", pathstring); - continue; - // spdlog::info(manifestJSON["version"].GetString()); - } - if (strcmp(manifestJSON["api_version"].GetString(), std::to_string(ABI_VERSION).c_str())) - { - spdlog::error("{} has an incompatible API version number in its manifest", pathstring); - continue; - } - // Passed all checks, going to actually load it now - - HMODULE pluginLib = LoadLibraryW(wpptr); // Load the DLL as a data file - if (pluginLib == NULL) - { - spdlog::info("Failed to load library {}: ", std::system_category().message(GetLastError())); - continue; - } - initPluginFuncPtr initPlugin = (initPluginFuncPtr)GetProcAddress(pluginLib, "initializePlugin"); - if (initPlugin == NULL) - { - spdlog::info("Library {} has no function initializePlugin", pathstring); - continue; - } - spdlog::info("Succesfully loaded {}", pathstring); - initPlugin(&getPluginObject); - } - return true; -} - -bool InitialiseNorthstar() -{ - if (initialised) - { - // spdlog::warn("Called InitialiseNorthstar more than once!"); // it's actually 100% fine for that to happen - return false; - } - - initialised = true; - - parseConfigurables(); - InitialiseVersion(); - - // Fix some users' failure to connect to respawn datacenters - SetEnvironmentVariableA("OPENSSL_ia32cap", "~0x200000200000000"); - - curl_global_init_mem(CURL_GLOBAL_DEFAULT, _malloc_base, _free_base, _realloc_base, _strdup_base, _calloc_base); - - InitialiseLogging(); - InstallInitialHooks(); - CreateLogFiles(); - - // Write launcher version to log - spdlog::info("NorthstarLauncher version: {}", version); - - InitialiseInterfaceCreationHooks(); - - AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions); - AddDllLoadCallback("engine.dll", WaitForDebugger); - AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions); - AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions); - - // dedi patches - { - AddDllLoadCallbackForDedicatedServer("tier0.dll", InitialiseDedicatedOrigin); - AddDllLoadCallbackForDedicatedServer("engine.dll", InitialiseDedicated); - AddDllLoadCallbackForDedicatedServer("server.dll", InitialiseDedicatedServerGameDLL); - AddDllLoadCallbackForDedicatedServer("materialsystem_dx11.dll", InitialiseDedicatedMaterialSystem); - // this fucking sucks, but seemingly we somehow load after rtech_game???? unsure how, but because of this we have to apply patches - // here, not on rtech_game load - AddDllLoadCallbackForDedicatedServer("engine.dll", InitialiseDedicatedRtechGame); - } - - AddDllLoadCallback("engine.dll", InitialiseConVars); - AddDllLoadCallback("engine.dll", InitialiseConCommands); - - // client-exclusive patches - { - - AddDllLoadCallbackForClient("tier0.dll", InitialiseTier0LanguageHooks); - AddDllLoadCallbackForClient("client.dll", InitialiseClientSquirrel); - AddDllLoadCallbackForClient("client.dll", InitialiseSourceConsole); - AddDllLoadCallbackForClient("engine.dll", InitialiseChatCommands); - AddDllLoadCallbackForClient("client.dll", InitialiseScriptModMenu); - AddDllLoadCallbackForClient("client.dll", InitialiseScriptServerBrowser); - AddDllLoadCallbackForClient("localize.dll", InitialiseModLocalisation); - AddDllLoadCallbackForClient("engine.dll", InitialiseClientAuthHooks); - AddDllLoadCallbackForClient("client.dll", InitialiseLatencyFleX); - AddDllLoadCallbackForClient("engine.dll", InitialiseScriptExternalBrowserHooks); - AddDllLoadCallbackForClient("client.dll", InitialiseScriptMainMenuPromos); - AddDllLoadCallbackForClient("client.dll", InitialiseMiscClientFixes); - AddDllLoadCallbackForClient("client.dll", InitialiseClientPrintHooks); - AddDllLoadCallbackForClient("client.dll", InitialisePluginCommands); - AddDllLoadCallbackForClient("client.dll", InitialiseClientChatHooks); - AddDllLoadCallbackForClient("client.dll", InitialiseLocalChatWriter); - AddDllLoadCallbackForClient("client.dll", InitialiseScriptServerToClientStringCommands); - AddDllLoadCallbackForClient("client.dll", InitialiseClientVideoOverrides); - AddDllLoadCallbackForClient("engine.dll", InitialiseEngineClientRUIHooks); - AddDllLoadCallbackForClient("engine.dll", InitialiseDebugOverlay); - // audio hooks - AddDllLoadCallbackForClient("client.dll", InitialiseMilesAudioHooks); - } - - AddDllLoadCallback("engine.dll", InitialiseEngineSpewFuncHooks); - AddDllLoadCallback("server.dll", InitialiseServerSquirrel); - AddDllLoadCallback("engine.dll", InitialiseBanSystem); - AddDllLoadCallback("engine.dll", InitialiseServerAuthentication); - AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer); - AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand); - AddDllLoadCallback("server.dll", InitialiseMiscServerFixes); - AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks); - - AddDllLoadCallback("engine.dll", InitialisePlaylistHooks); - - AddDllLoadCallback("filesystem_stdio.dll", InitialiseFilesystem); - AddDllLoadCallback("engine.dll", InitialiseEngineRpakFilesystem); - AddDllLoadCallback("engine.dll", InitialiseKeyValues); - - AddDllLoadCallback("engine.dll", InitialiseServerChatHooks_Engine); - AddDllLoadCallback("server.dll", InitialiseServerChatHooks_Server); - - // maxplayers increase - AddDllLoadCallback("engine.dll", InitialiseMaxPlayersOverride_Engine); - AddDllLoadCallback("client.dll", InitialiseMaxPlayersOverride_Client); - AddDllLoadCallback("server.dll", InitialiseMaxPlayersOverride_Server); - - // mod manager after everything else - AddDllLoadCallback("engine.dll", InitialiseModManager); - - // activate exploit fixes - AddDllLoadCallback("server.dll", ExploitFixes::LoadCallback); - AddDllLoadCallback("server.dll", InitialiseServerEmit_Blocker); - - // run callbacks for any libraries that are already loaded by now - CallAllPendingDLLLoadCallbacks(); - - return true; -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/emit_blocker.cpp b/NorthstarDedicatedTest/emit_blocker.cpp deleted file mode 100644 index 3f996c69..00000000 --- a/NorthstarDedicatedTest/emit_blocker.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "pch.h" -#include "cvar.h" - -ConVar* sv_cheats; - -typedef char(__fastcall* function_containing_emit_t)(uint64_t a1, uint64_t a2); -function_containing_emit_t function_containing_emit; - -char function_containing_emit_hook(uint64_t unknown_value, uint64_t command_ptr) -{ - char* command_string = *(char**)(command_ptr + 1040); // From decompile - if (!sv_cheats->m_Value.m_nValue && !strncmp(command_string, "emit", 5)) - { - spdlog::info("Blocking command \"emit\" because sv_cheats was 0"); - return 1; - } - return function_containing_emit(unknown_value, command_ptr); -} - -void InitialiseServerEmit_Blocker(HMODULE baseAddress) -{ - HookEnabler hook; - sv_cheats = g_pCVar->FindVar("sv_cheats"); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x5889A0, &function_containing_emit_hook, reinterpret_cast<LPVOID*>(&function_containing_emit)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/emit_blocker.h b/NorthstarDedicatedTest/emit_blocker.h deleted file mode 100644 index 43991927..00000000 --- a/NorthstarDedicatedTest/emit_blocker.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseServerEmit_Blocker(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp deleted file mode 100644 index 702141bb..00000000 --- a/NorthstarDedicatedTest/filesystem.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "pch.h" -#include "filesystem.h" -#include "hooks.h" -#include "hookutils.h" -#include "sourceinterface.h" -#include "modmanager.h" - -#include <iostream> -#include <sstream> - -// hook forward declares -typedef FileHandle_t (*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, char* filename); -ReadFileFromVPKType readFileFromVPK; -FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename); - -typedef bool (*ReadFromCacheType)(IFileSystem* filesystem, char* path, void* result); -ReadFromCacheType readFromCache; -bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result); - -typedef void (*AddSearchPathType)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType); -AddSearchPathType addSearchPathOriginal; -void AddSearchPathHook(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType); - -typedef FileHandle_t (*ReadFileFromFilesystemType)( - IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5); -ReadFileFromFilesystemType readFileFromFilesystem; -FileHandle_t ReadFileFromFilesystemHook(IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5); - -typedef VPKData* (*MountVPKType)(IFileSystem* fileSystem, const char* vpkPath); -MountVPKType mountVPK; -VPKData* MountVPKHook(IFileSystem* fileSystem, const char* vpkPath); - -bool readingOriginalFile; -std::string currentModPath; -SourceInterface<IFileSystem>* g_Filesystem; - -void InitialiseFilesystem(HMODULE baseAddress) -{ - g_Filesystem = new SourceInterface<IFileSystem>("filesystem_stdio.dll", "VFileSystem017"); - - // create hooks - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x5CBA0, &ReadFileFromVPKHook, reinterpret_cast<LPVOID*>(&readFileFromVPK)); - ENABLER_CREATEHOOK(hook, (*g_Filesystem)->m_vtable->ReadFromCache, &ReadFromCacheHook, reinterpret_cast<LPVOID*>(&readFromCache)); - ENABLER_CREATEHOOK( - hook, (*g_Filesystem)->m_vtable->AddSearchPath, &AddSearchPathHook, reinterpret_cast<LPVOID*>(&addSearchPathOriginal)); - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x15F20, &ReadFileFromFilesystemHook, reinterpret_cast<LPVOID*>(&readFileFromFilesystem)); - ENABLER_CREATEHOOK(hook, (*g_Filesystem)->m_vtable->MountVPK, &MountVPKHook, reinterpret_cast<LPVOID*>(&mountVPK)); -} - -std::string ReadVPKFile(const char* path) -{ - // read scripts.rson file, todo: check if this can be overwritten - FileHandle_t fileHandle = (*g_Filesystem)->m_vtable2->Open(&(*g_Filesystem)->m_vtable2, path, "rb", "GAME", 0); - - std::stringstream fileStream; - int bytesRead = 0; - char data[4096]; - do - { - bytesRead = (*g_Filesystem)->m_vtable2->Read(&(*g_Filesystem)->m_vtable2, data, (int)std::size(data), fileHandle); - fileStream.write(data, bytesRead); - } while (bytesRead == std::size(data)); - - (*g_Filesystem)->m_vtable2->Close(*g_Filesystem, fileHandle); - - return fileStream.str(); -} - -std::string ReadVPKOriginalFile(const char* path) -{ - readingOriginalFile = true; - std::string ret = ReadVPKFile(path); - readingOriginalFile = false; - - return ret; -} - -void SetNewModSearchPaths(Mod* mod) -{ - // put our new path to the head if we need to read from a different mod path - // in the future we could also determine whether the file we're setting paths for needs a mod dir, or compiled assets - if (mod != nullptr) - { - if ((fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string().compare(currentModPath)) - { - spdlog::info("changing mod search path from {} to {}", currentModPath, mod->ModDirectory.string()); - - addSearchPathOriginal( - &*(*g_Filesystem), (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string().c_str(), "GAME", PATH_ADD_TO_HEAD); - currentModPath = (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string(); - } - } - else // push compiled to head - addSearchPathOriginal(&*(*g_Filesystem), fs::absolute(GetCompiledAssetsPath()).string().c_str(), "GAME", PATH_ADD_TO_HEAD); -} - -bool TryReplaceFile(char* path, bool shouldCompile) -{ - if (readingOriginalFile) - return false; - - if (shouldCompile) - (*g_ModManager).CompileAssetsForFile(path); - - // idk how efficient the lexically normal check is - // can't just set all /s in path to \, since some paths aren't in writeable memory - auto file = g_ModManager->m_modFiles.find(fs::path(path).lexically_normal().string()); - if (file != g_ModManager->m_modFiles.end()) - { - SetNewModSearchPaths(file->second.owningMod); - return true; - } - - return false; -} - -FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename) -{ - // move this to a convar at some point when we can read them in native - // spdlog::info("ReadFileFromVPKHook {} {}", filename, vpkInfo->path); - - // there is literally never any reason to compile here, since we'll always compile in ReadFileFromFilesystemHook in the same codepath - // this is called - if (TryReplaceFile(filename, false)) - { - *b = -1; - return b; - } - - return readFileFromVPK(vpkInfo, b, filename); -} - -bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result) -{ - // move this to a convar at some point when we can read them in native - // spdlog::info("ReadFromCacheHook {}", path); - - if (TryReplaceFile(path, true)) - return false; - - return readFromCache(filesystem, path, result); -} - -void AddSearchPathHook(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType) -{ - addSearchPathOriginal(fileSystem, pPath, pathID, addType); - - // make sure current mod paths are at head - if (!strcmp(pathID, "GAME") && currentModPath.compare(pPath) && addType == PATH_ADD_TO_HEAD) - { - addSearchPathOriginal(fileSystem, currentModPath.c_str(), "GAME", PATH_ADD_TO_HEAD); - addSearchPathOriginal(fileSystem, GetCompiledAssetsPath().string().c_str(), "GAME", PATH_ADD_TO_HEAD); - } -} - -FileHandle_t ReadFileFromFilesystemHook(IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5) -{ - // this isn't super efficient, but it's necessary, since calling addsearchpath in readfilefromvpk doesn't work, possibly refactor later - // it also might be possible to hook functions that are called later, idk look into callstack for ReadFileFromVPK - if (!readingOriginalFile) - TryReplaceFile((char*)pPath, true); - - return readFileFromFilesystem(filesystem, pPath, pOptions, a4, a5); -} - -VPKData* MountVPKHook(IFileSystem* fileSystem, const char* vpkPath) -{ - spdlog::info("MountVPK {}", vpkPath); - VPKData* ret = mountVPK(fileSystem, vpkPath); - - for (Mod mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - for (ModVPKEntry& vpkEntry : mod.Vpks) - { - // if we're autoloading, just load no matter what - if (!vpkEntry.m_bAutoLoad) - { - // resolve vpk name and try to load one with the same name - // todo: we should be unloading these on map unload manually - std::string mapName(fs::path(vpkPath).filename().string()); - std::string modMapName(fs::path(vpkEntry.m_sVpkPath.c_str()).filename().string()); - if (mapName.compare(modMapName)) - continue; - } - - VPKData* loaded = mountVPK(fileSystem, vpkEntry.m_sVpkPath.c_str()); - if (!ret) // this is primarily for map vpks and stuff, so the map's vpk is what gets returned from here - ret = loaded; - } - } - - return ret; -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/gameutils.cpp b/NorthstarDedicatedTest/gameutils.cpp deleted file mode 100644 index 792d8bf2..00000000 --- a/NorthstarDedicatedTest/gameutils.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "pch.h" -#include "convar.h" -#include "gameutils.h" - -// memory -IMemAlloc* g_pMemAllocSingleton; -typedef IMemAlloc* (*CreateGlobalMemAllocType)(); -CreateGlobalMemAllocType CreateGlobalMemAlloc; - -// cmd.h -Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer; -Cbuf_AddTextType Cbuf_AddText; -Cbuf_ExecuteType Cbuf_Execute; - -// hoststate stuff -CHostState* g_pHostState; - -// cengine stuff -CEngine* g_pEngine; -server_state_t* sv_m_State; - -// network stuff -ConVar* Cvar_hostport; - -// playlist stuff -GetCurrentPlaylistType GetCurrentPlaylistName; -SetCurrentPlaylistType SetCurrentPlaylist; -SetPlaylistVarOverrideType SetPlaylistVarOverride; -GetCurrentPlaylistVarType GetCurrentPlaylistVar; - -// server entity stuff -Server_GetEntityByIndexType Server_GetEntityByIndex; - -// auth -char* g_LocalPlayerUserID; -char* g_LocalPlayerOriginToken; - -// misc stuff -ErrorType Error; -CommandLineType CommandLine; -Plat_FloatTimeType Plat_FloatTime; -ThreadInServerFrameThreadType ThreadInServerFrameThread; -GetBaseLocalClientType GetBaseLocalClient; - -void InitialiseEngineGameUtilFunctions(HMODULE baseAddress) -{ - Cbuf_GetCurrentPlayer = (Cbuf_GetCurrentPlayerType)((char*)baseAddress + 0x120630); - Cbuf_AddText = (Cbuf_AddTextType)((char*)baseAddress + 0x1203B0); - Cbuf_Execute = (Cbuf_ExecuteType)((char*)baseAddress + 0x1204B0); - - g_pHostState = (CHostState*)((char*)baseAddress + 0x7CF180); - g_pEngine = *(CEngine**)((char*)baseAddress + 0x7D70C8); - sv_m_State = (server_state_t*)((char*)baseAddress + 0x12A53D48); - - GetCurrentPlaylistName = (GetCurrentPlaylistType)((char*)baseAddress + 0x18C640); - SetCurrentPlaylist = (SetCurrentPlaylistType)((char*)baseAddress + 0x18EB20); - SetPlaylistVarOverride = (SetPlaylistVarOverrideType)((char*)baseAddress + 0x18ED00); - GetCurrentPlaylistVar = (GetCurrentPlaylistVarType)((char*)baseAddress + 0x18C680); - - g_LocalPlayerUserID = (char*)baseAddress + 0x13F8E688; - g_LocalPlayerOriginToken = (char*)baseAddress + 0x13979C80; - - GetBaseLocalClient = (GetBaseLocalClientType)((char*)baseAddress + 0x78200); - - /* NOTE: - g_pCVar->FindVar("convar_name") now works. These are no longer needed. - You can also itterate over every ConVar using CCVarIteratorInternal - dump the pointers to a vector and access them from there. - Example: - std::vector<ConVar*> g_pAllConVars; - for (auto& map : g_pCVar->DumpToMap()) - { - ConVar* pConVar = g_pCVar->FindVar(map.first.c_str()); - if (pConVar) - { - g_pAllConVars.push_back(pConVar); - } - }*/ - - Cvar_hostport = (ConVar*)((char*)baseAddress + 0x13FA6070); -} - -void InitialiseServerGameUtilFunctions(HMODULE baseAddress) -{ - Server_GetEntityByIndex = (Server_GetEntityByIndexType)((char*)baseAddress + 0xFB820); -} - -void InitialiseTier0GameUtilFunctions(HMODULE baseAddress) -{ - if (!baseAddress) - { - spdlog::critical("tier0 base address is null, but it should be already loaded"); - throw "tier0 base address is null, but it should be already loaded"; - } - if (g_pMemAllocSingleton) - return; // seems this function was already called - CreateGlobalMemAlloc = reinterpret_cast<CreateGlobalMemAllocType>(GetProcAddress(baseAddress, "CreateGlobalMemAlloc")); - IMemAlloc** ppMemAllocSingleton = reinterpret_cast<IMemAlloc**>(GetProcAddress(baseAddress, "g_pMemAllocSingleton")); - if (!ppMemAllocSingleton) - { - spdlog::critical("Address of g_pMemAllocSingleton is a null pointer, this should never happen"); - throw "Address of g_pMemAllocSingleton is a null pointer, this should never happen"; - } - if (!*ppMemAllocSingleton) - { - g_pMemAllocSingleton = CreateGlobalMemAlloc(); - *ppMemAllocSingleton = g_pMemAllocSingleton; - spdlog::info("Created new g_pMemAllocSingleton"); - } - else - { - g_pMemAllocSingleton = *ppMemAllocSingleton; - } - - Error = reinterpret_cast<ErrorType>(GetProcAddress(baseAddress, "Error")); - CommandLine = reinterpret_cast<CommandLineType>(GetProcAddress(baseAddress, "CommandLine")); - Plat_FloatTime = reinterpret_cast<Plat_FloatTimeType>(GetProcAddress(baseAddress, "Plat_FloatTime")); - ThreadInServerFrameThread = reinterpret_cast<ThreadInServerFrameThreadType>(GetProcAddress(baseAddress, "ThreadInServerFrameThread")); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/gameutils.h b/NorthstarDedicatedTest/gameutils.h deleted file mode 100644 index 6d625c16..00000000 --- a/NorthstarDedicatedTest/gameutils.h +++ /dev/null @@ -1,249 +0,0 @@ -#pragma once -#include "convar.h" - -// memory -class IMemAlloc -{ - public: - struct VTable - { - void* unknown[1]; // alloc debug - void* (*Alloc)(IMemAlloc* memAlloc, size_t nSize); - void* unknown2[1]; // realloc debug - void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize); - void* unknown3[1]; // free #1 - void (*Free)(IMemAlloc* memAlloc, void* pMem); - void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag - size_t (*GetSize)(IMemAlloc* memAlloc, void* pMem); - void* unknown5[9]; // they all do literally nothing - void (*DumpStats)(IMemAlloc* memAlloc); - void (*DumpStatsFileBase)(IMemAlloc* memAlloc, const char* pchFileBase); - void* unknown6[4]; - int (*heapchk)(IMemAlloc* memAlloc); - }; - - VTable* m_vtable; -}; - -extern IMemAlloc* g_pMemAllocSingleton; -typedef IMemAlloc* (*CreateGlobalMemAllocType)(); -extern CreateGlobalMemAllocType CreateGlobalMemAlloc; - -// cmd.h -enum class ECommandTarget_t -{ - CBUF_FIRST_PLAYER = 0, - CBUF_LAST_PLAYER = 1, // MAX_SPLITSCREEN_CLIENTS - 1, MAX_SPLITSCREEN_CLIENTS = 2 - CBUF_SERVER = CBUF_LAST_PLAYER + 1, - - CBUF_COUNT, -}; - -enum class cmd_source_t -{ - // Added to the console buffer by gameplay code. Generally unrestricted. - kCommandSrcCode, - - // Sent from code via engine->ClientCmd, which is restricted to commands visible - // via FCVAR_CLIENTCMD_CAN_EXECUTE. - kCommandSrcClientCmd, - - // Typed in at the console or via a user key-bind. Generally unrestricted, although - // the client will throttle commands sent to the server this way to 16 per second. - kCommandSrcUserInput, - - // Came in over a net connection as a clc_stringcmd - // host_client will be valid during this state. - // - // Restricted to FCVAR_GAMEDLL commands (but not convars) and special non-ConCommand - // server commands hardcoded into gameplay code (e.g. "joingame") - kCommandSrcNetClient, - - // Received from the server as the client - // - // Restricted to commands with FCVAR_SERVER_CAN_EXECUTE - kCommandSrcNetServer, - - // Being played back from a demo file - // - // Not currently restricted by convar flag, but some commands manually ignore calls - // from this source. FIXME: Should be heavily restricted as demo commands can come - // from untrusted sources. - kCommandSrcDemoFile, - - // Invalid value used when cleared - kCommandSrcInvalid = -1 -}; - -typedef ECommandTarget_t (*Cbuf_GetCurrentPlayerType)(); -extern Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer; - -// compared to the defs i've seen, this is missing an arg, it could be nTickInterval or source, not sure, guessing it's source -typedef void (*Cbuf_AddTextType)(ECommandTarget_t eTarget, const char* text, cmd_source_t source); -extern Cbuf_AddTextType Cbuf_AddText; - -typedef void (*Cbuf_ExecuteType)(); -extern Cbuf_ExecuteType Cbuf_Execute; - -// commandline stuff -class CCommandLine -{ - public: - // based on the defs in the 2013 source sdk, but for some reason has an extra function (may be another CreateCmdLine overload?) - // these seem to line up with what they should be though - virtual void CreateCmdLine(const char* commandline) {} - virtual void CreateCmdLine(int argc, char** argv) {} - virtual void unknown() {} - virtual const char* GetCmdLine(void) const {} - - virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const {} - virtual void RemoveParm() const {} - virtual void AppendParm(const char* pszParm, const char* pszValues) {} - - virtual const char* ParmValue(const char* psz, const char* pDefaultVal = 0) const {} - virtual int ParmValue(const char* psz, int nDefaultVal) const {} - virtual float ParmValue(const char* psz, float flDefaultVal) const {} - - virtual int ParmCount() const {} - virtual int FindParm(const char* psz) const {} - virtual const char* GetParm(int nIndex) const {} - virtual void SetParm(int nIndex, char const* pParm) {} - - // virtual const char** GetParms() const {} -}; - -// hoststate stuff -enum HostState_t -{ - HS_NEW_GAME = 0, - HS_LOAD_GAME, - HS_CHANGE_LEVEL_SP, - HS_CHANGE_LEVEL_MP, - HS_RUN, - HS_GAME_SHUTDOWN, - HS_SHUTDOWN, - HS_RESTART, -}; - -struct CHostState -{ - public: - HostState_t m_iCurrentState; - HostState_t m_iNextState; - - float m_vecLocation[3]; - float m_angLocation[3]; - - char m_levelName[32]; - char m_mapGroupName[32]; - char m_landmarkName[32]; - char m_saveName[32]; - float m_flShortFrameTime; // run a few one-tick frames to avoid large timesteps while loading assets - - bool m_activeGame; - bool m_bRememberLocation; - bool m_bBackgroundLevel; - bool m_bWaitingForConnection; - bool m_bLetToolsOverrideLoadGameEnts; // During a load game, this tells Foundry to override ents that are selected in Hammer. - bool m_bSplitScreenConnect; - bool m_bGameHasShutDownAndFlushedMemory; // This is false once we load a map into memory, and set to true once the map is unloaded and - // all memory flushed - bool m_bWorkshopMapDownloadPending; -}; - -extern CHostState* g_pHostState; - -// cengine stuff -enum EngineQuitState -{ - QUIT_NOTQUITTING = 0, - QUIT_TODESKTOP, - QUIT_RESTART -}; - -enum EngineState_t -{ - DLL_INACTIVE = 0, // no dll - DLL_ACTIVE, // engine is focused - DLL_CLOSE, // closing down dll - DLL_RESTART, // engine is shutting down but will restart right away - DLL_PAUSED, // engine is paused, can become active from this state -}; - -class CEngine -{ - public: - virtual void unknown() {} // unsure if this is where - virtual bool Load(bool dedicated, const char* baseDir) {} - virtual void Unload() {} - virtual void SetNextState(EngineState_t iNextState) {} - virtual EngineState_t GetState() {} - virtual void Frame() {} - virtual double GetFrameTime() {} - virtual float GetCurTime() {} - - EngineQuitState m_nQuitting; - EngineState_t m_nDllState; - EngineState_t m_nNextDllState; - double m_flCurrentTime; - float m_flFrameTime; - double m_flPreviousTime; - float m_flFilteredTime; - float m_flMinFrameTime; // Expected duration of a frame, or zero if it is unlimited. -}; - -extern CEngine* g_pEngine; - -enum server_state_t -{ - ss_dead = 0, // Dead - ss_loading, // Spawning - ss_active, // Running - ss_paused, // Running, but paused -}; - -extern server_state_t* sv_m_State; - -// network stuff -extern ConVar* Cvar_hostport; - -// playlist stuff -typedef const char* (*GetCurrentPlaylistType)(); -extern GetCurrentPlaylistType GetCurrentPlaylistName; - -typedef void (*SetCurrentPlaylistType)(const char* playlistName); -extern SetCurrentPlaylistType SetCurrentPlaylist; - -typedef void (*SetPlaylistVarOverrideType)(const char* varName, const char* value); -extern SetPlaylistVarOverrideType SetPlaylistVarOverride; - -typedef char* (*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides); -extern GetCurrentPlaylistVarType GetCurrentPlaylistVar; - -// server entity stuff -typedef void* (*Server_GetEntityByIndexType)(int index); -extern Server_GetEntityByIndexType Server_GetEntityByIndex; - -// auth -extern char* g_LocalPlayerUserID; -extern char* g_LocalPlayerOriginToken; - -// misc stuff -typedef void (*ErrorType)(const char* fmt, ...); -extern ErrorType Error; - -typedef CCommandLine* (*CommandLineType)(); -extern CommandLineType CommandLine; - -typedef double (*Plat_FloatTimeType)(); -extern Plat_FloatTimeType Plat_FloatTime; - -typedef bool (*ThreadInServerFrameThreadType)(); -extern ThreadInServerFrameThreadType ThreadInServerFrameThread; - -typedef void* (*GetBaseLocalClientType)(); -extern GetBaseLocalClientType GetBaseLocalClient; - -void InitialiseEngineGameUtilFunctions(HMODULE baseAddress); -void InitialiseServerGameUtilFunctions(HMODULE baseAddress); -void InitialiseTier0GameUtilFunctions(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/hooks.cpp b/NorthstarDedicatedTest/hooks.cpp deleted file mode 100644 index cc99341a..00000000 --- a/NorthstarDedicatedTest/hooks.cpp +++ /dev/null @@ -1,255 +0,0 @@ -#include "pch.h" -#include "hooks.h" -#include "hookutils.h" -#include "sigscanning.h" -#include "dedicated.h" - -#include <wchar.h> -#include <iostream> -#include <vector> -#include <fstream> -#include <sstream> -#include <filesystem> -#include <Psapi.h> - -typedef LPSTR (*GetCommandLineAType)(); -LPSTR GetCommandLineAHook(); - -typedef HMODULE (*LoadLibraryExAType)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); -HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); - -typedef HMODULE (*LoadLibraryAType)(LPCSTR lpLibFileName); -HMODULE LoadLibraryAHook(LPCSTR lpLibFileName); - -typedef HMODULE (*LoadLibraryExWType)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); -HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); - -typedef HMODULE (*LoadLibraryWType)(LPCWSTR lpLibFileName); -HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName); - -GetCommandLineAType GetCommandLineAOriginal; -LoadLibraryExAType LoadLibraryExAOriginal; -LoadLibraryAType LoadLibraryAOriginal; -LoadLibraryExWType LoadLibraryExWOriginal; -LoadLibraryWType LoadLibraryWOriginal; - -void InstallInitialHooks() -{ - if (MH_Initialize() != MH_OK) - spdlog::error("MH_Initialize (minhook initialization) failed"); - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, &GetCommandLineA, &GetCommandLineAHook, reinterpret_cast<LPVOID*>(&GetCommandLineAOriginal)); - ENABLER_CREATEHOOK(hook, &LoadLibraryExA, &LoadLibraryExAHook, reinterpret_cast<LPVOID*>(&LoadLibraryExAOriginal)); - ENABLER_CREATEHOOK(hook, &LoadLibraryA, &LoadLibraryAHook, reinterpret_cast<LPVOID*>(&LoadLibraryAOriginal)); - ENABLER_CREATEHOOK(hook, &LoadLibraryExW, &LoadLibraryExWHook, reinterpret_cast<LPVOID*>(&LoadLibraryExWOriginal)); - ENABLER_CREATEHOOK(hook, &LoadLibraryW, &LoadLibraryWHook, reinterpret_cast<LPVOID*>(&LoadLibraryWOriginal)); -} - -LPSTR GetCommandLineAHook() -{ - static char* cmdlineModified; - static char* cmdlineOrg; - - if (cmdlineOrg == nullptr || cmdlineModified == nullptr) - { - cmdlineOrg = GetCommandLineAOriginal(); - bool isDedi = strstr(cmdlineOrg, "-dedicated"); // well, this one has to be a real argument - bool ignoreStartupArgs = strstr(cmdlineOrg, "-nostartupargs"); - - std::string args; - std::ifstream cmdlineArgFile; - - // it looks like CommandLine() prioritizes parameters apprearing first, so we want the real commandline to take priority - // not to mention that cmdlineOrg starts with the EXE path - args.append(cmdlineOrg); - args.append(" "); - - // append those from the file - - if (!ignoreStartupArgs) - { - - cmdlineArgFile = std::ifstream(!isDedi ? "ns_startup_args.txt" : "ns_startup_args_dedi.txt"); - - if (cmdlineArgFile) - { - std::stringstream argBuffer; - argBuffer << cmdlineArgFile.rdbuf(); - cmdlineArgFile.close(); - - // if some other command line option includes "-northstar" in the future then you have to refactor this check to check with - // both either space after or ending with - if (!isDedi && argBuffer.str().find("-northstar") != std::string::npos) - MessageBoxA( - NULL, - "The \"-northstar\" command line option is NOT supposed to go into ns_startup_args.txt file!\n\nThis option is " - "supposed to go into Origin/Steam game launch options, and then you are supposed to launch the original " - "Titanfall2.exe " - "rather than NorthstarLauncher.exe to make use of it.", - "Northstar Warning", - MB_ICONWARNING); - - args.append(argBuffer.str()); - } - } - - auto len = args.length(); - cmdlineModified = new char[len + 1]; - if (!cmdlineModified) - { - spdlog::error("malloc failed for command line"); - return cmdlineOrg; - } - memcpy(cmdlineModified, args.c_str(), len + 1); - - spdlog::info("Command line: {}", cmdlineModified); - } - - return cmdlineModified; -} - -// dll load callback stuff -// this allows for code to register callbacks to be run as soon as a dll is loaded, mainly to allow for patches to be made on dll load -struct DllLoadCallback -{ - std::string dll; - DllLoadCallbackFuncType callback; - bool called; -}; - -std::vector<DllLoadCallback*> dllLoadCallbacks; - -void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback) -{ - DllLoadCallback* callbackStruct = new DllLoadCallback; - callbackStruct->dll = dll; - callbackStruct->callback = callback; - callbackStruct->called = false; - - dllLoadCallbacks.push_back(callbackStruct); -} - -void AddDllLoadCallbackForDedicatedServer(std::string dll, DllLoadCallbackFuncType callback) -{ - if (!IsDedicated()) - return; - - DllLoadCallback* callbackStruct = new DllLoadCallback; - callbackStruct->dll = dll; - callbackStruct->callback = callback; - callbackStruct->called = false; - - dllLoadCallbacks.push_back(callbackStruct); -} - -void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback) -{ - if (IsDedicated()) - return; - - DllLoadCallback* callbackStruct = new DllLoadCallback; - callbackStruct->dll = dll; - callbackStruct->callback = callback; - callbackStruct->called = false; - - dllLoadCallbacks.push_back(callbackStruct); -} - -void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress) -{ - for (auto& callbackStruct : dllLoadCallbacks) - { - if (!callbackStruct->called && - strstr(lpLibFileName + (strlen(lpLibFileName) - callbackStruct->dll.length()), callbackStruct->dll.c_str()) != nullptr) - { - callbackStruct->callback(moduleAddress); - callbackStruct->called = true; - } - } -} - -void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress) -{ - for (auto& callbackStruct : dllLoadCallbacks) - { - std::wstring wcharStrDll = std::wstring(callbackStruct->dll.begin(), callbackStruct->dll.end()); - const wchar_t* callbackDll = wcharStrDll.c_str(); - if (!callbackStruct->called && wcsstr(lpLibFileName + (wcslen(lpLibFileName) - wcharStrDll.length()), callbackDll) != nullptr) - { - callbackStruct->callback(moduleAddress); - callbackStruct->called = true; - } - } -} - -void CallAllPendingDLLLoadCallbacks() -{ - HMODULE hMods[1024]; - HANDLE hProcess = GetCurrentProcess(); - DWORD cbNeeded; - unsigned int i; - - // Get a list of all the modules in this process. - if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) - { - for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) - { - wchar_t szModName[MAX_PATH]; - - // Get the full path to the module's file. - if (GetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) - { - CallLoadLibraryWCallbacks(szModName, hMods[i]); - } - } - } -} - -HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - HMODULE moduleAddress = LoadLibraryExAOriginal(lpLibFileName, hFile, dwFlags); - - if (moduleAddress) - { - CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); - } - - return moduleAddress; -} - -HMODULE LoadLibraryAHook(LPCSTR lpLibFileName) -{ - HMODULE moduleAddress = LoadLibraryAOriginal(lpLibFileName); - - if (moduleAddress) - { - CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); - } - - return moduleAddress; -} - -HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - HMODULE moduleAddress = LoadLibraryExWOriginal(lpLibFileName, hFile, dwFlags); - - if (moduleAddress) - { - CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); - } - - return moduleAddress; -} - -HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName) -{ - HMODULE moduleAddress = LoadLibraryWOriginal(lpLibFileName); - - if (moduleAddress) - { - CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); - } - - return moduleAddress; -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/hooks.h b/NorthstarDedicatedTest/hooks.h deleted file mode 100644 index ab7b3d64..00000000 --- a/NorthstarDedicatedTest/hooks.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include <string> - -void InstallInitialHooks(); - -typedef void (*DllLoadCallbackFuncType)(HMODULE moduleAddress); -void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback); -void AddDllLoadCallbackForDedicatedServer(std::string dll, DllLoadCallbackFuncType callback); -void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback); - -void CallAllPendingDLLLoadCallbacks();
\ No newline at end of file diff --git a/NorthstarDedicatedTest/hookutils.cpp b/NorthstarDedicatedTest/hookutils.cpp deleted file mode 100644 index f5df3996..00000000 --- a/NorthstarDedicatedTest/hookutils.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "pch.h" -#include "hookutils.h" - -#include <iostream> - -void HookEnabler::CreateHook(LPVOID ppTarget, LPVOID ppDetour, LPVOID* ppOriginal, const char* targetName) -{ - // the macro for this uses ppTarget's name as targetName, and this typically starts with & - // targetname is used for debug stuff and debug output is nicer if we don't have this - if (*targetName == '&') - targetName++; - - if (MH_CreateHook(ppTarget, ppDetour, ppOriginal) == MH_OK) - { - HookTarget* target = new HookTarget; - target->targetAddress = ppTarget; - target->targetName = (char*)targetName; - - m_hookTargets.push_back(target); - } - else - { - if (targetName != nullptr) - spdlog::error("MH_CreateHook failed for function {}", targetName); - else - spdlog::error("MH_CreateHook failed for unknown function"); - } -} - -HookEnabler::~HookEnabler() -{ - for (auto& hook : m_hookTargets) - { - if (MH_EnableHook(hook->targetAddress) != MH_OK) - { - if (hook->targetName != nullptr) - spdlog::error("MH_EnableHook failed for function {}", hook->targetName); - else - spdlog::error("MH_EnableHook failed for unknown function"); - } - else - spdlog::info("Enabling hook {}", hook->targetName); - } -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/hookutils.h b/NorthstarDedicatedTest/hookutils.h deleted file mode 100644 index 47ec12bf..00000000 --- a/NorthstarDedicatedTest/hookutils.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include <vector> - -// Enables all hooks created with the HookEnabler object when it goes out of scope and handles hook errors -class HookEnabler -{ - private: - struct HookTarget - { - char* targetName; - LPVOID targetAddress; - }; - - std::vector<HookTarget*> m_hookTargets; - - public: - void CreateHook(LPVOID ppTarget, LPVOID ppDetour, LPVOID* ppOriginal, const char* targetName = nullptr); - ~HookEnabler(); -}; - -// macro to call HookEnabler::CreateHook with the hook's name -#define ENABLER_CREATEHOOK(enabler, ppTarget, ppDetour, ppOriginal) enabler.CreateHook(ppTarget, ppDetour, ppOriginal, #ppDetour)
\ No newline at end of file diff --git a/NorthstarDedicatedTest/keyvalues.h b/NorthstarDedicatedTest/keyvalues.h deleted file mode 100644 index b7de850d..00000000 --- a/NorthstarDedicatedTest/keyvalues.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseKeyValues(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/languagehooks.h b/NorthstarDedicatedTest/languagehooks.h deleted file mode 100644 index 55b591e0..00000000 --- a/NorthstarDedicatedTest/languagehooks.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseTier0LanguageHooks(HMODULE baseAddress); diff --git a/NorthstarDedicatedTest/latencyflex.cpp b/NorthstarDedicatedTest/latencyflex.cpp deleted file mode 100644 index 4ac1c760..00000000 --- a/NorthstarDedicatedTest/latencyflex.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "pch.h" -#include "latencyflex.h" -#include "hookutils.h" -#include "convar.h" - -typedef void (*OnRenderStartType)(); -OnRenderStartType OnRenderStart; - -ConVar* Cvar_r_latencyflex; - -HMODULE m_lfxModule {}; -typedef void (*PFN_winelfx_WaitAndBeginFrame)(); -PFN_winelfx_WaitAndBeginFrame m_winelfx_WaitAndBeginFrame {}; - -void OnRenderStartHook() -{ - if (Cvar_r_latencyflex->GetInt()) - m_winelfx_WaitAndBeginFrame(); - - OnRenderStart(); -} - -void InitialiseLatencyFleX(HMODULE baseAddress) -{ - // Connect to the LatencyFleX service - // LatencyFleX is an open source vendor agnostic replacement for Nvidia Reflex input latency reduction technology. - // https://ishitatsuyuki.github.io/post/latencyflex/ - m_lfxModule = LoadLibraryA("latencyflex_wine.dll"); - - if (m_lfxModule == nullptr) - { - spdlog::info("Unable to load LatencyFleX library, LatencyFleX disabled."); - return; - } - - m_winelfx_WaitAndBeginFrame = - reinterpret_cast<PFN_winelfx_WaitAndBeginFrame>(reinterpret_cast<void*>(GetProcAddress(m_lfxModule, "winelfx_WaitAndBeginFrame"))); - spdlog::info("LatencyFleX initialized."); - - Cvar_r_latencyflex = new ConVar("r_latencyflex", "1", FCVAR_ARCHIVE, "Whether or not to use LatencyFleX input latency reduction."); - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1952C0, &OnRenderStartHook, reinterpret_cast<LPVOID*>(&OnRenderStart)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/latencyflex.h b/NorthstarDedicatedTest/latencyflex.h deleted file mode 100644 index db801261..00000000 --- a/NorthstarDedicatedTest/latencyflex.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void InitialiseLatencyFleX(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/logging.h b/NorthstarDedicatedTest/logging.h deleted file mode 100644 index 2e78c81a..00000000 --- a/NorthstarDedicatedTest/logging.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "context.h" - -void CreateLogFiles(); -void InitialiseLogging(); -void InitialiseEngineSpewFuncHooks(HMODULE baseAddress); -void InitialiseClientPrintHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp deleted file mode 100644 index 38268e60..00000000 --- a/NorthstarDedicatedTest/masterserver.cpp +++ /dev/null @@ -1,1366 +0,0 @@ -#include "pch.h" -#include "masterserver.h" -#include "concommand.h" -#include "gameutils.h" -#include "hookutils.h" -#include "serverauthentication.h" -#include "gameutils.h" -#include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" -#include "rapidjson/error/en.h" -#include "modmanager.h" -#include "misccommands.h" -#include <cstring> -#include <regex> -#include "version.h" -// NOTE for anyone reading this: we used to use httplib for requests here, but it had issues, so we're moving to curl now for masterserver -// requests so httplib is used exclusively for server stuff now - -ConVar* Cvar_ns_masterserver_hostname; -ConVar* Cvar_ns_report_server_to_masterserver; -ConVar* Cvar_ns_report_sp_server_to_masterserver; - -ConVar* Cvar_ns_server_name; -ConVar* Cvar_ns_server_desc; -ConVar* Cvar_ns_server_password; - -ConVar* Cvar_ns_curl_log_enable; - -// Source ConVar -ConVar* Cvar_hostname; - -MasterServerManager* g_MasterServerManager; - -typedef void (*CHostState__State_NewGameType)(CHostState* hostState); -CHostState__State_NewGameType CHostState__State_NewGame; - -typedef void (*CHostState__State_ChangeLevelMPType)(CHostState* hostState); -CHostState__State_ChangeLevelMPType CHostState__State_ChangeLevelMP; - -typedef void (*CHostState__State_ChangeLevelSPType)(CHostState* hostState); -CHostState__State_ChangeLevelSPType CHostState__State_ChangeLevelSP; - -typedef void (*CHostState__State_GameShutdownType)(CHostState* hostState); -CHostState__State_GameShutdownType CHostState__State_GameShutdown; - -// Convert a hex digit char to integer. -inline int hctod(char c) -{ - if (c >= 'A' && c <= 'F') - { - return c - 'A' + 10; - } - else if (c >= 'a' && c <= 'f') - { - return c - 'a' + 10; - } - else - { - return c - '0'; - } -} - -// This function interprets all 4-hexadecimal-digit unicode codepoint characters like \u4E2D to UTF-8 encoding. -std::string unescape_unicode(const std::string& str) -{ - std::string result; - std::regex r("\\\\u([a-f\\d]{4})", std::regex::icase); - auto matches_begin = std::sregex_iterator(str.begin(), str.end(), r); - auto matches_end = std::sregex_iterator(); - std::smatch last_match; - for (std::sregex_iterator i = matches_begin; i != matches_end; ++i) - { - last_match = *i; - result.append(last_match.prefix()); - unsigned int cp = 0; - for (int i = 2; i <= 5; ++i) - { - cp *= 16; - cp += hctod(last_match.str()[i]); - } - if (cp <= 0x7F) - { - result.push_back(cp); - } - else if (cp <= 0x7FF) - { - result.push_back((cp >> 6) | 0b11000000 & (~(1 << 5))); - result.push_back(cp & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); - } - else if (cp <= 0xFFFF) - { - result.push_back((cp >> 12) | 0b11100000 & (~(1 << 4))); - result.push_back((cp >> 6) & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); - result.push_back(cp & ((1 << 6) - 1) | 0b10000000 & (~(1 << 6))); - } - } - if (!last_match.ready()) - { - return str; - } - else - { - result.append(last_match.suffix()); - } - return result; -} - -void UpdateServerInfoFromUnicodeToUTF8() -{ - g_MasterServerManager->ns_auth_srvName = unescape_unicode(Cvar_ns_server_name->GetString()); - g_MasterServerManager->ns_auth_srvDesc = unescape_unicode(Cvar_ns_server_desc->GetString()); -} - -const char* HttplibErrorToString(httplib::Error error) -{ - switch (error) - { - case httplib::Error::Success: - return "httplib::Error::Success"; - case httplib::Error::Unknown: - return "httplib::Error::Unknown"; - case httplib::Error::Connection: - return "httplib::Error::Connection"; - case httplib::Error::BindIPAddress: - return "httplib::Error::BindIPAddress"; - case httplib::Error::Read: - return "httplib::Error::Read"; - case httplib::Error::Write: - return "httplib::Error::Write"; - case httplib::Error::ExceedRedirectCount: - return "httplib::Error::ExceedRedirectCount"; - case httplib::Error::Canceled: - return "httplib::Error::Canceled"; - case httplib::Error::SSLConnection: - return "httplib::Error::SSLConnection"; - case httplib::Error::SSLLoadingCerts: - return "httplib::Error::SSLLoadingCerts"; - case httplib::Error::SSLServerVerification: - return "httplib::Error::SSLServerVerification"; - case httplib::Error::UnsupportedMultipartBoundaryChars: - return "httplib::Error::UnsupportedMultipartBoundaryChars"; - } - - return ""; -} - -RemoteServerInfo::RemoteServerInfo( - const char* newId, - const char* newName, - const char* newDescription, - const char* newMap, - const char* newPlaylist, - int newPlayerCount, - int newMaxPlayers, - bool newRequiresPassword) -{ - // passworded servers don't have public ips - requiresPassword = newRequiresPassword; - - strncpy((char*)id, newId, sizeof(id)); - id[sizeof(id) - 1] = 0; - strncpy((char*)name, newName, sizeof(name)); - name[sizeof(name) - 1] = 0; - - description = std::string(newDescription); - - strncpy((char*)map, newMap, sizeof(map)); - map[sizeof(map) - 1] = 0; - strncpy((char*)playlist, newPlaylist, sizeof(playlist)); - playlist[sizeof(playlist) - 1] = 0; - - playerCount = newPlayerCount; - maxPlayers = newMaxPlayers; -} - -void MasterServerManager::SetCommonHttpClientOptions(CURL* curl) -{ - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); - curl_easy_setopt(curl, CURLOPT_VERBOSE, Cvar_ns_curl_log_enable->GetBool()); - curl_easy_setopt(curl, CURLOPT_USERAGENT, &NSUserAgent); - // curl_easy_setopt(curl, CURLOPT_STDERR, stdout); - if (CommandLine()->FindParm("-msinsecure")) // TODO: this check doesn't seem to work - { - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - } -} - -void MasterServerManager::ClearServerList() -{ - // this doesn't really do anything lol, probably isn't threadsafe - m_requestingServerList = true; - - m_remoteServers.clear(); - - m_requestingServerList = false; -} - -size_t CurlWriteToStringBufferCallback(char* contents, size_t size, size_t nmemb, void* userp) -{ - ((std::string*)userp)->append((char*)contents, size * nmemb); - return size * nmemb; -} - -void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* originToken) -{ - if (m_bOriginAuthWithMasterServerInProgress) - return; - - // do this here so it's instantly set - m_bOriginAuthWithMasterServerInProgress = true; - std::string uidStr(uid); - std::string tokenStr(originToken); - - std::thread requestThread( - [this, uidStr, tokenStr]() - { - spdlog::info("Trying to authenticate with northstar masterserver for user {}", uidStr); - - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - std::string readBuffer; - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format("{}/client/origin_auth?id={}&token={}", Cvar_ns_masterserver_hostname->GetString(), uidStr, tokenStr).c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - { - m_successfullyConnected = true; - - rapidjson_document originAuthInfo; - originAuthInfo.Parse(readBuffer.c_str()); - - if (originAuthInfo.HasParseError()) - { - spdlog::error( - "Failed reading origin auth info response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(originAuthInfo.GetParseError())); - goto REQUEST_END_CLEANUP; - } - - if (!originAuthInfo.IsObject() || !originAuthInfo.HasMember("success")) - { - spdlog::error("Failed reading origin auth info response: malformed response object {}", readBuffer); - goto REQUEST_END_CLEANUP; - } - - if (originAuthInfo["success"].IsTrue() && originAuthInfo.HasMember("token") && originAuthInfo["token"].IsString()) - { - strncpy(m_ownClientAuthToken, originAuthInfo["token"].GetString(), sizeof(m_ownClientAuthToken)); - m_ownClientAuthToken[sizeof(m_ownClientAuthToken) - 1] = 0; - spdlog::info("Northstar origin authentication completed successfully!"); - } - else - spdlog::error("Northstar origin authentication failed"); - } - else - { - spdlog::error("Failed performing northstar origin auth: error {}", curl_easy_strerror(result)); - m_successfullyConnected = false; - } - - // we goto this instead of returning so we always hit this - REQUEST_END_CLEANUP: - m_bOriginAuthWithMasterServerInProgress = false; - m_bOriginAuthWithMasterServerDone = true; - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::RequestServerList() -{ - // do this here so it's instantly set on call for scripts - m_scriptRequestingServerList = true; - - std::thread requestThread( - [this]() - { - // make sure we never have 2 threads writing at once - // i sure do hope this is actually threadsafe - while (m_requestingServerList) - Sleep(100); - - m_requestingServerList = true; - m_scriptRequestingServerList = true; - - spdlog::info("Requesting server list from {}", Cvar_ns_masterserver_hostname->GetString()); - - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_URL, fmt::format("{}/client/servers", Cvar_ns_masterserver_hostname->GetString()).c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - { - m_successfullyConnected = true; - - rapidjson_document serverInfoJson; - serverInfoJson.Parse(readBuffer.c_str()); - - if (serverInfoJson.HasParseError()) - { - spdlog::error( - "Failed reading masterserver response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(serverInfoJson.GetParseError())); - goto REQUEST_END_CLEANUP; - } - - if (serverInfoJson.IsObject() && serverInfoJson.HasMember("error")) - { - spdlog::error("Failed reading masterserver response: got fastify error response"); - spdlog::error(readBuffer); - goto REQUEST_END_CLEANUP; - } - - if (!serverInfoJson.IsArray()) - { - spdlog::error("Failed reading masterserver response: root object is not an array"); - goto REQUEST_END_CLEANUP; - } - - rapidjson::GenericArray<false, rapidjson_document::GenericValue> serverArray = serverInfoJson.GetArray(); - - spdlog::info("Got {} servers", serverArray.Size()); - - for (auto& serverObj : serverArray) - { - if (!serverObj.IsObject()) - { - spdlog::error("Failed reading masterserver response: member of server array is not an object"); - goto REQUEST_END_CLEANUP; - } - - // todo: verify json props are fine before adding to m_remoteServers - if (!serverObj.HasMember("id") || !serverObj["id"].IsString() || !serverObj.HasMember("name") || - !serverObj["name"].IsString() || !serverObj.HasMember("description") || !serverObj["description"].IsString() || - !serverObj.HasMember("map") || !serverObj["map"].IsString() || !serverObj.HasMember("playlist") || - !serverObj["playlist"].IsString() || !serverObj.HasMember("playerCount") || !serverObj["playerCount"].IsNumber() || - !serverObj.HasMember("maxPlayers") || !serverObj["maxPlayers"].IsNumber() || !serverObj.HasMember("hasPassword") || - !serverObj["hasPassword"].IsBool() || !serverObj.HasMember("modInfo") || !serverObj["modInfo"].HasMember("Mods") || - !serverObj["modInfo"]["Mods"].IsArray()) - { - spdlog::error("Failed reading masterserver response: malformed server object"); - continue; - }; - - const char* id = serverObj["id"].GetString(); - - RemoteServerInfo* newServer = nullptr; - - bool createNewServerInfo = true; - for (RemoteServerInfo& server : m_remoteServers) - { - // if server already exists, update info rather than adding to it - if (!strncmp((const char*)server.id, id, 32)) - { - server = RemoteServerInfo( - id, - serverObj["name"].GetString(), - serverObj["description"].GetString(), - serverObj["map"].GetString(), - serverObj["playlist"].GetString(), - serverObj["playerCount"].GetInt(), - serverObj["maxPlayers"].GetInt(), - serverObj["hasPassword"].IsTrue()); - newServer = &server; - createNewServerInfo = false; - break; - } - } - - // server didn't exist - if (createNewServerInfo) - newServer = &m_remoteServers.emplace_back( - id, - serverObj["name"].GetString(), - serverObj["description"].GetString(), - serverObj["map"].GetString(), - serverObj["playlist"].GetString(), - serverObj["playerCount"].GetInt(), - serverObj["maxPlayers"].GetInt(), - serverObj["hasPassword"].IsTrue()); - - newServer->requiredMods.clear(); - for (auto& requiredMod : serverObj["modInfo"]["Mods"].GetArray()) - { - RemoteModInfo modInfo; - - if (!requiredMod.HasMember("RequiredOnClient") || !requiredMod["RequiredOnClient"].IsTrue()) - continue; - - if (!requiredMod.HasMember("Name") || !requiredMod["Name"].IsString()) - continue; - modInfo.Name = requiredMod["Name"].GetString(); - - if (!requiredMod.HasMember("Version") || !requiredMod["Version"].IsString()) - continue; - modInfo.Version = requiredMod["Version"].GetString(); - - newServer->requiredMods.push_back(modInfo); - } - // Can probably re-enable this later with a -verbose flag, but slows down loading of the server browser quite a bit as - // is - // spdlog::info( - // "Server {} on map {} with playlist {} has {}/{} players", serverObj["name"].GetString(), - // serverObj["map"].GetString(), serverObj["playlist"].GetString(), serverObj["playerCount"].GetInt(), - // serverObj["maxPlayers"].GetInt()); - } - - std::sort( - m_remoteServers.begin(), - m_remoteServers.end(), - [](RemoteServerInfo& a, RemoteServerInfo& b) { return a.playerCount > b.playerCount; }); - } - else - { - spdlog::error("Failed requesting servers: error {}", curl_easy_strerror(result)); - m_successfullyConnected = false; - } - - // we goto this instead of returning so we always hit this - REQUEST_END_CLEANUP: - m_requestingServerList = false; - m_scriptRequestingServerList = false; - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::RequestMainMenuPromos() -{ - m_bHasMainMenuPromoData = false; - - std::thread requestThread( - [this]() - { - while (m_bOriginAuthWithMasterServerInProgress || !m_bOriginAuthWithMasterServerDone) - Sleep(500); - - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt( - curl, CURLOPT_URL, fmt::format("{}/client/mainmenupromos", Cvar_ns_masterserver_hostname->GetString()).c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - { - m_successfullyConnected = true; - - rapidjson_document mainMenuPromoJson; - mainMenuPromoJson.Parse(readBuffer.c_str()); - - if (mainMenuPromoJson.HasParseError()) - { - spdlog::error( - "Failed reading masterserver main menu promos response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(mainMenuPromoJson.GetParseError())); - goto REQUEST_END_CLEANUP; - } - - if (!mainMenuPromoJson.IsObject()) - { - spdlog::error("Failed reading masterserver main menu promos response: root object is not an object"); - goto REQUEST_END_CLEANUP; - } - - if (mainMenuPromoJson.HasMember("error")) - { - spdlog::error("Failed reading masterserver response: got fastify error response"); - spdlog::error(readBuffer); - goto REQUEST_END_CLEANUP; - } - - if (!mainMenuPromoJson.HasMember("newInfo") || !mainMenuPromoJson["newInfo"].IsObject() || - !mainMenuPromoJson["newInfo"].HasMember("Title1") || !mainMenuPromoJson["newInfo"]["Title1"].IsString() || - !mainMenuPromoJson["newInfo"].HasMember("Title2") || !mainMenuPromoJson["newInfo"]["Title2"].IsString() || - !mainMenuPromoJson["newInfo"].HasMember("Title3") || !mainMenuPromoJson["newInfo"]["Title3"].IsString() || - - !mainMenuPromoJson.HasMember("largeButton") || !mainMenuPromoJson["largeButton"].IsObject() || - !mainMenuPromoJson["largeButton"].HasMember("Title") || !mainMenuPromoJson["largeButton"]["Title"].IsString() || - !mainMenuPromoJson["largeButton"].HasMember("Text") || !mainMenuPromoJson["largeButton"]["Text"].IsString() || - !mainMenuPromoJson["largeButton"].HasMember("Url") || !mainMenuPromoJson["largeButton"]["Url"].IsString() || - !mainMenuPromoJson["largeButton"].HasMember("ImageIndex") || - !mainMenuPromoJson["largeButton"]["ImageIndex"].IsNumber() || - - !mainMenuPromoJson.HasMember("smallButton1") || !mainMenuPromoJson["smallButton1"].IsObject() || - !mainMenuPromoJson["smallButton1"].HasMember("Title") || !mainMenuPromoJson["smallButton1"]["Title"].IsString() || - !mainMenuPromoJson["smallButton1"].HasMember("Url") || !mainMenuPromoJson["smallButton1"]["Url"].IsString() || - !mainMenuPromoJson["smallButton1"].HasMember("ImageIndex") || - !mainMenuPromoJson["smallButton1"]["ImageIndex"].IsNumber() || - - !mainMenuPromoJson.HasMember("smallButton2") || !mainMenuPromoJson["smallButton2"].IsObject() || - !mainMenuPromoJson["smallButton2"].HasMember("Title") || !mainMenuPromoJson["smallButton2"]["Title"].IsString() || - !mainMenuPromoJson["smallButton2"].HasMember("Url") || !mainMenuPromoJson["smallButton2"]["Url"].IsString() || - !mainMenuPromoJson["smallButton2"].HasMember("ImageIndex") || - !mainMenuPromoJson["smallButton2"]["ImageIndex"].IsNumber()) - { - spdlog::error("Failed reading masterserver main menu promos response: malformed json object"); - goto REQUEST_END_CLEANUP; - } - - m_MainMenuPromoData.newInfoTitle1 = mainMenuPromoJson["newInfo"]["Title1"].GetString(); - m_MainMenuPromoData.newInfoTitle2 = mainMenuPromoJson["newInfo"]["Title2"].GetString(); - m_MainMenuPromoData.newInfoTitle3 = mainMenuPromoJson["newInfo"]["Title3"].GetString(); - - m_MainMenuPromoData.largeButtonTitle = mainMenuPromoJson["largeButton"]["Title"].GetString(); - m_MainMenuPromoData.largeButtonText = mainMenuPromoJson["largeButton"]["Text"].GetString(); - m_MainMenuPromoData.largeButtonUrl = mainMenuPromoJson["largeButton"]["Url"].GetString(); - m_MainMenuPromoData.largeButtonImageIndex = mainMenuPromoJson["largeButton"]["ImageIndex"].GetInt(); - - m_MainMenuPromoData.smallButton1Title = mainMenuPromoJson["smallButton1"]["Title"].GetString(); - m_MainMenuPromoData.smallButton1Url = mainMenuPromoJson["smallButton1"]["Url"].GetString(); - m_MainMenuPromoData.smallButton1ImageIndex = mainMenuPromoJson["smallButton1"]["ImageIndex"].GetInt(); - - m_MainMenuPromoData.smallButton2Title = mainMenuPromoJson["smallButton2"]["Title"].GetString(); - m_MainMenuPromoData.smallButton2Url = mainMenuPromoJson["smallButton2"]["Url"].GetString(); - m_MainMenuPromoData.smallButton2ImageIndex = mainMenuPromoJson["smallButton2"]["ImageIndex"].GetInt(); - - m_bHasMainMenuPromoData = true; - } - else - { - spdlog::error("Failed requesting main menu promos: error {}", curl_easy_strerror(result)); - m_successfullyConnected = false; - } - - REQUEST_END_CLEANUP: - // nothing lol - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken) -{ - // dont wait, just stop if we're trying to do 2 auth requests at once - if (m_authenticatingWithGameServer) - return; - - m_authenticatingWithGameServer = true; - m_scriptAuthenticatingWithGameServer = true; - m_successfullyAuthenticatedWithGameServer = false; - - std::string uidStr(uid); - std::string tokenStr(playerToken); - - std::thread requestThread( - [this, uidStr, tokenStr]() - { - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format("{}/client/auth_with_self?id={}&playerToken={}", Cvar_ns_masterserver_hostname->GetString(), uidStr, tokenStr) - .c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - { - m_successfullyConnected = true; - - rapidjson_document authInfoJson; - authInfoJson.Parse(readBuffer.c_str()); - - if (authInfoJson.HasParseError()) - { - spdlog::error( - "Failed reading masterserver authentication response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(authInfoJson.GetParseError())); - goto REQUEST_END_CLEANUP; - } - - if (!authInfoJson.IsObject()) - { - spdlog::error("Failed reading masterserver authentication response: root object is not an object"); - goto REQUEST_END_CLEANUP; - } - - if (authInfoJson.HasMember("error")) - { - spdlog::error("Failed reading masterserver response: got fastify error response"); - spdlog::error(readBuffer); - goto REQUEST_END_CLEANUP; - } - - if (!authInfoJson["success"].IsTrue()) - { - spdlog::error("Authentication with masterserver failed: \"success\" is not true"); - goto REQUEST_END_CLEANUP; - } - - if (!authInfoJson.HasMember("success") || !authInfoJson.HasMember("id") || !authInfoJson["id"].IsString() || - !authInfoJson.HasMember("authToken") || !authInfoJson["authToken"].IsString() || - !authInfoJson.HasMember("persistentData") || !authInfoJson["persistentData"].IsArray()) - { - spdlog::error("Failed reading masterserver authentication response: malformed json object"); - goto REQUEST_END_CLEANUP; - } - - AuthData newAuthData {}; - strncpy(newAuthData.uid, authInfoJson["id"].GetString(), sizeof(newAuthData.uid)); - newAuthData.uid[sizeof(newAuthData.uid) - 1] = 0; - - newAuthData.pdataSize = authInfoJson["persistentData"].GetArray().Size(); - newAuthData.pdata = new char[newAuthData.pdataSize]; - // memcpy(newAuthData.pdata, authInfoJson["persistentData"].GetString(), newAuthData.pdataSize); - - int i = 0; - // note: persistentData is a uint8array because i had problems getting strings to behave, it sucks but it's just how it be - // unfortunately potentially refactor later - for (auto& byte : authInfoJson["persistentData"].GetArray()) - { - if (!byte.IsUint() || byte.GetUint() > 255) - { - spdlog::error("Failed reading masterserver authentication response: malformed json object"); - goto REQUEST_END_CLEANUP; - } - - newAuthData.pdata[i++] = static_cast<char>(byte.GetUint()); - } - - std::lock_guard<std::mutex> guard(g_ServerAuthenticationManager->m_authDataMutex); - g_ServerAuthenticationManager->m_authData.clear(); - g_ServerAuthenticationManager->m_authData.insert(std::make_pair(authInfoJson["authToken"].GetString(), newAuthData)); - - m_successfullyAuthenticatedWithGameServer = true; - } - else - { - spdlog::error("Failed authenticating with own server: error {}", curl_easy_strerror(result)); - m_successfullyConnected = false; - m_successfullyAuthenticatedWithGameServer = false; - m_scriptAuthenticatingWithGameServer = false; - } - - REQUEST_END_CLEANUP: - m_authenticatingWithGameServer = false; - m_scriptAuthenticatingWithGameServer = false; - - if (m_bNewgameAfterSelfAuth) - { - // pretty sure this is threadsafe? - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "ns_end_reauth_and_leave_to_lobby", cmd_source_t::kCommandSrcCode); - m_bNewgameAfterSelfAuth = false; - } - - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, char* serverId, char* password) -{ - // dont wait, just stop if we're trying to do 2 auth requests at once - if (m_authenticatingWithGameServer) - return; - - m_authenticatingWithGameServer = true; - m_scriptAuthenticatingWithGameServer = true; - m_successfullyAuthenticatedWithGameServer = false; - - std::string uidStr(uid); - std::string tokenStr(playerToken); - std::string serverIdStr(serverId); - std::string passwordStr(password); - - std::thread requestThread( - [this, uidStr, tokenStr, serverIdStr, passwordStr]() - { - // esnure that any persistence saving is done, so we know masterserver has newest - while (m_savingPersistentData) - Sleep(100); - - spdlog::info("Attempting authentication with server of id \"{}\"", serverIdStr); - - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - { - char* escapedPassword = curl_easy_escape(curl, passwordStr.c_str(), passwordStr.length()); - - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/client/auth_with_server?id={}&playerToken={}&server={}&password={}", - Cvar_ns_masterserver_hostname->GetString(), - uidStr, - tokenStr, - serverIdStr, - escapedPassword) - .c_str()); - - curl_free(escapedPassword); - } - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - { - m_successfullyConnected = true; - - rapidjson_document connectionInfoJson; - connectionInfoJson.Parse(readBuffer.c_str()); - - if (connectionInfoJson.HasParseError()) - { - spdlog::error( - "Failed reading masterserver authentication response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(connectionInfoJson.GetParseError())); - goto REQUEST_END_CLEANUP; - } - - if (!connectionInfoJson.IsObject()) - { - spdlog::error("Failed reading masterserver authentication response: root object is not an object"); - goto REQUEST_END_CLEANUP; - } - - if (connectionInfoJson.HasMember("error")) - { - spdlog::error("Failed reading masterserver response: got fastify error response"); - spdlog::error(readBuffer); - goto REQUEST_END_CLEANUP; - } - - if (!connectionInfoJson["success"].IsTrue()) - { - spdlog::error("Authentication with masterserver failed: \"success\" is not true"); - goto REQUEST_END_CLEANUP; - } - - if (!connectionInfoJson.HasMember("success") || !connectionInfoJson.HasMember("ip") || - !connectionInfoJson["ip"].IsString() || !connectionInfoJson.HasMember("port") || - !connectionInfoJson["port"].IsNumber() || !connectionInfoJson.HasMember("authToken") || - !connectionInfoJson["authToken"].IsString()) - { - spdlog::error("Failed reading masterserver authentication response: malformed json object"); - goto REQUEST_END_CLEANUP; - } - - m_pendingConnectionInfo.ip.S_un.S_addr = inet_addr(connectionInfoJson["ip"].GetString()); - m_pendingConnectionInfo.port = (unsigned short)connectionInfoJson["port"].GetUint(); - - strncpy(m_pendingConnectionInfo.authToken, connectionInfoJson["authToken"].GetString(), 31); - m_pendingConnectionInfo.authToken[31] = 0; - - m_hasPendingConnectionInfo = true; - m_successfullyAuthenticatedWithGameServer = true; - } - else - { - spdlog::error("Failed authenticating with server: error {}", curl_easy_strerror(result)); - m_successfullyConnected = false; - m_successfullyAuthenticatedWithGameServer = false; - m_scriptAuthenticatingWithGameServer = false; - } - - REQUEST_END_CLEANUP: - m_authenticatingWithGameServer = false; - m_scriptAuthenticatingWithGameServer = false; - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::AddSelfToServerList( - int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password) -{ - if (!Cvar_ns_report_server_to_masterserver->GetBool()) - return; - - if (!Cvar_ns_report_sp_server_to_masterserver->GetBool() && !strncmp(map, "sp_", 3)) - { - m_bRequireClientAuth = false; - return; - } - - m_bRequireClientAuth = true; - - std::string strName(name); - std::string strDescription(description); - std::string strMap(map); - std::string strPlaylist(playlist); - std::string strPassword(password); - - std::thread requestThread( - [this, port, authPort, strName, strDescription, strMap, strPlaylist, maxPlayers, strPassword] - { - m_ownServerId[0] = 0; - m_ownServerAuthToken[0] = 0; - - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_POST, 1L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - curl_mime* mime = curl_mime_init(curl); - curl_mimepart* part = curl_mime_addpart(mime); - - curl_mime_data(part, m_ownModInfoJson.c_str(), m_ownModInfoJson.size()); - curl_mime_name(part, "modinfo"); - curl_mime_filename(part, "modinfo.json"); - curl_mime_type(part, "application/json"); - - curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); - - // format every paramter because computers hate me - { - char* nameEscaped = curl_easy_escape(curl, strName.c_str(), strName.length()); - char* descEscaped = curl_easy_escape(curl, strDescription.c_str(), strDescription.length()); - char* mapEscaped = curl_easy_escape(curl, strMap.c_str(), strMap.length()); - char* playlistEscaped = curl_easy_escape(curl, strPlaylist.c_str(), strPlaylist.length()); - char* passwordEscaped = curl_easy_escape(curl, strPassword.c_str(), strPassword.length()); - - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/server/add_server?port={}&authPort={}&name={}&description={}&map={}&playlist={}&maxPlayers={}&password={}", - Cvar_ns_masterserver_hostname->GetString(), - port, - authPort, - nameEscaped, - descEscaped, - mapEscaped, - playlistEscaped, - maxPlayers, - passwordEscaped) - .c_str()); - - curl_free(nameEscaped); - curl_free(descEscaped); - curl_free(mapEscaped); - curl_free(playlistEscaped); - curl_free(passwordEscaped); - } - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - { - m_successfullyConnected = true; - - rapidjson_document serverAddedJson; - serverAddedJson.Parse(readBuffer.c_str()); - - if (serverAddedJson.HasParseError()) - { - spdlog::error( - "Failed reading masterserver authentication response: encountered parse error \"{}\"", - rapidjson::GetParseError_En(serverAddedJson.GetParseError())); - goto REQUEST_END_CLEANUP; - } - - if (!serverAddedJson.IsObject()) - { - spdlog::error("Failed reading masterserver authentication response: root object is not an object"); - goto REQUEST_END_CLEANUP; - } - - if (serverAddedJson.HasMember("error")) - { - spdlog::error("Failed reading masterserver response: got fastify error response"); - spdlog::error(readBuffer); - goto REQUEST_END_CLEANUP; - } - - if (!serverAddedJson["success"].IsTrue()) - { - spdlog::error("Adding server to masterserver failed: \"success\" is not true"); - goto REQUEST_END_CLEANUP; - } - - if (!serverAddedJson.HasMember("id") || !serverAddedJson["id"].IsString() || - !serverAddedJson.HasMember("serverAuthToken") || !serverAddedJson["serverAuthToken"].IsString()) - { - spdlog::error("Failed reading masterserver response: malformed json object"); - goto REQUEST_END_CLEANUP; - } - - strncpy(m_ownServerId, serverAddedJson["id"].GetString(), sizeof(m_ownServerId)); - m_ownServerId[sizeof(m_ownServerId) - 1] = 0; - - strncpy(m_ownServerAuthToken, serverAddedJson["serverAuthToken"].GetString(), sizeof(m_ownServerAuthToken)); - m_ownServerAuthToken[sizeof(m_ownServerAuthToken) - 1] = 0; - - // heartbeat thread - // ideally this should actually be done in main thread, rather than on it's own thread, so it'd stop if server freezes - std::thread heartbeatThread( - [this] - { - Sleep(5000); - - // defensive check, as m_ownServer could be set to null during the Sleep(5000) above - if (!*m_ownServerId) - return; - - do - { - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); - - // send all registration info so we have all necessary info to reregister our server if masterserver goes down, - // without a restart this isn't threadsafe :terror: - { - char* escapedNameNew = curl_easy_escape(curl, g_MasterServerManager->ns_auth_srvName.c_str(), NULL); - char* escapedDescNew = curl_easy_escape(curl, g_MasterServerManager->ns_auth_srvDesc.c_str(), NULL); - char* escapedMapNew = curl_easy_escape(curl, g_pHostState->m_levelName, NULL); - char* escapedPlaylistNew = curl_easy_escape(curl, GetCurrentPlaylistName(), NULL); - char* escapedPasswordNew = curl_easy_escape(curl, Cvar_ns_server_password->GetString(), NULL); - - int maxPlayers = 6; - char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false); - if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this - maxPlayers = std::stoi(maxPlayersVar); - - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/server/" - "update_values?id={}&port={}&authPort={}&name={}&description={}&map={}&playlist={}&playerCount={}&" - "maxPlayers={}&password={}", - Cvar_ns_masterserver_hostname->GetString(), - m_ownServerId, - Cvar_hostport->GetInt(), - Cvar_ns_player_auth_port->GetInt(), - escapedNameNew, - escapedDescNew, - escapedMapNew, - escapedPlaylistNew, - g_ServerAuthenticationManager->m_additionalPlayerData.size(), - maxPlayers, - escapedPasswordNew) - .c_str()); - - curl_free(escapedNameNew); - curl_free(escapedDescNew); - curl_free(escapedMapNew); - curl_free(escapedPlaylistNew); - curl_free(escapedPasswordNew); - } - - curl_mime* mime = curl_mime_init(curl); - curl_mimepart* part = curl_mime_addpart(mime); - - curl_mime_data(part, m_ownModInfoJson.c_str(), m_ownModInfoJson.size()); - curl_mime_name(part, "modinfo"); - curl_mime_filename(part, "modinfo.json"); - curl_mime_type(part, "application/json"); - - curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); - - CURLcode result = curl_easy_perform(curl); - - // defensive check, as m_ownServerId could be set to null before this request gets processed - if (!*m_ownServerId) - return; - - if (result == CURLcode::CURLE_OK) - { - rapidjson_document serverAddedJson; - serverAddedJson.Parse(readBuffer.c_str()); - - if (!serverAddedJson.HasParseError() && serverAddedJson.IsObject()) - { - if (serverAddedJson.HasMember("id") && serverAddedJson["id"].IsString()) - { - strncpy(m_ownServerId, serverAddedJson["id"].GetString(), sizeof(m_ownServerId)); - m_ownServerId[sizeof(m_ownServerId) - 1] = 0; - } - - if (serverAddedJson.HasMember("serverAuthToken") && serverAddedJson["serverAuthToken"].IsString()) - { - strncpy( - m_ownServerAuthToken, - serverAddedJson["serverAuthToken"].GetString(), - sizeof(m_ownServerAuthToken)); - m_ownServerAuthToken[sizeof(m_ownServerAuthToken) - 1] = 0; - } - } - } - else - spdlog::warn("Heartbeat failed with error {}", curl_easy_strerror(result)); - - curl_easy_cleanup(curl); - Sleep(10000); - } while (*m_ownServerId); - }); - - heartbeatThread.detach(); - } - else - { - spdlog::error("Failed adding self to server list: error {}", curl_easy_strerror(result)); - m_successfullyConnected = false; - } - - REQUEST_END_CLEANUP: - curl_easy_cleanup(curl); - curl_mime_free(mime); - }); - - requestThread.detach(); -} - -void MasterServerManager::UpdateServerMapAndPlaylist(char* map, char* playlist, int maxPlayers) -{ - // dont call this if we don't have a server id - if (!*m_ownServerId) - return; - - std::string strMap(map); - std::string strPlaylist(playlist); - - std::thread requestThread( - [this, strMap, strPlaylist, maxPlayers] - { - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - // escape params - { - char* mapEscaped = curl_easy_escape(curl, strMap.c_str(), strMap.length()); - char* playlistEscaped = curl_easy_escape(curl, strPlaylist.c_str(), strPlaylist.length()); - - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/server/update_values?id={}&map={}&playlist={}&maxPlayers={}", - Cvar_ns_masterserver_hostname->GetString(), - m_ownServerId, - mapEscaped, - playlistEscaped, - maxPlayers) - .c_str()); - - curl_free(mapEscaped); - curl_free(playlistEscaped); - } - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - m_successfullyConnected = true; - else - m_successfullyConnected = false; - - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::UpdateServerPlayerCount(int playerCount) -{ - // dont call this if we don't have a server id - if (!*m_ownServerId) - return; - - std::thread requestThread( - [this, playerCount] - { - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/server/update_values?id={}&playerCount={}", Cvar_ns_masterserver_hostname->GetString(), m_ownServerId, playerCount) - .c_str()); - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - m_successfullyConnected = true; - else - m_successfullyConnected = false; - - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void MasterServerManager::WritePlayerPersistentData(char* playerId, char* pdata, size_t pdataSize) -{ - // still call this if we don't have a server id, since lobbies that aren't port forwarded need to be able to call it - m_savingPersistentData = true; - if (!pdataSize) - { - spdlog::warn("attempted to write pdata of size 0!"); - return; - } - - std::string strPlayerId(playerId); - std::string strPdata(pdata, pdataSize); - - std::thread requestThread( - [this, strPlayerId, strPdata, pdataSize] - { - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format( - "{}/accounts/write_persistence?id={}&serverId={}", - Cvar_ns_masterserver_hostname->GetString(), - strPlayerId, - m_ownServerId) - .c_str()); - curl_easy_setopt(curl, CURLOPT_POST, 1L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - curl_mime* mime = curl_mime_init(curl); - curl_mimepart* part = curl_mime_addpart(mime); - - curl_mime_data(part, strPdata.c_str(), pdataSize); - curl_mime_name(part, "pdata"); - curl_mime_filename(part, "file.pdata"); - curl_mime_type(part, "application/octet-stream"); - - curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); - - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - m_successfullyConnected = true; - else - m_successfullyConnected = false; - - curl_easy_cleanup(curl); - - m_savingPersistentData = false; - }); - - requestThread.detach(); -} - -void MasterServerManager::RemoveSelfFromServerList() -{ - // dont call this if we don't have a server id - if (!*m_ownServerId || !Cvar_ns_report_server_to_masterserver->GetBool()) - return; - - std::thread requestThread( - [this] - { - CURL* curl = curl_easy_init(); - SetCommonHttpClientOptions(curl); - - std::string readBuffer; - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_setopt( - curl, - CURLOPT_URL, - fmt::format("{}/server/remove_server?id={}", Cvar_ns_masterserver_hostname->GetString(), m_ownServerId).c_str()); - - *m_ownServerId = 0; - CURLcode result = curl_easy_perform(curl); - - if (result == CURLcode::CURLE_OK) - m_successfullyConnected = true; - else - m_successfullyConnected = false; - - curl_easy_cleanup(curl); - }); - - requestThread.detach(); -} - -void ConCommand_ns_fetchservers(const CCommand& args) -{ - g_MasterServerManager->RequestServerList(); -} - -void CHostState__State_NewGameHook(CHostState* hostState) -{ - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", cmd_source_t::kCommandSrcCode); - Cbuf_Execute(); - - // need to do this to ensure we don't go to private match - if (g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame) - SetCurrentPlaylist("tdm"); - - // net_data_block_enabled is required for sp, force it if we're on an sp map - // sucks for security but just how it be - if (!strncmp(g_pHostState->m_levelName, "sp_", 3)) - { - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "net_data_block_enabled 1", cmd_source_t::kCommandSrcCode); - Cbuf_Execute(); - } - - CHostState__State_NewGame(hostState); - - int maxPlayers = 6; - char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false); - if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this - maxPlayers = std::stoi(maxPlayersVar); - - // Copy new server name cvar to source - Cvar_hostname->SetValue(Cvar_ns_server_name->GetString()); - // This calls the function that converts unicode strings from servername and serverdesc to UTF-8 - UpdateServerInfoFromUnicodeToUTF8(); - - g_MasterServerManager->AddSelfToServerList( - Cvar_hostport->GetInt(), - Cvar_ns_player_auth_port->GetInt(), - (char*)Cvar_ns_server_name->GetString(), - (char*)Cvar_ns_server_desc->GetString(), - hostState->m_levelName, - (char*)GetCurrentPlaylistName(), - maxPlayers, - (char*)Cvar_ns_server_password->GetString()); - g_ServerAuthenticationManager->StartPlayerAuthServer(); - g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame = false; -} - -void CHostState__State_ChangeLevelMPHook(CHostState* hostState) -{ - int maxPlayers = 6; - char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false); - if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this - maxPlayers = std::stoi(maxPlayersVar); - - // net_data_block_enabled is required for sp, force it if we're on an sp map - // sucks for security but just how it be - if (!strncmp(g_pHostState->m_levelName, "sp_", 3)) - { - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "net_data_block_enabled 1", cmd_source_t::kCommandSrcCode); - Cbuf_Execute(); - } - - g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)GetCurrentPlaylistName(), maxPlayers); - CHostState__State_ChangeLevelMP(hostState); -} - -void CHostState__State_ChangeLevelSPHook(CHostState* hostState) -{ - // is this even called? genuinely i don't think so - // from what i can tell, it's not called on mp=>sp change or sp=>sp change - // so idk it's fucked - - int maxPlayers = 6; - char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false); - if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this - maxPlayers = std::stoi(maxPlayersVar); - - g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)GetCurrentPlaylistName(), maxPlayers); - CHostState__State_ChangeLevelSP(hostState); -} - -void CHostState__State_GameShutdownHook(CHostState* hostState) -{ - g_MasterServerManager->RemoveSelfFromServerList(); - g_ServerAuthenticationManager->StopPlayerAuthServer(); - - CHostState__State_GameShutdown(hostState); -} - -MasterServerManager::MasterServerManager() : m_pendingConnectionInfo {}, m_ownServerId {""}, m_ownClientAuthToken {""} {} - -void InitialiseSharedMasterServer(HMODULE baseAddress) -{ - Cvar_ns_masterserver_hostname = new ConVar("ns_masterserver_hostname", "127.0.0.1", FCVAR_NONE, ""); - // unfortunately lib doesn't let us specify a port and still have https work - // Cvar_ns_masterserver_port = new ConVar("ns_masterserver_port", "8080", FCVAR_NONE, ""); - - Cvar_ns_server_name = new ConVar("ns_server_name", "Unnamed Northstar Server", FCVAR_GAMEDLL, ""); - Cvar_ns_server_desc = new ConVar("ns_server_desc", "Default server description", FCVAR_GAMEDLL, ""); - Cvar_ns_server_password = new ConVar("ns_server_password", "", FCVAR_GAMEDLL, ""); - Cvar_ns_report_server_to_masterserver = new ConVar("ns_report_server_to_masterserver", "1", FCVAR_GAMEDLL, ""); - Cvar_ns_report_sp_server_to_masterserver = new ConVar("ns_report_sp_server_to_masterserver", "0", FCVAR_GAMEDLL, ""); - - Cvar_ns_curl_log_enable = new ConVar("ns_curl_log_enable", "0", FCVAR_NONE, ""); - - Cvar_hostname = *(ConVar**)((char*)baseAddress + 0x1315bae8); - - g_MasterServerManager = new MasterServerManager; - - RegisterConCommand("ns_fetchservers", ConCommand_ns_fetchservers, "", FCVAR_CLIENTDLL); - - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x16E7D0, CHostState__State_NewGameHook, reinterpret_cast<LPVOID*>(&CHostState__State_NewGame)); - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x16E520, - CHostState__State_ChangeLevelMPHook, - reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelMP)); - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x16E5D0, - CHostState__State_ChangeLevelSPHook, - reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelSP)); - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x16E640, - CHostState__State_GameShutdownHook, - reinterpret_cast<LPVOID*>(&CHostState__State_GameShutdown)); -} diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h deleted file mode 100644 index 10f91356..00000000 --- a/NorthstarDedicatedTest/masterserver.h +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once -#include "convar.h" -#include <WinSock2.h> -#include <string> -#include <cstring> -struct RemoteModInfo -{ - public: - std::string Name; - std::string Version; -}; - -class RemoteServerInfo -{ - public: - char id[33]; // 32 bytes + nullterminator - - // server info - char name[64]; - std::string description; - char map[32]; - char playlist[16]; - std::vector<RemoteModInfo> requiredMods; - - int playerCount; - int maxPlayers; - - // connection stuff - bool requiresPassword; - - public: - RemoteServerInfo( - const char* newId, - const char* newName, - const char* newDescription, - const char* newMap, - const char* newPlaylist, - int newPlayerCount, - int newMaxPlayers, - bool newRequiresPassword); -}; - -struct RemoteServerConnectionInfo -{ - public: - char authToken[32]; - - in_addr ip; - unsigned short port; -}; - -struct MainMenuPromoData -{ - public: - std::string newInfoTitle1; - std::string newInfoTitle2; - std::string newInfoTitle3; - - std::string largeButtonTitle; - std::string largeButtonText; - std::string largeButtonUrl; - int largeButtonImageIndex; - - std::string smallButton1Title; - std::string smallButton1Url; - int smallButton1ImageIndex; - - std::string smallButton2Title; - std::string smallButton2Url; - int smallButton2ImageIndex; -}; - -class MasterServerManager -{ - private: - bool m_requestingServerList = false; - bool m_authenticatingWithGameServer = false; - - public: - char m_ownServerId[33]; - char m_ownServerAuthToken[33]; - char m_ownClientAuthToken[33]; - - std::string m_ownModInfoJson; - std::string ns_auth_srvName; // Unicode unescaped version of Cvar_ns_auth_servername for support in cjk characters - std::string ns_auth_srvDesc; // Unicode unescaped version of Cvar_ns_auth_serverdesc for support in cjk characters - - bool m_bOriginAuthWithMasterServerDone = false; - bool m_bOriginAuthWithMasterServerInProgress = false; - - bool m_bRequireClientAuth = false; - bool m_savingPersistentData = false; - - bool m_scriptRequestingServerList = false; - bool m_successfullyConnected = true; - - bool m_bNewgameAfterSelfAuth = false; - bool m_scriptAuthenticatingWithGameServer = false; - bool m_successfullyAuthenticatedWithGameServer = false; - - bool m_hasPendingConnectionInfo = false; - RemoteServerConnectionInfo m_pendingConnectionInfo; - - std::vector<RemoteServerInfo> m_remoteServers; - - bool m_bHasMainMenuPromoData = false; - MainMenuPromoData m_MainMenuPromoData; - - private: - void SetCommonHttpClientOptions(CURL* curl); - - public: - MasterServerManager(); - void ClearServerList(); - void RequestServerList(); - void RequestMainMenuPromos(); - void AuthenticateOriginWithMasterServer(char* uid, char* originToken); - void AuthenticateWithOwnServer(char* uid, char* playerToken); - void AuthenticateWithServer(char* uid, char* playerToken, char* serverId, char* password); - void - AddSelfToServerList(int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password); - void UpdateServerMapAndPlaylist(char* map, char* playlist, int playerCount); - void UpdateServerPlayerCount(int playerCount); - void WritePlayerPersistentData(char* playerId, char* pdata, size_t pdataSize); - void RemoveSelfFromServerList(); -}; -std::string unescape_unicode(const std::string& str); -void UpdateServerInfoFromUnicodeToUTF8(); -void InitialiseSharedMasterServer(HMODULE baseAddress); - -extern MasterServerManager* g_MasterServerManager; -extern ConVar* Cvar_ns_masterserver_hostname; -extern ConVar* Cvar_ns_server_password;
\ No newline at end of file diff --git a/NorthstarDedicatedTest/maxplayers.cpp b/NorthstarDedicatedTest/maxplayers.cpp deleted file mode 100644 index 32f3b2ec..00000000 --- a/NorthstarDedicatedTest/maxplayers.cpp +++ /dev/null @@ -1,682 +0,0 @@ -#include "pch.h" -#include "maxplayers.h" -#include "gameutils.h" - -// never set this to anything below 32 -#define NEW_MAX_PLAYERS 64 -// dg note: the theoretical limit is actually 100, 76 works without entity issues, and 64 works without clientside prediction issues. - -#define PAD_NUMBER(number, boundary) (((number) + ((boundary)-1)) / (boundary)) * (boundary) - -// this is horrible -constexpr int PlayerResource_Name_Start = 0; // Start of modded allocated space. -constexpr int PlayerResource_Name_Size = ((NEW_MAX_PLAYERS + 1) * 8); // const char* m_szName[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_Ping_Start = PlayerResource_Name_Start + PlayerResource_Name_Size; -constexpr int PlayerResource_Ping_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPing[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_Team_Start = PlayerResource_Ping_Start + PlayerResource_Ping_Size; -constexpr int PlayerResource_Team_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iTeam[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_PRHealth_Start = PlayerResource_Team_Start + PlayerResource_Team_Size; -constexpr int PlayerResource_PRHealth_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPRHealth[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_Connected_Start = PlayerResource_PRHealth_Start + PlayerResource_PRHealth_Size; -constexpr int PlayerResource_Connected_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bConnected[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_Alive_Start = PlayerResource_Connected_Start + PlayerResource_Connected_Size; -constexpr int PlayerResource_Alive_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bAlive[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_BoolStats_Start = PlayerResource_Alive_Start + PlayerResource_Alive_Size; -constexpr int PlayerResource_BoolStats_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool idk) m_boolStats[MAX_PLAYERS + 1]; - -constexpr int PlayerResource_KillStats_Start = PlayerResource_BoolStats_Start + PlayerResource_BoolStats_Size; -constexpr int PlayerResource_KillStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 6, 4); -constexpr int PlayerResource_KillStats_Size = (PlayerResource_KillStats_Length * 6); // int m_killStats[MAX_PLAYERS + 1][6]; - -constexpr int PlayerResource_ScoreStats_Start = PlayerResource_KillStats_Start + PlayerResource_KillStats_Size; -constexpr int PlayerResource_ScoreStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 5, 4); -constexpr int PlayerResource_ScoreStats_Size = (PlayerResource_ScoreStats_Length * 4); // int m_scoreStats[MAX_PLAYERS + 1][5]; - -// must be the usage of the last field to account for any possible paddings -constexpr int PlayerResource_TotalSize = PlayerResource_ScoreStats_Start + PlayerResource_ScoreStats_Size; - -constexpr int Team_PlayerArray_AddedLength = NEW_MAX_PLAYERS - 32; -constexpr int Team_PlayerArray_AddedSize = PAD_NUMBER(Team_PlayerArray_AddedLength * 8, 4); -constexpr int Team_AddedSize = Team_PlayerArray_AddedSize; - -#include "NSMem.h" -template <class T> void ChangeOffset(void* addr, unsigned int offset) -{ - NSMem::BytePatch((uintptr_t)addr, (BYTE*)&offset, sizeof(T)); -} - -/* -typedef bool(*MatchRecvPropsToSendProps_R_Type)(__int64 lookup, __int64 tableNameBroken, __int64 sendTable, __int64 recvTable); -MatchRecvPropsToSendProps_R_Type MatchRecvPropsToSendProps_R_Original; - -bool MatchRecvPropsToSendProps_R_Hook(__int64 lookup, __int64 tableNameBroken, __int64 sendTable, __int64 recvTable) -{ - const char* tableName = *(const char**)(sendTable + 0x118); - - spdlog::info("MatchRecvPropsToSendProps_R table name {}", tableName); - - bool orig = MatchRecvPropsToSendProps_R_Original(lookup, tableNameBroken, sendTable, recvTable); - return orig; -} - -typedef bool(*DataTable_SetupReceiveTableFromSendTable_Type)(__int64 sendTable, bool needsDecoder); -DataTable_SetupReceiveTableFromSendTable_Type DataTable_SetupReceiveTableFromSendTable_Original; - -bool DataTable_SetupReceiveTableFromSendTable_Hook(__int64 sendTable, bool needsDecoder) -{ - const char* tableName = *(const char**)(sendTable + 0x118); - - spdlog::info("DataTable_SetupReceiveTableFromSendTable table name {}", tableName); - if (!strcmp(tableName, "m_bConnected")) { - char f[64]; - sprintf_s(f, "%p", sendTable); - MessageBoxA(0, f, "DataTable_SetupReceiveTableFromSendTable", 0); - } - - return DataTable_SetupReceiveTableFromSendTable_Original(sendTable, needsDecoder); -} -*/ - -typedef void* (*StringTables_CreateStringTable_Type)( - __int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags); -StringTables_CreateStringTable_Type StringTables_CreateStringTable_Original; - -void* StringTables_CreateStringTable_Hook( - __int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags) -{ - // Change the amount of entries to account for a bigger player amount - if (!strcmp(name, "userinfo")) - { - int maxPlayersPowerOf2 = 1; - while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS) - maxPlayersPowerOf2 <<= 1; - - maxentries = maxPlayersPowerOf2; - } - - return StringTables_CreateStringTable_Original(thisptr, name, maxentries, userdatafixedsize, userdatanetworkbits, flags); -} - -bool MaxPlayersIncreaseEnabled() -{ - return CommandLine() && CommandLine()->CheckParm("-experimentalmaxplayersincrease"); -} - -void InitialiseMaxPlayersOverride_Engine(HMODULE baseAddress) -{ - if (!MaxPlayersIncreaseEnabled()) - return; - - // patch GetPlayerLimits to ignore the boundary limit - ChangeOffset<unsigned char>((char*)baseAddress + 0x116458, 0xEB); // jle => jmp - - // patch ED_Alloc to change nFirstIndex - ChangeOffset<int>((char*)baseAddress + 0x18F46C + 1, NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1) - - // patch CGameServer::SpawnServer to change GetMaxClients inline - ChangeOffset<int>((char*)baseAddress + 0x119543 + 2, NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1) - - // patch CGameServer::SpawnServer to change for loop - ChangeOffset<unsigned char>((char*)baseAddress + 0x11957F + 2, NEW_MAX_PLAYERS); // original: 32 - - // patch CGameServer::SpawnServer to change for loop (there are two) - ChangeOffset<unsigned char>((char*)baseAddress + 0x119586 + 2, NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1) - - // patch max players somewhere in CClientState - ChangeOffset<unsigned char>((char*)baseAddress + 0x1A162C + 2, NEW_MAX_PLAYERS - 1); // original: 31 (32 - 1) - - // patch max players in userinfo stringtable creation - /*{ - int maxPlayersPowerOf2 = 1; - while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS) - maxPlayersPowerOf2 <<= 1; - ChangeOffset<unsigned char>((char*)baseAddress + 0x114B79 + 3, maxPlayersPowerOf2); // original: 32 - }*/ - // this is not supposed to work at all but it does on 64 players (how) - // proper fix below - - // patch max players in userinfo stringtable creation loop - ChangeOffset<unsigned char>((char*)baseAddress + 0x114C48 + 2, NEW_MAX_PLAYERS); // original: 32 - - // do not load prebaked SendTable message list - ChangeOffset<unsigned char>((char*)baseAddress + 0x75859, 0xEB); // jnz -> jmp - - HookEnabler hook; - - // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x209000, &MatchRecvPropsToSendProps_R_Hook, - // reinterpret_cast<LPVOID*>(&MatchRecvPropsToSendProps_R_Original)); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FACD0, - // &DataTable_SetupReceiveTableFromSendTable_Hook, reinterpret_cast<LPVOID*>(&DataTable_SetupReceiveTableFromSendTable_Original)); - - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x22E220, - &StringTables_CreateStringTable_Hook, - reinterpret_cast<LPVOID*>(&StringTables_CreateStringTable_Original)); -} - -typedef void (*RunUserCmds_Type)(bool a1, float a2); -RunUserCmds_Type RunUserCmds_Original; - -HMODULE serverBase = 0; -auto RandomIntZeroMax = (__int64(__fastcall*)())0; - -// lazy rebuild -void RunUserCmds_Hook(bool a1, float a2) -{ - unsigned char v3; // bl - int v5; // er14 - int i; // edi - __int64 v7; // rax - DWORD* v8; // rbx - int v9; // edi - __int64* v10; // rsi - __int64 v11; // rax - int v12; // er12 - __int64 v13; // rdi - int v14; // ebx - int v15; // eax - __int64 v16; // r8 - int v17; // edx - char v18; // r15 - char v19; // bp - int v20; // esi - __int64* v21; // rdi - __int64 v22; // rcx - bool v23; // al - __int64 v24; // rax - __int64 v25[NEW_MAX_PLAYERS]; // [rsp+20h] [rbp-138h] BYREF - - uintptr_t base = (__int64)serverBase; - auto g_pGlobals = *(__int64*)(base + 0xBFBE08); - __int64 globals = g_pGlobals; - - auto g_pEngineServer = *(__int64*)(base + 0xBFBD98); - - auto qword_1814D9648 = *(__int64*)(base + 0x14D9648); - auto qword_1814DA408 = *(__int64*)(base + 0x14DA408); - auto qword_1812107E8 = *(__int64*)(base + 0x12107E8); - auto qword_1812105A8 = *(__int64*)(base + 0x12105A8); - - auto UTIL_PlayerByIndex = (__int64(__fastcall*)(int index))(base + 0x26AA10); - auto sub_180485590 = (void(__fastcall*)(__int64))(base + 0x485590); - auto sub_18058CD80 = (void(__fastcall*)(__int64))(base + 0x58CD80); - auto sub_1805A6D90 = (void(__fastcall*)(__int64))(base + 0x5A6D90); - auto sub_1805A6E50 = (bool(__fastcall*)(__int64, int, char))(base + 0x5A6E50); - auto sub_1805A6C20 = (void(__fastcall*)(__int64))(base + 0x5A6C20); - - v3 = *(unsigned char*)(g_pGlobals + 73); - if (*(DWORD*)(qword_1814D9648 + 92) && - ((*(unsigned __int8(__fastcall**)(__int64))(*(__int64*)g_pEngineServer + 32i64))(g_pEngineServer) || - !*(DWORD*)(qword_1814DA408 + 92)) && - v3) - { - globals = g_pGlobals; - v5 = 1; - for (i = 1; i <= *(DWORD*)(g_pGlobals + 52); ++i) - { - v7 = UTIL_PlayerByIndex(i); - v8 = (DWORD*)v7; - if (v7) - { - *(__int64*)(base + 0x1210420) = v7; - *(float*)(g_pGlobals + 16) = a2; - if (!a1) - sub_18058CD80(v7); - sub_1805A6D90((__int64)v8); - } - globals = g_pGlobals; - } - memset(v25, 0, sizeof(v25)); - v9 = 0; - if (*(int*)(globals + 52) > 0) - { - v10 = v25; - do - { - v11 = UTIL_PlayerByIndex(++v9); - globals = g_pGlobals; - *v10++ = v11; - } while (v9 < *(DWORD*)(globals + 52)); - } - v12 = *(DWORD*)(qword_1812107E8 + 92); - if (*(DWORD*)(qword_1812105A8 + 92)) - { - v13 = *(DWORD*)(globals + 52) - 1; - if (v13 >= 1) - { - v14 = *(DWORD*)(globals + 52); - do - { - v15 = RandomIntZeroMax(); - v16 = v25[v13--]; - v17 = v15 % v14--; - v25[v13 + 1] = v25[v17]; - v25[v17] = v16; - } while (v13 >= 1); - globals = g_pGlobals; - } - } - v18 = 1; - do - { - v19 = 0; - v20 = 0; - if (*(int*)(globals + 52) > 0) - { - v21 = v25; - do - { - v22 = *v21; - if (*v21) - { - *(__int64*)(base + 0x1210420) = *v21; - *(float*)(globals + 16) = a2; - v23 = sub_1805A6E50(v22, v12, v18); - globals = g_pGlobals; - if (v23) - v19 = 1; - else - *v21 = 0i64; - } - ++v20; - ++v21; - } while (v20 < *(DWORD*)(globals + 52)); - } - v18 = 0; - } while (v19); - if (*(int*)(globals + 52) >= 1) - { - do - { - v24 = UTIL_PlayerByIndex(v5); - if (v24) - { - *(__int64*)(base + 0x1210420) = v24; - *(float*)(g_pGlobals + 16) = a2; - sub_1805A6C20(v24); - } - ++v5; - } while (v5 <= *(DWORD*)(g_pGlobals + 52)); - } - sub_180485590(*(__int64*)(base + 0xB7B2D8)); - } -} - -typedef __int64 (*SendPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1); -SendPropArray2_Type SendPropArray2_Original; - -__int64 __fastcall SendPropArray2_Hook(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1) -{ - // Change the amount of elements to account for a bigger player amount - if (!strcmp(name, "\"player_array\"")) - elements = NEW_MAX_PLAYERS; - - return SendPropArray2_Original(recvProp, elements, flags, name, proxyFn, unk1); -} - -void InitialiseMaxPlayersOverride_Server(HMODULE baseAddress) -{ - if (!MaxPlayersIncreaseEnabled()) - return; - - // get required data - serverBase = GetModuleHandleA("server.dll"); - RandomIntZeroMax = (decltype(RandomIntZeroMax))(GetProcAddress(GetModuleHandleA("vstdlib.dll"), "RandomIntZeroMax")); - - // patch max players amount - ChangeOffset<unsigned char>((char*)baseAddress + 0x9A44D + 3, NEW_MAX_PLAYERS); // 0x20 (32) => 0x80 (128) - - // patch SpawnGlobalNonRewinding to change forced edict index - ChangeOffset<unsigned char>((char*)baseAddress + 0x2BC403 + 2, NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1) - - constexpr int CPlayerResource_OriginalSize = 4776; - constexpr int CPlayerResource_AddedSize = PlayerResource_TotalSize; - constexpr int CPlayerResource_ModifiedSize = CPlayerResource_OriginalSize + CPlayerResource_AddedSize; - - // CPlayerResource class allocation function - allocate a bigger amount to fit all new max player data - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C560A + 1, CPlayerResource_ModifiedSize); - - // DT_PlayerResource::m_iPing SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5059 + 2, CPlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C50A8 + 2, CPlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C50E2 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_iPing DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB94598, CPlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB9459C, NEW_MAX_PLAYERS + 1); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB945C0, PlayerResource_Ping_Size); - - // DT_PlayerResource::m_iTeam SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5110 + 2, CPlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C519C + 2, CPlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C517E + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_iTeam DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB94600, CPlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94604, NEW_MAX_PLAYERS + 1); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94628, PlayerResource_Team_Size); - - // DT_PlayerResource::m_iPRHealth SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C51C0 + 2, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5204 + 2, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C523E + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_iPRHealth DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB94668, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB9466C, NEW_MAX_PLAYERS + 1); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94690, PlayerResource_PRHealth_Size); - - // DT_PlayerResource::m_bConnected SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C526C + 2, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C52B4 + 2, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C52EE + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_bConnected DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB946D0, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB946D4, NEW_MAX_PLAYERS + 1); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB946F8, PlayerResource_Connected_Size); - - // DT_PlayerResource::m_bAlive SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5321 + 2, CPlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5364 + 2, CPlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C539E + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_bAlive DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB94738, CPlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB9473C, NEW_MAX_PLAYERS + 1); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94760, PlayerResource_Alive_Size); - - // DT_PlayerResource::m_boolStats SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C53CC + 2, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5414 + 2, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C544E + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_boolStats DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB947A0, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB947A4, NEW_MAX_PLAYERS + 1); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB947C8, PlayerResource_BoolStats_Size); - - // DT_PlayerResource::m_killStats SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C547C + 2, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C54E2 + 2, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C54FE + 4, PlayerResource_KillStats_Length); - - // DT_PlayerResource::m_killStats DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB94808, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB9480C, PlayerResource_KillStats_Length); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94830, PlayerResource_KillStats_Size); - - // DT_PlayerResource::m_scoreStats SendProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5528 + 2, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5576 + 2, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5584 + 4, PlayerResource_ScoreStats_Length); - - // DT_PlayerResource::m_scoreStats DataMap - ChangeOffset<unsigned int>((char*)baseAddress + 0xB94870, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94874, PlayerResource_ScoreStats_Length); - ChangeOffset<unsigned short>((char*)baseAddress + 0xB94898, PlayerResource_ScoreStats_Size); - - // CPlayerResource::UpdatePlayerData - m_bConnected - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C66EE + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C672E + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - - // CPlayerResource::UpdatePlayerData - m_iPing - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6394 + 4, CPlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C63DB + 4, CPlayerResource_OriginalSize + PlayerResource_Ping_Start); - - // CPlayerResource::UpdatePlayerData - m_iTeam - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C63FD + 4, CPlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6442 + 4, CPlayerResource_OriginalSize + PlayerResource_Team_Start); - - // CPlayerResource::UpdatePlayerData - m_iPRHealth - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C645B + 4, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64A0 + 4, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - - // CPlayerResource::UpdatePlayerData - m_bConnected - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64AA + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64F0 + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start); - - // CPlayerResource::UpdatePlayerData - m_bAlive - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C650A + 4, CPlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C654F + 4, CPlayerResource_OriginalSize + PlayerResource_Alive_Start); - - // CPlayerResource::UpdatePlayerData - m_boolStats - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6557 + 4, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65A5 + 4, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - - // CPlayerResource::UpdatePlayerData - m_scoreStats - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65C2 + 3, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65E3 + 4, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - - // CPlayerResource::UpdatePlayerData - m_killStats - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6654 + 3, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x5C665B + 3, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start); - - // GameLoop::RunUserCmds - rebuild - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x483D10, &RunUserCmds_Hook, reinterpret_cast<LPVOID*>(&RunUserCmds_Original)); - - *(DWORD*)((char*)baseAddress + 0x14E7390) = 0; - auto DT_PlayerResource_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x5C4FE0); - DT_PlayerResource_Construct(); - - constexpr int CTeam_OriginalSize = 3336; - constexpr int CTeam_AddedSize = Team_AddedSize; - constexpr int CTeam_ModifiedSize = CTeam_OriginalSize + CTeam_AddedSize; - - // CTeam class allocation function - allocate a bigger amount to fit all new team player data - ChangeOffset<unsigned int>((char*)baseAddress + 0x23924A + 1, CTeam_ModifiedSize); - - // CTeam::CTeam - increase memset length to clean newly allocated data - ChangeOffset<unsigned int>((char*)baseAddress + 0x2395AE + 2, 256 + CTeam_AddedSize); - - // hook required to change the size of DT_Team::"player_array" - HookEnabler hook2; - ENABLER_CREATEHOOK(hook2, (char*)baseAddress + 0x12B130, &SendPropArray2_Hook, reinterpret_cast<LPVOID*>(&SendPropArray2_Original)); - hook2.~HookEnabler(); // force hook before calling construct function - - *(DWORD*)((char*)baseAddress + 0xC945A0) = 0; - auto DT_Team_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x238F50); - DT_Team_Construct(); -} - -typedef __int64 (*RecvPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn); -RecvPropArray2_Type RecvPropArray2_Original; - -__int64 __fastcall RecvPropArray2_Hook(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn) -{ - // Change the amount of elements to account for a bigger player amount - if (!strcmp(name, "\"player_array\"")) - elements = NEW_MAX_PLAYERS; - - return RecvPropArray2_Original(recvProp, elements, flags, name, proxyFn); -} - -void InitialiseMaxPlayersOverride_Client(HMODULE baseAddress) -{ - if (!MaxPlayersIncreaseEnabled()) - return; - - constexpr int C_PlayerResource_OriginalSize = 5768; - constexpr int C_PlayerResource_AddedSize = PlayerResource_TotalSize; - constexpr int C_PlayerResource_ModifiedSize = C_PlayerResource_OriginalSize + C_PlayerResource_AddedSize; - - // C_PlayerResource class allocation function - allocate a bigger amount to fit all new max player data - ChangeOffset<unsigned int>((char*)baseAddress + 0x164C41 + 1, C_PlayerResource_ModifiedSize); - - // C_PlayerResource::C_PlayerResource - change loop end value - ChangeOffset<unsigned char>((char*)baseAddress + 0x1640C4 + 2, NEW_MAX_PLAYERS - 32); - - // C_PlayerResource::C_PlayerResource - change m_szName address - ChangeOffset<unsigned int>( - (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class - - // C_PlayerResource::C_PlayerResource - change m_szName address - ChangeOffset<unsigned int>( - (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class - - // C_PlayerResource::C_PlayerResource - increase memset length to clean newly allocated data - ChangeOffset<unsigned int>((char*)baseAddress + 0x1640D0 + 3, 2244 + C_PlayerResource_AddedSize); - - // C_PlayerResource::UpdatePlayerName - change m_szName address - ChangeOffset<unsigned int>((char*)baseAddress + 0x16431F + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName - change m_szName address 1 - ChangeOffset<unsigned int>((char*)baseAddress + 0x1645B1 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName - change m_szName address 2 - ChangeOffset<unsigned int>((char*)baseAddress + 0x1645C0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName - change m_szName address 3 - ChangeOffset<unsigned int>((char*)baseAddress + 0x1645DD + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName internal func - change m_szName address 1 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164B71 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName internal func - change m_szName address 2 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164B9B + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 1 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164641 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 2 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164650 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 3 - ChangeOffset<unsigned int>((char*)baseAddress + 0x16466D + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 1 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164BA3 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 2 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164BCE + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 3 - ChangeOffset<unsigned int>((char*)baseAddress + 0x164BE7 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - - // C_PlayerResource::m_szName - ChangeOffset<unsigned int>((char*)baseAddress + 0xc350f8, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc350f8 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource size - ChangeOffset<unsigned int>((char*)baseAddress + 0x163415 + 6, C_PlayerResource_ModifiedSize); - - // DT_PlayerResource::m_iPing RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x163492 + 2, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1634D6 + 2, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163515 + 5, NEW_MAX_PLAYERS + 1); - - // C_PlayerResource::m_iPing - ChangeOffset<unsigned int>((char*)baseAddress + 0xc35170, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc35170 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_iTeam RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x163549 + 2, C_PlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1635C8 + 2, C_PlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1635AD + 5, NEW_MAX_PLAYERS + 1); - - // C_PlayerResource::m_iTeam - ChangeOffset<unsigned int>((char*)baseAddress + 0xc351e8, C_PlayerResource_OriginalSize + PlayerResource_Team_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc351e8 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_iPRHealth RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x1635F9 + 2, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163625 + 2, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163675 + 5, NEW_MAX_PLAYERS + 1); - - // C_PlayerResource::m_iPRHealth - ChangeOffset<unsigned int>((char*)baseAddress + 0xc35260, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc35260 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_bConnected RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x1636A9 + 2, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1636D5 + 2, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163725 + 5, NEW_MAX_PLAYERS + 1); - - // C_PlayerResource::m_bConnected - ChangeOffset<unsigned int>((char*)baseAddress + 0xc352d8, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc352d8 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_bAlive RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x163759 + 2, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163785 + 2, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1637D5 + 5, NEW_MAX_PLAYERS + 1); - - // C_PlayerResource::m_bAlive - ChangeOffset<unsigned int>((char*)baseAddress + 0xc35350, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc35350 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_boolStats RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x163809 + 2, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163835 + 2, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163885 + 5, NEW_MAX_PLAYERS + 1); - - // C_PlayerResource::m_boolStats - ChangeOffset<unsigned int>((char*)baseAddress + 0xc353c8, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc353c8 + 4, NEW_MAX_PLAYERS + 1); - - // DT_PlayerResource::m_killStats RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x1638B3 + 2, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1638E5 + 2, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163935 + 5, PlayerResource_KillStats_Length); - - // C_PlayerResource::m_killStats - ChangeOffset<unsigned int>((char*)baseAddress + 0xc35440, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc35440 + 4, PlayerResource_KillStats_Length); - - // DT_PlayerResource::m_scoreStats RecvProp - ChangeOffset<unsigned int>((char*)baseAddress + 0x163969 + 2, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x163995 + 2, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned int>((char*)baseAddress + 0x1639E5 + 5, PlayerResource_ScoreStats_Length); - - // C_PlayerResource::m_scoreStats - ChangeOffset<unsigned int>((char*)baseAddress + 0xc354b8, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start); - ChangeOffset<unsigned short>((char*)baseAddress + 0xc354b8 + 4, PlayerResource_ScoreStats_Length); - - // C_PlayerResource::GetPlayerName - change m_bConnected address - ChangeOffset<unsigned int>((char*)baseAddress + 0x164599 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - - // C_PlayerResource::GetPlayerName2 (?) - change m_bConnected address - ChangeOffset<unsigned int>((char*)baseAddress + 0x164629 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - - // C_PlayerResource::GetPlayerName internal func - change m_bConnected address - ChangeOffset<unsigned int>((char*)baseAddress + 0x164B13 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - - // Some other get name func (that seems to be unused) - change m_bConnected address - ChangeOffset<unsigned int>((char*)baseAddress + 0x164860 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - - // Some other get name func 2 (that seems to be unused too) - change m_bConnected address - ChangeOffset<unsigned int>((char*)baseAddress + 0x164834 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start); - - *(DWORD*)((char*)baseAddress + 0xC35068) = 0; - auto DT_PlayerResource_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x163400); - DT_PlayerResource_Construct(); - - constexpr int C_Team_OriginalSize = 3200; - constexpr int C_Team_AddedSize = Team_AddedSize; - constexpr int C_Team_ModifiedSize = C_Team_OriginalSize + C_Team_AddedSize; - - // C_Team class allocation function - allocate a bigger amount to fit all new team player data - ChangeOffset<unsigned int>((char*)baseAddress + 0x182321 + 1, C_Team_ModifiedSize); - - // C_Team::C_Team - increase memset length to clean newly allocated data - ChangeOffset<unsigned int>((char*)baseAddress + 0x1804A2 + 2, 256 + C_Team_AddedSize); - - // DT_Team size - ChangeOffset<unsigned int>((char*)baseAddress + 0xC3AA0C, C_Team_ModifiedSize); - - // hook required to change the size of DT_Team::"player_array" - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1CEDA0, &RecvPropArray2_Hook, reinterpret_cast<LPVOID*>(&RecvPropArray2_Original)); - hook.~HookEnabler(); // force hook before calling construct function - - *(DWORD*)((char*)baseAddress + 0xC3AFF8) = 0; - auto DT_Team_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x17F950); - DT_Team_Construct(); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/maxplayers.h b/NorthstarDedicatedTest/maxplayers.h deleted file mode 100644 index cd191fc8..00000000 --- a/NorthstarDedicatedTest/maxplayers.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -void InitialiseMaxPlayersOverride_Engine(HMODULE baseAddress); -void InitialiseMaxPlayersOverride_Server(HMODULE baseAddress); -void InitialiseMaxPlayersOverride_Client(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscclientfixes.cpp b/NorthstarDedicatedTest/miscclientfixes.cpp deleted file mode 100644 index 62ffd4a4..00000000 --- a/NorthstarDedicatedTest/miscclientfixes.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "pch.h" -#include "miscclientfixes.h" -#include "hookutils.h" -#include "dedicated.h" - -typedef void* (*CrashingWeaponActivityFuncType)(void* a1); -CrashingWeaponActivityFuncType CrashingWeaponActivityFunc0; -CrashingWeaponActivityFuncType CrashingWeaponActivityFunc1; - -void* CrashingWeaponActivityFunc0Hook(void* a1) -{ - // this return is safe, other functions that use this value seemingly dont care about it being null - if (!a1) - return 0; - - return CrashingWeaponActivityFunc0(a1); -} - -void* CrashingWeaponActivityFunc1Hook(void* a1) -{ - // this return is safe, other functions that use this value seemingly dont care about it being null - if (!a1) - return 0; - - return CrashingWeaponActivityFunc1(a1); -} - -void InitialiseMiscClientFixes(HMODULE baseAddress) -{ - if (IsDedicated()) - return; - - HookEnabler hook; - - // these functions will occasionally pass a null pointer on respawn, unsure what causes this but seems easiest just to return null if - // null, which seems to work fine fucking sucks this has to be fixed like this but unsure what exactly causes this serverside, breaks - // vanilla compatibility to a degree tho will say i have about 0 clue what exactly these functions do, testing this it doesn't even seem - // like they do much of anything i can see tbh - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x5A92D0, &CrashingWeaponActivityFunc0Hook, reinterpret_cast<LPVOID*>(&CrashingWeaponActivityFunc0)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x5A9310, &CrashingWeaponActivityFunc1Hook, reinterpret_cast<LPVOID*>(&CrashingWeaponActivityFunc1)); - - // experimental: allow cl_extrapolate to be enabled without cheats - { - void* ptr = (char*)baseAddress + 0x275F9D9; - *((char*)ptr) = (char)0; - } -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscclientfixes.h b/NorthstarDedicatedTest/miscclientfixes.h deleted file mode 100644 index 1f0ad807..00000000 --- a/NorthstarDedicatedTest/miscclientfixes.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void InitialiseMiscClientFixes(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/misccommands.cpp b/NorthstarDedicatedTest/misccommands.cpp deleted file mode 100644 index df2f4a3d..00000000 --- a/NorthstarDedicatedTest/misccommands.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "pch.h" -#include "misccommands.h" -#include "concommand.h" -#include "gameutils.h" -#include "masterserver.h" -#include "serverauthentication.h" -#include "squirrel.h" - -void AddMiscConCommands() -{ - MAKE_CONCMD( - "force_newgame", - "forces a map load through directly setting g_pHostState->m_iNextState to HS_NEW_GAME", - FCVAR_NONE, - [](const CCommand& arg) - { - if (arg.ArgC() < 2) - return; - - g_pHostState->m_iNextState = HS_NEW_GAME; - strncpy(g_pHostState->m_levelName, arg.Arg(1), sizeof(g_pHostState->m_levelName)); - }); - - MAKE_CONCMD( - "ns_start_reauth_and_leave_to_lobby", - "called by the server, used to reauth and return the player to lobby when leaving a game", - FCVAR_SERVER_CAN_EXECUTE, - [](const CCommand& arg) - { - // hack for special case where we're on a local server, so we erase our own newly created auth data on disconnect - g_MasterServerManager->m_bNewgameAfterSelfAuth = true; - g_MasterServerManager->AuthenticateWithOwnServer(g_LocalPlayerUserID, g_MasterServerManager->m_ownClientAuthToken); - }); - - // this is a concommand because we make a deferred call to it from another thread - MAKE_CONCMD( - "ns_end_reauth_and_leave_to_lobby", - "", - FCVAR_NONE, - [](const CCommand& arg) - { - Cbuf_AddText( - Cbuf_GetCurrentPlayer(), - fmt::format("serverfilter {}", g_ServerAuthenticationManager->m_authData.begin()->first).c_str(), - cmd_source_t::kCommandSrcCode); - Cbuf_Execute(); - - // weird way of checking, but check if client script vm is initialised, mainly just to allow players to cancel this - if (g_ClientSquirrelManager->sqvm) - { - g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame = true; - - // this won't set playlist correctly on remote clients, don't think they can set playlist until they've left which sorta - // fucks things should maybe set this in HostState_NewGame? - SetCurrentPlaylist("tdm"); - strcpy(g_pHostState->m_levelName, "mp_lobby"); - g_pHostState->m_iNextState = HS_NEW_GAME; - } - }); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/misccommands.h b/NorthstarDedicatedTest/misccommands.h deleted file mode 100644 index cbd1df65..00000000 --- a/NorthstarDedicatedTest/misccommands.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void AddMiscConCommands();
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscserverfixes.cpp b/NorthstarDedicatedTest/miscserverfixes.cpp deleted file mode 100644 index 30cd5777..00000000 --- a/NorthstarDedicatedTest/miscserverfixes.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "pch.h" -#include "miscserverfixes.h" -#include "hookutils.h" - -#include "NSMem.h" - -void InitialiseMiscServerFixes(HMODULE baseAddress) -{ - uintptr_t ba = (uintptr_t)baseAddress; - - // ret at the start of the concommand GenerateObjFile as it can crash servers - { - NSMem::BytePatch(ba + 0x38D920, "C3"); - } - - // nop out call to VGUI shutdown since it crashes the game when quitting from the console - { - NSMem::NOP(ba + 0x154A96, 5); - } - - // ret at the start of CServerGameClients::ClientCommandKeyValues as it has no benefit and is forwarded to client (i.e. security issue) - // this prevents the attack vector of client=>server=>client, however server=>client also has clientside patches - { - NSMem::BytePatch(ba + 0x153920, "C3"); - } -} - -void InitialiseMiscEngineServerFixes(HMODULE baseAddress) {}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscserverfixes.h b/NorthstarDedicatedTest/miscserverfixes.h deleted file mode 100644 index d1c05a6b..00000000 --- a/NorthstarDedicatedTest/miscserverfixes.h +++ /dev/null @@ -1 +0,0 @@ -void InitialiseMiscServerFixes(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscserverscript.cpp b/NorthstarDedicatedTest/miscserverscript.cpp deleted file mode 100644 index b2bf52ec..00000000 --- a/NorthstarDedicatedTest/miscserverscript.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "pch.h" -#include "miscserverscript.h" -#include "squirrel.h" -#include "masterserver.h" -#include "serverauthentication.h" -#include "gameutils.h" - -// annoying helper function because i can't figure out getting players or entities from sqvm rn -// wish i didn't have to do it like this, but here we are -void* GetPlayerByIndex(int playerIndex) -{ - const int PLAYER_ARRAY_OFFSET = 0x12A53F90; - const int PLAYER_SIZE = 0x2D728; - - void* playerArrayBase = (char*)GetModuleHandleA("engine.dll") + PLAYER_ARRAY_OFFSET; - void* player = (char*)playerArrayBase + (playerIndex * PLAYER_SIZE); - - return player; -} - -// void function NSEarlyWritePlayerIndexPersistenceForLeave( int playerIndex ) -SQRESULT SQ_EarlyWritePlayerIndexPersistenceForLeave(void* sqvm) -{ - int playerIndex = ServerSq_getinteger(sqvm, 1); - void* player = GetPlayerByIndex(playerIndex); - - if (!g_ServerAuthenticationManager->m_additionalPlayerData.count(player)) - { - ServerSq_pusherror(sqvm, fmt::format("Invalid playerindex {}", playerIndex).c_str()); - return SQRESULT_ERROR; - } - - g_ServerAuthenticationManager->m_additionalPlayerData[player].needPersistenceWriteOnLeave = false; - g_ServerAuthenticationManager->WritePersistentData(player); - return SQRESULT_NULL; -} - -// bool function NSIsWritingPlayerPersistence() -SQRESULT SQ_IsWritingPlayerPersistence(void* sqvm) -{ - ServerSq_pushbool(sqvm, g_MasterServerManager->m_savingPersistentData); - return SQRESULT_NOTNULL; -} - -// bool function NSIsPlayerIndexLocalPlayer( int playerIndex ) -SQRESULT SQ_IsPlayerIndexLocalPlayer(void* sqvm) -{ - int playerIndex = ServerSq_getinteger(sqvm, 1); - void* player = GetPlayerByIndex(playerIndex); - if (!g_ServerAuthenticationManager->m_additionalPlayerData.count(player)) - { - ServerSq_pusherror(sqvm, fmt::format("Invalid playerindex {}", playerIndex).c_str()); - return SQRESULT_ERROR; - } - - ServerSq_pushbool(sqvm, !strcmp(g_LocalPlayerUserID, (char*)player + 0xF500)); - return SQRESULT_NOTNULL; -} - -void InitialiseMiscServerScriptCommand(HMODULE baseAddress) -{ - g_ServerSquirrelManager->AddFuncRegistration( - "void", "NSEarlyWritePlayerIndexPersistenceForLeave", "int playerIndex", "", SQ_EarlyWritePlayerIndexPersistenceForLeave); - g_ServerSquirrelManager->AddFuncRegistration("bool", "NSIsWritingPlayerPersistence", "", "", SQ_IsWritingPlayerPersistence); - g_ServerSquirrelManager->AddFuncRegistration("bool", "NSIsPlayerIndexLocalPlayer", "int playerIndex", "", SQ_IsPlayerIndexLocalPlayer); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscserverscript.h b/NorthstarDedicatedTest/miscserverscript.h deleted file mode 100644 index 8197e502..00000000 --- a/NorthstarDedicatedTest/miscserverscript.h +++ /dev/null @@ -1,2 +0,0 @@ -void InitialiseMiscServerScriptCommand(HMODULE baseAddress); -void* GetPlayerByIndex(int playerIndex);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/modlocalisation.cpp b/NorthstarDedicatedTest/modlocalisation.cpp deleted file mode 100644 index a3c45e40..00000000 --- a/NorthstarDedicatedTest/modlocalisation.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "pch.h" -#include "modlocalisation.h" -#include "hookutils.h" -#include "modmanager.h" - -typedef bool (*AddLocalisationFileType)(void* g_pVguiLocalize, const char* path, const char* pathId, char unknown); -AddLocalisationFileType AddLocalisationFile; - -bool loadModLocalisationFiles = true; - -bool AddLocalisationFileHook(void* g_pVguiLocalize, const char* path, const char* pathId, char unknown) -{ - bool ret = AddLocalisationFile(g_pVguiLocalize, path, pathId, unknown); - - if (ret) - spdlog::info("Loaded localisation file {} successfully", path); - - if (!loadModLocalisationFiles) - return ret; - - loadModLocalisationFiles = false; - - for (Mod mod : g_ModManager->m_loadedMods) - if (mod.Enabled) - for (std::string& localisationFile : mod.LocalisationFiles) - AddLocalisationFile(g_pVguiLocalize, localisationFile.c_str(), pathId, unknown); - - loadModLocalisationFiles = true; - - return ret; -} - -void InitialiseModLocalisation(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x6D80, AddLocalisationFileHook, reinterpret_cast<LPVOID*>(&AddLocalisationFile)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/modlocalisation.h b/NorthstarDedicatedTest/modlocalisation.h deleted file mode 100644 index b7d9cd50..00000000 --- a/NorthstarDedicatedTest/modlocalisation.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseModLocalisation(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/playlist.cpp b/NorthstarDedicatedTest/playlist.cpp deleted file mode 100644 index fdb23893..00000000 --- a/NorthstarDedicatedTest/playlist.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "pch.h" -#include "playlist.h" -#include "concommand.h" -#include "convar.h" -#include "gameutils.h" -#include "hookutils.h" -#include "squirrel.h" - -typedef char (*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2); -Onclc_SetPlaylistVarOverrideType Onclc_SetPlaylistVarOverride; - -typedef int (*GetCurrentGamemodeMaxPlayersType)(); -GetCurrentGamemodeMaxPlayersType GetCurrentGamemodeMaxPlayers; - -// function type defined in gameutils.h -SetPlaylistVarOverrideType SetPlaylistVarOverrideOriginal; -GetCurrentPlaylistVarType GetCurrentPlaylistVarOriginal; - -ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride; - -void SetPlaylistCommand(const CCommand& args) -{ - if (args.ArgC() < 2) - return; - - SetCurrentPlaylist(args.Arg(1)); -} - -void SetPlaylistVarOverrideCommand(const CCommand& args) -{ - if (args.ArgC() < 3) - return; - - for (int i = 1; i < args.ArgC(); i += 2) - SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1)); -} - -char Onclc_SetPlaylistVarOverrideHook(void* a1, void* a2) -{ - // the private_match playlist is the only situation where there should be any legitimate sending of this netmessage - // todo: check mp_lobby here too - if (!Cvar_ns_use_clc_SetPlaylistVarOverride->GetBool() || strcmp(GetCurrentPlaylistName(), "private_match")) - return 1; - - return Onclc_SetPlaylistVarOverride(a1, a2); -} - -void SetPlaylistVarOverrideHook(const char* varName, const char* value) -{ - if (strlen(value) >= 64) - return; - - SetPlaylistVarOverrideOriginal(varName, value); -} - -char* GetCurrentPlaylistVarHook(const char* varName, bool useOverrides) -{ - if (!useOverrides && !strcmp(varName, "max_players")) - useOverrides = true; - - return GetCurrentPlaylistVarOriginal(varName, useOverrides); -} - -int GetCurrentGamemodeMaxPlayersHook() -{ - char* maxPlayersStr = GetCurrentPlaylistVar("max_players", 0); - if (!maxPlayersStr) - return GetCurrentGamemodeMaxPlayers(); - - int maxPlayers = atoi(maxPlayersStr); - return maxPlayers; -} - -#include "NSMem.h" -void InitialisePlaylistHooks(HMODULE baseAddress) -{ - RegisterConCommand("setplaylist", SetPlaylistCommand, "Sets the current playlist", FCVAR_NONE); - RegisterConCommand("setplaylistvaroverrides", SetPlaylistVarOverrideCommand, "sets a playlist var override", FCVAR_NONE); - // note: clc_SetPlaylistVarOverride is pretty insecure, since it allows for entirely arbitrary playlist var overrides to be sent to the - // server this is somewhat restricted on custom servers to prevent it being done outside of private matches, but ideally it should be - // disabled altogether, since the custom menus won't use it anyway this should only really be accepted if you want vanilla client - // compatibility - Cvar_ns_use_clc_SetPlaylistVarOverride = new ConVar( - "ns_use_clc_SetPlaylistVarOverride", "0", FCVAR_GAMEDLL, "Whether the server should accept clc_SetPlaylistVarOverride messages"); - - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x222180, &Onclc_SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&Onclc_SetPlaylistVarOverride)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x18ED00, &SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&SetPlaylistVarOverrideOriginal)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x18C680, &GetCurrentPlaylistVarHook, reinterpret_cast<LPVOID*>(&GetCurrentPlaylistVarOriginal)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x18C430, &GetCurrentGamemodeMaxPlayersHook, reinterpret_cast<LPVOID*>(&GetCurrentGamemodeMaxPlayers)); - - uintptr_t ba = (uintptr_t)baseAddress; - - // patch to prevent clc_SetPlaylistVarOverride from being able to crash servers if we reach max overrides due to a call to Error (why is - // this possible respawn, wtf) todo: add a warning for this - { - NSMem::BytePatch(ba + 0x18ED8D, "C3"); - } - - // patch to allow setplaylistvaroverride to be called before map init on dedicated and private match launched through the game - NSMem::NOP(ba + 0x18ED17, 6); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/playlist.h b/NorthstarDedicatedTest/playlist.h deleted file mode 100644 index bf827ff4..00000000 --- a/NorthstarDedicatedTest/playlist.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void InitialisePlaylistHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp deleted file mode 100644 index d52f9ef1..00000000 --- a/NorthstarDedicatedTest/rpakfilesystem.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include "pch.h" -#include "rpakfilesystem.h" -#include "hookutils.h" -#include "modmanager.h" -#include "dedicated.h" - -typedef void* (*LoadCommonPaksForMapType)(char* map); -LoadCommonPaksForMapType LoadCommonPaksForMap; - -typedef void* (*LoadPakSyncType)(const char* path, void* unknownSingleton, int flags); -typedef int (*LoadPakAsyncType)(const char* path, void* unknownSingleton, int flags, void* callback0, void* callback1); -typedef void* (*UnloadPakType)(int pakHandle, void* callback); -typedef void* (*ReadFullFileFromDiskType)(const char* requestedPath, void* a2); - -// there are more i'm just too lazy to add -struct PakLoadFuncs -{ - void* unk0[2]; - LoadPakSyncType LoadPakSync; - LoadPakAsyncType LoadPakAsync; - void* unk1[2]; - UnloadPakType UnloadPak; - void* unk2[17]; - ReadFullFileFromDiskType ReadFullFileFromDisk; -}; - -PakLoadFuncs* g_pakLoadApi; -void** pUnknownPakLoadSingleton; - -PakLoadManager* g_PakLoadManager; -void PakLoadManager::LoadPakSync(const char* path) -{ - g_pakLoadApi->LoadPakSync(path, *pUnknownPakLoadSingleton, 0); -} -void PakLoadManager::LoadPakAsync(const char* path, bool bMarkForUnload) -{ - int handle = g_pakLoadApi->LoadPakAsync(path, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); - - if (bMarkForUnload) - m_pakHandlesToUnload.push_back(handle); -} - -void PakLoadManager::UnloadPaks() -{ - for (int pakHandle : m_pakHandlesToUnload) - g_pakLoadApi->UnloadPak(pakHandle, nullptr); - - m_pakHandlesToUnload.clear(); -} - -void HandlePakAliases(char** map) -{ - // convert the pak being loaded to it's aliased one, e.g. aliasing mp_hub_timeshift => sp_hub_timeshift - for (int64_t i = g_ModManager->m_loadedMods.size() - 1; i > -1; i--) - { - Mod* mod = &g_ModManager->m_loadedMods[i]; - if (!mod->Enabled) - continue; - - if (mod->RpakAliases.find(*map) != mod->RpakAliases.end()) - { - *map = &mod->RpakAliases[*map][0]; - return; - } - } -} - -void LoadPreloadPaks() -{ - // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - // need to get a relative path of mod to mod folder - fs::path modPakPath("./" / mod.ModDirectory / "paks"); - - for (ModRpakEntry& pak : mod.Rpaks) - if (pak.m_bAutoLoad) - g_PakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), false); - } -} - -void LoadCustomMapPaks(char** pakName, bool* bNeedToFreePakName) -{ - // whether the vanilla game has this rpak - bool bHasOriginalPak = fs::exists(fs::path("./r2/paks/Win64/") / *pakName); - - // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - // need to get a relative path of mod to mod folder - fs::path modPakPath("./" / mod.ModDirectory / "paks"); - - for (ModRpakEntry& pak : mod.Rpaks) - { - if (!pak.m_bAutoLoad && !pak.m_sPakName.compare(*pakName)) - { - // if the game doesn't have the original pak, let it handle loading this one as if it was the one it was loading originally - if (!bHasOriginalPak) - { - std::string path = (modPakPath / pak.m_sPakName).string(); - *pakName = new char[path.size() + 1]; - strcpy(*pakName, &path[0]); - (*pakName)[path.size()] = '\0'; - - bHasOriginalPak = true; - *bNeedToFreePakName = - true; // we can't free this memory until we're done with the pak, so let whatever's calling this deal with it - } - else - g_PakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), true); - } - } - } -} - -LoadPakSyncType LoadPakSyncOriginal; -void* LoadPakSyncHook(char* path, void* unknownSingleton, int flags) -{ - HandlePakAliases(&path); - - bool bNeedToFreePakName = false; - - // note: we don't handle loading any preloaded custom paks synchronously since LoadPakSync is never actually called in retail, just load - // them async instead - static bool bShouldLoadPaks = true; - if (bShouldLoadPaks) - { - // disable preloading while we're doing this - bShouldLoadPaks = false; - - LoadPreloadPaks(); - LoadCustomMapPaks(&path, &bNeedToFreePakName); - - bShouldLoadPaks = true; - } - - spdlog::info("LoadPakSync {}", path); - void* ret = LoadPakSyncOriginal(path, unknownSingleton, flags); - - if (bNeedToFreePakName) - delete[] path; - - return ret; -} - -LoadPakAsyncType LoadPakAsyncOriginal; -int LoadPakAsyncHook(char* path, void* unknownSingleton, int flags, void* callback0, void* callback1) -{ - HandlePakAliases(&path); - - bool bNeedToFreePakName = false; - - static bool bShouldLoadPaks = true; - if (bShouldLoadPaks) - { - // disable preloading while we're doing this - bShouldLoadPaks = false; - - LoadPreloadPaks(); - LoadCustomMapPaks(&path, &bNeedToFreePakName); - - bShouldLoadPaks = true; - - // do this after custom paks load and in bShouldLoadPaks so we only ever call this on the root pakload call - // todo: could probably add some way to flag custom paks to not be loaded on dedicated servers in rpak.json - if (IsDedicated() && strncmp(path, "common", 6)) // dedicated only needs common and common_mp - return -1; - } - - int ret = LoadPakAsyncOriginal(path, unknownSingleton, flags, callback0, callback1); - spdlog::info("LoadPakAsync {} {}", path, ret); - - if (bNeedToFreePakName) - delete[] path; - - return ret; -} - -UnloadPakType UnloadPakOriginal; -void* UnloadPakHook(int pakHandle, void* callback) -{ - static bool bShouldUnloadPaks = true; - if (bShouldUnloadPaks) - { - bShouldUnloadPaks = false; - g_PakLoadManager->UnloadPaks(); - bShouldUnloadPaks = true; - } - - spdlog::info("UnloadPak {}", pakHandle); - return UnloadPakOriginal(pakHandle, callback); -} - -// we hook this exclusively for resolving stbsp paths, but seemingly it's also used for other stuff like vpk and rpak loads -// possibly just async loading all together? -ReadFullFileFromDiskType ReadFullFileFromDiskOriginal; -void* ReadFullFileFromDiskHook(const char* requestedPath, void* a2) -{ - fs::path path(requestedPath); - char* allocatedNewPath = nullptr; - - if (path.extension() == ".stbsp") - { - fs::path filename = path.filename(); - spdlog::info("LoadStreamBsp: {}", filename.string()); - - // resolve modded stbsp path so we can load mod stbsps - auto modFile = g_ModManager->m_modFiles.find(fs::path("maps" / filename).lexically_normal().string()); - if (modFile != g_ModManager->m_modFiles.end()) - { - // need to allocate a new string for this - std::string newPath = (modFile->second.owningMod->ModDirectory / "mod" / modFile->second.path).string(); - allocatedNewPath = new char[newPath.size() + 1]; - strncpy(allocatedNewPath, newPath.c_str(), newPath.size()); - allocatedNewPath[newPath.size()] = '\0'; - requestedPath = allocatedNewPath; - } - } - - void* ret = ReadFullFileFromDiskOriginal(requestedPath, a2); - if (allocatedNewPath) - delete[] allocatedNewPath; - - return ret; -} - -void InitialiseEngineRpakFilesystem(HMODULE baseAddress) -{ - g_PakLoadManager = new PakLoadManager; - - g_pakLoadApi = *(PakLoadFuncs**)((char*)baseAddress + 0x5BED78); - pUnknownPakLoadSingleton = (void**)((char*)baseAddress + 0x7C5E20); - - HookEnabler hook; - ENABLER_CREATEHOOK(hook, g_pakLoadApi->LoadPakSync, &LoadPakSyncHook, reinterpret_cast<LPVOID*>(&LoadPakSyncOriginal)); - ENABLER_CREATEHOOK(hook, g_pakLoadApi->LoadPakAsync, &LoadPakAsyncHook, reinterpret_cast<LPVOID*>(&LoadPakAsyncOriginal)); - ENABLER_CREATEHOOK(hook, g_pakLoadApi->UnloadPak, &UnloadPakHook, reinterpret_cast<LPVOID*>(&UnloadPakOriginal)); - ENABLER_CREATEHOOK( - hook, g_pakLoadApi->ReadFullFileFromDisk, &ReadFullFileFromDiskHook, reinterpret_cast<LPVOID*>(&ReadFullFileFromDiskOriginal)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/rpakfilesystem.h b/NorthstarDedicatedTest/rpakfilesystem.h deleted file mode 100644 index 3c104822..00000000 --- a/NorthstarDedicatedTest/rpakfilesystem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -void InitialiseEngineRpakFilesystem(HMODULE baseAddress); - -class PakLoadManager -{ - public: - void LoadPakSync(const char* path); - void LoadPakAsync(const char* path, bool bMarkForUnload); - void UnloadPaks(); - - private: - std::vector<int> m_pakHandlesToUnload; -}; - -extern PakLoadManager* g_PakLoadManager;
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptbrowserhooks.cpp b/NorthstarDedicatedTest/scriptbrowserhooks.cpp deleted file mode 100644 index d90bc998..00000000 --- a/NorthstarDedicatedTest/scriptbrowserhooks.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "pch.h" -#include "scriptbrowserhooks.h" -#include "hookutils.h" - -typedef void (*OpenExternalWebBrowserType)(char* url, char flags); -OpenExternalWebBrowserType OpenExternalWebBrowser; - -bool* bIsOriginOverlayEnabled; - -void OpenExternalWebBrowserHook(char* url, char flags) -{ - bool bIsOriginOverlayEnabledOriginal = *bIsOriginOverlayEnabled; - if (flags & 2 && !strncmp(url, "http", 4)) // custom force external browser flag - *bIsOriginOverlayEnabled = false; // if this bool is false, game will use an external browser rather than the origin overlay one - - OpenExternalWebBrowser(url, flags); - *bIsOriginOverlayEnabled = bIsOriginOverlayEnabledOriginal; -} - -void InitialiseScriptExternalBrowserHooks(HMODULE baseAddress) -{ - bIsOriginOverlayEnabled = (bool*)baseAddress + 0x13978255; - - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x184E40, &OpenExternalWebBrowserHook, reinterpret_cast<LPVOID*>(&OpenExternalWebBrowser)); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptbrowserhooks.h b/NorthstarDedicatedTest/scriptbrowserhooks.h deleted file mode 100644 index 919cc92e..00000000 --- a/NorthstarDedicatedTest/scriptbrowserhooks.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseScriptExternalBrowserHooks(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptmainmenupromos.cpp b/NorthstarDedicatedTest/scriptmainmenupromos.cpp deleted file mode 100644 index c63d58d3..00000000 --- a/NorthstarDedicatedTest/scriptmainmenupromos.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "pch.h" -#include "scriptmainmenupromos.h" -#include "squirrel.h" -#include "masterserver.h" - -// mirror this in script -enum eMainMenuPromoDataProperty -{ - newInfoTitle1, - newInfoTitle2, - newInfoTitle3, - - largeButtonTitle, - largeButtonText, - largeButtonUrl, - largeButtonImageIndex, - - smallButton1Title, - smallButton1Url, - smallButton1ImageIndex, - - smallButton2Title, - smallButton2Url, - smallButton2ImageIndex -}; - -// void function NSRequestCustomMainMenuPromos() -SQRESULT SQ_RequestCustomMainMenuPromos(void* sqvm) -{ - g_MasterServerManager->RequestMainMenuPromos(); - return SQRESULT_NULL; -} - -// bool function NSHasCustomMainMenuPromoData() -SQRESULT SQ_HasCustomMainMenuPromoData(void* sqvm) -{ - ClientSq_pushbool(sqvm, g_MasterServerManager->m_bHasMainMenuPromoData); - return SQRESULT_NOTNULL; -} - -// var function NSGetCustomMainMenuPromoData( int promoDataKey ) -SQRESULT SQ_GetCustomMainMenuPromoData(void* sqvm) -{ - if (!g_MasterServerManager->m_bHasMainMenuPromoData) - return SQRESULT_NULL; - - switch (ClientSq_getinteger(sqvm, 1)) - { - case eMainMenuPromoDataProperty::newInfoTitle1: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle1.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::newInfoTitle2: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle2.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::newInfoTitle3: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.newInfoTitle3.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::largeButtonTitle: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonTitle.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::largeButtonText: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonText.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::largeButtonUrl: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonUrl.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::largeButtonImageIndex: - { - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.largeButtonImageIndex); - break; - } - - case eMainMenuPromoDataProperty::smallButton1Title: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1Title.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::smallButton1Url: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1Url.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::smallButton1ImageIndex: - { - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton1ImageIndex); - break; - } - - case eMainMenuPromoDataProperty::smallButton2Title: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2Title.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::smallButton2Url: - { - ClientSq_pushstring(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2Url.c_str(), -1); - break; - } - - case eMainMenuPromoDataProperty::smallButton2ImageIndex: - { - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_MainMenuPromoData.smallButton2ImageIndex); - break; - } - } - - return SQRESULT_NOTNULL; -} - -void InitialiseScriptMainMenuPromos(HMODULE baseAddress) -{ - g_UISquirrelManager->AddFuncRegistration("void", "NSRequestCustomMainMenuPromos", "", "", SQ_RequestCustomMainMenuPromos); - g_UISquirrelManager->AddFuncRegistration("bool", "NSHasCustomMainMenuPromoData", "", "", SQ_HasCustomMainMenuPromoData); - g_UISquirrelManager->AddFuncRegistration("var", "NSGetCustomMainMenuPromoData", "int promoDataKey", "", SQ_GetCustomMainMenuPromoData); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptmainmenupromos.h b/NorthstarDedicatedTest/scriptmainmenupromos.h deleted file mode 100644 index 2719e647..00000000 --- a/NorthstarDedicatedTest/scriptmainmenupromos.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseScriptMainMenuPromos(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptmodmenu.cpp b/NorthstarDedicatedTest/scriptmodmenu.cpp deleted file mode 100644 index ca3cfed4..00000000 --- a/NorthstarDedicatedTest/scriptmodmenu.cpp +++ /dev/null @@ -1,203 +0,0 @@ -#include "pch.h" -#include "scriptmodmenu.h" -#include "modmanager.h" -#include "squirrel.h" - -// array<string> function NSGetModNames() -SQRESULT SQ_GetModNames(void* sqvm) -{ - ClientSq_newarray(sqvm, 0); - - for (Mod& mod : g_ModManager->m_loadedMods) - { - ClientSq_pushstring(sqvm, mod.Name.c_str(), -1); - ClientSq_arrayappend(sqvm, -2); - } - - return SQRESULT_NOTNULL; -} - -// bool function NSIsModEnabled(string modName) -SQRESULT SQ_IsModEnabled(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - ClientSq_pushbool(sqvm, mod.Enabled); - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NULL; -} - -// void function NSSetModEnabled(string modName, bool enabled) -SQRESULT SQ_SetModEnabled(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - const SQBool enabled = ClientSq_getbool(sqvm, 2); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - mod.Enabled = enabled; - return SQRESULT_NULL; - } - } - - return SQRESULT_NULL; -} - -// string function NSGetModDescriptionByModName(string modName) -SQRESULT SQ_GetModDescription(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - ClientSq_pushstring(sqvm, mod.Description.c_str(), -1); - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NULL; -} - -// string function NSGetModVersionByModName(string modName) -SQRESULT SQ_GetModVersion(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - ClientSq_pushstring(sqvm, mod.Version.c_str(), -1); - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NULL; -} - -// string function NSGetModDownloadLinkByModName(string modName) -SQRESULT SQ_GetModDownloadLink(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - ClientSq_pushstring(sqvm, mod.DownloadLink.c_str(), -1); - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NULL; -} - -// int function NSGetModLoadPriority(string modName) -SQRESULT SQ_GetModLoadPriority(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - ClientSq_pushinteger(sqvm, mod.LoadPriority); - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NULL; -} - -// bool function NSIsModRequiredOnClient(string modName) -SQRESULT SQ_IsModRequiredOnClient(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - ClientSq_pushbool(sqvm, mod.RequiredOnClient); - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NULL; -} - -// array<string> function NSGetModConvarsByModName(string modName) -SQRESULT SQ_GetModConvars(void* sqvm) -{ - const SQChar* modName = ClientSq_getstring(sqvm, 1); - ClientSq_newarray(sqvm, 0); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_ModManager->m_loadedMods) - { - if (!mod.Name.compare(modName)) - { - for (ModConVar* cvar : mod.ConVars) - { - ClientSq_pushstring(sqvm, cvar->Name.c_str(), -1); - ClientSq_arrayappend(sqvm, -2); - } - - return SQRESULT_NOTNULL; - } - } - - return SQRESULT_NOTNULL; // return empty array -} - -// void function NSReloadMods() -SQRESULT SQ_ReloadMods(void* sqvm) -{ - g_ModManager->LoadMods(); - return SQRESULT_NULL; -} - -void InitialiseScriptModMenu(HMODULE baseAddress) -{ - g_UISquirrelManager->AddFuncRegistration("array<string>", "NSGetModNames", "", "Returns the names of all loaded mods", SQ_GetModNames); - g_UISquirrelManager->AddFuncRegistration( - "bool", "NSIsModEnabled", "string modName", "Returns whether a given mod is enabled", SQ_IsModEnabled); - g_UISquirrelManager->AddFuncRegistration( - "void", "NSSetModEnabled", "string modName, bool enabled", "Sets whether a given mod is enabled", SQ_SetModEnabled); - g_UISquirrelManager->AddFuncRegistration( - "string", "NSGetModDescriptionByModName", "string modName", "Returns a given mod's description", SQ_GetModDescription); - g_UISquirrelManager->AddFuncRegistration( - "string", "NSGetModVersionByModName", "string modName", "Returns a given mod's version", SQ_GetModVersion); - g_UISquirrelManager->AddFuncRegistration( - "string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModDownloadLink); - g_UISquirrelManager->AddFuncRegistration( - "bool", - "NSIsModRequiredOnClient", - "string modName", - "Returns whether a given mod is required on connecting clients", - SQ_IsModRequiredOnClient); - g_UISquirrelManager->AddFuncRegistration( - "int", "NSGetModLoadPriority", "string modName", "Returns a given mod's load priority", SQ_GetModLoadPriority); - g_UISquirrelManager->AddFuncRegistration( - "array<string>", "NSGetModConvarsByModName", "string modName", "Returns the names of all a given mod's cvars", SQ_GetModConvars); - - g_UISquirrelManager->AddFuncRegistration("void", "NSReloadMods", "", "Reloads mods", SQ_ReloadMods); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptmodmenu.h b/NorthstarDedicatedTest/scriptmodmenu.h deleted file mode 100644 index 019346d3..00000000 --- a/NorthstarDedicatedTest/scriptmodmenu.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseScriptModMenu(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptserverbrowser.cpp b/NorthstarDedicatedTest/scriptserverbrowser.cpp deleted file mode 100644 index aec47c3b..00000000 --- a/NorthstarDedicatedTest/scriptserverbrowser.cpp +++ /dev/null @@ -1,441 +0,0 @@ -#include "pch.h" -#include "scriptserverbrowser.h" -#include "squirrel.h" -#include "masterserver.h" -#include "gameutils.h" -#include "serverauthentication.h" - -// functions for viewing server browser - -// bool function NSIsMasterServerAuthenticated() -SQRESULT SQ_IsMasterServerAuthenticated(void* sqvm) -{ - ClientSq_pushbool(sqvm, g_MasterServerManager->m_bOriginAuthWithMasterServerDone); - return SQRESULT_NOTNULL; -} - -// void function NSRequestServerList() -SQRESULT SQ_RequestServerList(void* sqvm) -{ - g_MasterServerManager->RequestServerList(); - return SQRESULT_NULL; -} - -// bool function NSIsRequestingServerList() -SQRESULT SQ_IsRequestingServerList(void* sqvm) -{ - ClientSq_pushbool(sqvm, g_MasterServerManager->m_scriptRequestingServerList); - return SQRESULT_NOTNULL; -} - -// bool function NSMasterServerConnectionSuccessful() -SQRESULT SQ_MasterServerConnectionSuccessful(void* sqvm) -{ - ClientSq_pushbool(sqvm, g_MasterServerManager->m_successfullyConnected); - return SQRESULT_NOTNULL; -} - -// int function NSGetServerCount() -SQRESULT SQ_GetServerCount(void* sqvm) -{ - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_remoteServers.size()); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerName( int serverIndex ) -SQRESULT SQ_GetServerName(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get name of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].name, -1); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerDescription( int serverIndex ) -SQRESULT SQ_GetServerDescription(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get description of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].description.c_str(), -1); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerMap( int serverIndex ) -SQInteger SQ_GetServerMap(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get map of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].map, -1); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerPlaylist( int serverIndex ) -SQRESULT SQ_GetServerPlaylist(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get playlist of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].playlist, -1); - return SQRESULT_NOTNULL; -} - -// int function NSGetServerPlayerCount( int serverIndex ) -SQRESULT SQ_GetServerPlayerCount(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get playercount of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].playerCount); - return SQRESULT_NOTNULL; -} - -// int function NSGetServerMaxPlayerCount( int serverIndex ) -SQRESULT SQ_GetServerMaxPlayerCount(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get max playercount of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].maxPlayers); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerID( int serverIndex ) -SQRESULT SQ_GetServerID(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get id of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].id, -1); - return SQRESULT_NOTNULL; -} - -// bool function NSServerRequiresPassword( int serverIndex ) -SQRESULT SQ_ServerRequiresPassword(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get hasPassword of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushbool(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].requiresPassword); - return SQRESULT_NOTNULL; -} - -// int function NSGetServerRequiredModsCount( int serverIndex ) -SQRESULT SQ_GetServerRequiredModsCount(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get required mods count of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushinteger(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerRequiredModName( int serverIndex, int modIndex ) -SQRESULT SQ_GetServerRequiredModName(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - SQInteger modIndex = ClientSq_getinteger(sqvm, 2); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get hasPassword of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - if (modIndex >= g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get required mod name of mod index {} when only {} mod are available", - modIndex, - g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].requiredMods[modIndex].Name.c_str(), -1); - return SQRESULT_NOTNULL; -} - -// string function NSGetServerRequiredModVersion( int serverIndex, int modIndex ) -SQRESULT SQ_GetServerRequiredModVersion(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - SQInteger modIndex = ClientSq_getinteger(sqvm, 2); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get required mod version of server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - if (modIndex >= g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to get required mod version of mod index {} when only {} mod are available", - modIndex, - g_MasterServerManager->m_remoteServers[serverIndex].requiredMods.size()) - .c_str()); - return SQRESULT_ERROR; - } - - ClientSq_pushstring(sqvm, g_MasterServerManager->m_remoteServers[serverIndex].requiredMods[modIndex].Version.c_str(), -1); - return SQRESULT_NOTNULL; -} - -// void function NSClearRecievedServerList() -SQRESULT SQ_ClearRecievedServerList(void* sqvm) -{ - g_MasterServerManager->ClearServerList(); - return SQRESULT_NULL; -} - -// functions for authenticating with servers - -// void function NSTryAuthWithServer( int serverIndex, string password = "" ) -SQRESULT SQ_TryAuthWithServer(void* sqvm) -{ - SQInteger serverIndex = ClientSq_getinteger(sqvm, 1); - const SQChar* password = ClientSq_getstring(sqvm, 2); - - if (serverIndex >= g_MasterServerManager->m_remoteServers.size()) - { - ClientSq_pusherror( - sqvm, - fmt::format( - "Tried to auth with server index {} when only {} servers are available", - serverIndex, - g_MasterServerManager->m_remoteServers.size()) - .c_str()); - return SQRESULT_ERROR; - } - - // send off persistent data first, don't worry about server/client stuff, since m_additionalPlayerData should only have entries when - // we're a local server note: this seems like it could create a race condition, test later - for (auto& pair : g_ServerAuthenticationManager->m_additionalPlayerData) - g_ServerAuthenticationManager->WritePersistentData(pair.first); - - // do auth - g_MasterServerManager->AuthenticateWithServer( - g_LocalPlayerUserID, - g_MasterServerManager->m_ownClientAuthToken, - g_MasterServerManager->m_remoteServers[serverIndex].id, - (char*)password); - - return SQRESULT_NULL; -} - -// bool function NSIsAuthenticatingWithServer() -SQRESULT SQ_IsAuthComplete(void* sqvm) -{ - ClientSq_pushbool(sqvm, g_MasterServerManager->m_scriptAuthenticatingWithGameServer); - return SQRESULT_NOTNULL; -} - -// bool function NSWasAuthSuccessful() -SQRESULT SQ_WasAuthSuccessful(void* sqvm) -{ - ClientSq_pushbool(sqvm, g_MasterServerManager->m_successfullyAuthenticatedWithGameServer); - return SQRESULT_NOTNULL; -} - -// void function NSConnectToAuthedServer() -SQRESULT SQ_ConnectToAuthedServer(void* sqvm) -{ - if (!g_MasterServerManager->m_hasPendingConnectionInfo) - { - ClientSq_pusherror(sqvm, fmt::format("Tried to connect to authed server before any pending connection info was available").c_str()); - return SQRESULT_ERROR; - } - - RemoteServerConnectionInfo info = g_MasterServerManager->m_pendingConnectionInfo; - - // set auth token, then try to connect - // i'm honestly not entirely sure how silentconnect works regarding ports and encryption so using connect for now - Cbuf_AddText(Cbuf_GetCurrentPlayer(), fmt::format("serverfilter {}", info.authToken).c_str(), cmd_source_t::kCommandSrcCode); - Cbuf_AddText( - Cbuf_GetCurrentPlayer(), - fmt::format( - "connect {}.{}.{}.{}:{}", - info.ip.S_un.S_un_b.s_b1, - info.ip.S_un.S_un_b.s_b2, - info.ip.S_un.S_un_b.s_b3, - info.ip.S_un.S_un_b.s_b4, - info.port) - .c_str(), - cmd_source_t::kCommandSrcCode); - - g_MasterServerManager->m_hasPendingConnectionInfo = false; - return SQRESULT_NULL; -} - -// void function NSTryAuthWithLocalServer() -SQRESULT SQ_TryAuthWithLocalServer(void* sqvm) -{ - // do auth request - g_MasterServerManager->AuthenticateWithOwnServer(g_LocalPlayerUserID, g_MasterServerManager->m_ownClientAuthToken); - - return SQRESULT_NULL; -} - -// void function NSCompleteAuthWithLocalServer() -SQRESULT SQ_CompleteAuthWithLocalServer(void* sqvm) -{ - // literally just set serverfilter - // note: this assumes we have no authdata other than our own - Cbuf_AddText( - Cbuf_GetCurrentPlayer(), - fmt::format("serverfilter {}", g_ServerAuthenticationManager->m_authData.begin()->first).c_str(), - cmd_source_t::kCommandSrcCode); - - return SQRESULT_NULL; -} - -void InitialiseScriptServerBrowser(HMODULE baseAddress) -{ - g_UISquirrelManager->AddFuncRegistration("bool", "NSIsMasterServerAuthenticated", "", "", SQ_IsMasterServerAuthenticated); - g_UISquirrelManager->AddFuncRegistration("void", "NSRequestServerList", "", "", SQ_RequestServerList); - g_UISquirrelManager->AddFuncRegistration("bool", "NSIsRequestingServerList", "", "", SQ_IsRequestingServerList); - g_UISquirrelManager->AddFuncRegistration("bool", "NSMasterServerConnectionSuccessful", "", "", SQ_MasterServerConnectionSuccessful); - g_UISquirrelManager->AddFuncRegistration("int", "NSGetServerCount", "", "", SQ_GetServerCount); - g_UISquirrelManager->AddFuncRegistration("void", "NSClearRecievedServerList", "", "", SQ_ClearRecievedServerList); - - g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerName", "int serverIndex", "", SQ_GetServerName); - g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerDescription", "int serverIndex", "", SQ_GetServerDescription); - g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerMap", "int serverIndex", "", SQ_GetServerMap); - g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerPlaylist", "int serverIndex", "", SQ_GetServerPlaylist); - g_UISquirrelManager->AddFuncRegistration("int", "NSGetServerPlayerCount", "int serverIndex", "", SQ_GetServerPlayerCount); - g_UISquirrelManager->AddFuncRegistration("int", "NSGetServerMaxPlayerCount", "int serverIndex", "", SQ_GetServerMaxPlayerCount); - g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerID", "int serverIndex", "", SQ_GetServerID); - g_UISquirrelManager->AddFuncRegistration("bool", "NSServerRequiresPassword", "int serverIndex", "", SQ_ServerRequiresPassword); - g_UISquirrelManager->AddFuncRegistration("int", "NSGetServerRequiredModsCount", "int serverIndex", "", SQ_GetServerRequiredModsCount); - g_UISquirrelManager->AddFuncRegistration( - "string", "NSGetServerRequiredModName", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModName); - g_UISquirrelManager->AddFuncRegistration( - "string", "NSGetServerRequiredModVersion", "int serverIndex, int modIndex", "", SQ_GetServerRequiredModVersion); - - g_UISquirrelManager->AddFuncRegistration( - "void", "NSTryAuthWithServer", "int serverIndex, string password = \"\"", "", SQ_TryAuthWithServer); - g_UISquirrelManager->AddFuncRegistration("bool", "NSIsAuthenticatingWithServer", "", "", SQ_IsAuthComplete); - g_UISquirrelManager->AddFuncRegistration("bool", "NSWasAuthSuccessful", "", "", SQ_WasAuthSuccessful); - g_UISquirrelManager->AddFuncRegistration("void", "NSConnectToAuthedServer", "", "", SQ_ConnectToAuthedServer); - - g_UISquirrelManager->AddFuncRegistration("void", "NSTryAuthWithLocalServer", "", "", SQ_TryAuthWithLocalServer); - g_UISquirrelManager->AddFuncRegistration("void", "NSCompleteAuthWithLocalServer", "", "", SQ_CompleteAuthWithLocalServer); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptserverbrowser.h b/NorthstarDedicatedTest/scriptserverbrowser.h deleted file mode 100644 index 55776de0..00000000 --- a/NorthstarDedicatedTest/scriptserverbrowser.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include <minwindef.h> - -void InitialiseScriptServerBrowser(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp b/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp deleted file mode 100644 index 084db1e4..00000000 --- a/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "pch.h" -#include "scriptservertoclientstringcommand.h" -#include "squirrel.h" -#include "convar.h" -#include "concommand.h" - -void ConCommand_ns_script_servertoclientstringcommand(const CCommand& arg) -{ - if (g_ClientSquirrelManager->sqvm && - g_ClientSquirrelManager->setupfunc("NSClientCodeCallback_RecievedServerToClientStringCommand") != SQRESULT_ERROR) - { - g_ClientSquirrelManager->pusharg(arg.ArgS()); - g_ClientSquirrelManager->call(1); // todo: doesn't throw or log errors from within this, probably not great behaviour - } -} - -void InitialiseScriptServerToClientStringCommands(HMODULE baseAddress) -{ - RegisterConCommand( - "ns_script_servertoclientstringcommand", - ConCommand_ns_script_servertoclientstringcommand, - "", - FCVAR_CLIENTDLL | FCVAR_SERVER_CAN_EXECUTE); -} diff --git a/NorthstarDedicatedTest/scriptservertoclientstringcommand.h b/NorthstarDedicatedTest/scriptservertoclientstringcommand.h deleted file mode 100644 index 609c6105..00000000 --- a/NorthstarDedicatedTest/scriptservertoclientstringcommand.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void InitialiseScriptServerToClientStringCommands(HMODULE baseAddress);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp deleted file mode 100644 index 09ed41d3..00000000 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ /dev/null @@ -1,743 +0,0 @@ -#include "pch.h" -#include "serverauthentication.h" -#include "cvar.h" -#include "convar.h" -#include "hookutils.h" -#include "masterserver.h" -#include "httplib.h" -#include "gameutils.h" -#include "bansystem.h" -#include "miscserverscript.h" -#include "concommand.h" -#include "dedicated.h" -#include <fstream> -#include <filesystem> -#include <thread> -#include "configurables.h" -#include "NSMem.h" - -const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!"; - -// hook types - -typedef void* (*CBaseServer__ConnectClientType)( - void* server, - void* a2, - void* a3, - uint32_t a4, - uint32_t a5, - int32_t a6, - void* a7, - void* a8, - char* serverFilter, - void* a10, - char a11, - void* a12, - char a13, - char a14, - int64_t uid, - uint32_t a16, - uint32_t a17); -CBaseServer__ConnectClientType CBaseServer__ConnectClient; - -typedef bool (*CBaseClient__ConnectType)( - void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7); -CBaseClient__ConnectType CBaseClient__Connect; - -typedef void (*CBaseClient__ActivatePlayerType)(void* self); -CBaseClient__ActivatePlayerType CBaseClient__ActivatePlayer; - -CBaseClient__DisconnectType CBaseClient__Disconnect; - -typedef char (*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString); -CGameClient__ExecuteStringCommandType CGameClient__ExecuteStringCommand; - -typedef char (*__fastcall CNetChan___ProcessMessagesType)(void* self, void* buf); -CNetChan___ProcessMessagesType CNetChan___ProcessMessages; - -typedef char (*CBaseClient__SendServerInfoType)(void* self); -CBaseClient__SendServerInfoType CBaseClient__SendServerInfo; - -typedef bool (*ProcessConnectionlessPacketType)(void* a1, netpacket_t* packet); -ProcessConnectionlessPacketType ProcessConnectionlessPacket; - -typedef void (*CServerGameDLL__OnReceivedSayTextMessageType)(void* self, unsigned int senderClientIndex, const char* message, char unknown); -CServerGameDLL__OnReceivedSayTextMessageType CServerGameDLL__OnReceivedSayTextMessage; - -typedef void (*ConCommand__DispatchType)(ConCommand* command, const CCommand& args, void* a3); -ConCommand__DispatchType ConCommand__Dispatch; - -// global vars -ServerAuthenticationManager* g_ServerAuthenticationManager; - -ConVar* Cvar_ns_player_auth_port; -ConVar* Cvar_ns_erase_auth_info; -ConVar* CVar_ns_auth_allow_insecure; -ConVar* CVar_ns_auth_allow_insecure_write; -ConVar* CVar_sv_quota_stringcmdspersecond; -ConVar* Cvar_net_chan_limit_mode; -ConVar* Cvar_net_chan_limit_msec_per_sec; -ConVar* Cvar_sv_querylimit_per_sec; -ConVar* Cvar_sv_max_chat_messages_per_sec; - -ConVar* Cvar_net_datablock_enabled; - -void ServerAuthenticationManager::StartPlayerAuthServer() -{ - if (m_runningPlayerAuthThread) - { - spdlog::warn("ServerAuthenticationManager::StartPlayerAuthServer was called while m_runningPlayerAuthThread is true"); - return; - } - - m_runningPlayerAuthThread = true; - - // listen is a blocking call so thread this - std::thread serverThread( - [this] - { - // this is just a super basic way to verify that servers have ports open, masterserver will try to read this before ensuring - // server is legit - m_playerAuthServer.Get( - "/verify", - [](const httplib::Request& request, httplib::Response& response) - { response.set_content(AUTHSERVER_VERIFY_STRING, "text/plain"); }); - - m_playerAuthServer.Post( - "/authenticate_incoming_player", - [this](const httplib::Request& request, httplib::Response& response) - { - // can't just do request.remote_addr == Cvar_ns_masterserver_hostname->GetString() because the cvar can be a url, gotta - // resolve an ip from it for comparisons - // unsigned long remoteAddr = inet_addr(request.remote_addr.c_str()); - // - // char* addrPtr = Cvar_ns_masterserver_hostname->GetString(); - // char* typeStart = strstr(addrPtr, "://"); - // if (typeStart) - // addrPtr = typeStart + 3; - // hostent* resolvedRemoteAddr = gethostbyname((const char*)addrPtr); - - if (!request.has_param("id") || !request.has_param("authToken") || request.body.size() >= 65335 || - !request.has_param("serverAuthToken") || - strcmp( - g_MasterServerManager->m_ownServerAuthToken, - request.get_param_value("serverAuthToken") - .c_str())) // || !resolvedRemoteAddr || ((in_addr**)resolvedRemoteAddr->h_addr_list)[0]->S_un.S_addr != - // remoteAddr) - { - response.set_content("{\"success\":false}", "application/json"); - return; - } - - // Log playername and UID from request - spdlog::info( - "Player \"{}\" with UID \"{}\" requested to join", - request.get_param_value("username").c_str(), - request.get_param_value("id").c_str()); - - AuthData newAuthData {}; - strncpy(newAuthData.uid, request.get_param_value("id").c_str(), sizeof(newAuthData.uid)); - newAuthData.uid[sizeof(newAuthData.uid) - 1] = 0; - - strncpy(newAuthData.username, request.get_param_value("username").c_str(), sizeof(newAuthData.username)); - newAuthData.username[sizeof(newAuthData.username) - 1] = 0; - - newAuthData.pdataSize = request.body.size(); - newAuthData.pdata = new char[newAuthData.pdataSize]; - memcpy(newAuthData.pdata, request.body.c_str(), newAuthData.pdataSize); - - std::lock_guard<std::mutex> guard(m_authDataMutex); - m_authData.insert(std::make_pair(request.get_param_value("authToken"), newAuthData)); - - response.set_content("{\"success\":true}", "application/json"); - }); - - m_playerAuthServer.listen("0.0.0.0", Cvar_ns_player_auth_port->GetInt()); - }); - - serverThread.detach(); -} - -void ServerAuthenticationManager::StopPlayerAuthServer() -{ - if (!m_runningPlayerAuthThread) - { - spdlog::warn("ServerAuthenticationManager::StopPlayerAuthServer was called while m_runningPlayerAuthThread is false"); - return; - } - - m_runningPlayerAuthThread = false; - m_playerAuthServer.stop(); -} - -char* ServerAuthenticationManager::VerifyPlayerName(void* player, char* authToken, char* name) -{ - std::lock_guard<std::mutex> guard(m_authDataMutex); - - if (!m_authData.empty() && m_authData.count(std::string(authToken))) - { - AuthData authData = m_authData[authToken]; - - bool nameAccepted = (!*authData.username || !strcmp(name, authData.username)); - - if (!nameAccepted && g_MasterServerManager->m_bRequireClientAuth && !CVar_ns_auth_allow_insecure->GetInt()) - { - // limit name length to 64 characters just in case something changes, this technically shouldn't be needed given the master - // server gets usernames from origin but we have it just in case - strncpy(name, authData.username, 64); - name[63] = 0; - } - } - return name; -} - -bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, char* authToken) -{ - std::string strUid = std::to_string(uid); - std::lock_guard<std::mutex> guard(m_authDataMutex); - - bool authFail = true; - if (!m_authData.empty() && m_authData.count(std::string(authToken))) - { - // use stored auth data - AuthData authData = m_authData[authToken]; - - // Log playnername and UID from request - spdlog::info("Comparing connecting UID \"{}\" against stored UID from ms auth request \"{}\"", strUid.c_str(), authData.uid); - - if (!strcmp(strUid.c_str(), authData.uid)) // connecting client's uid is the same as auth's uid - { - authFail = false; - // uuid - strcpy((char*)player + 0xF500, strUid.c_str()); - - // reset from disk if we're doing that - if (m_bForceReadLocalPlayerPersistenceFromDisk && !strcmp(authData.uid, g_LocalPlayerUserID)) - { - std::fstream pdataStream(GetNorthstarPrefix() + "/placeholder_playerdata.pdata", std::ios_base::in); - - if (!pdataStream.fail()) - { - // get file length - pdataStream.seekg(0, pdataStream.end); - auto length = pdataStream.tellg(); - pdataStream.seekg(0, pdataStream.beg); - - // copy pdata into buffer - pdataStream.read((char*)player + 0x4FA, length); - } - else // fallback to remote pdata if no local default - memcpy((char*)player + 0x4FA, authData.pdata, authData.pdataSize); - } - else - { - // copy pdata into buffer - memcpy((char*)player + 0x4FA, authData.pdata, authData.pdataSize); - } - - // set persistent data as ready, we use 0x4 internally to mark the client as using remote persistence - *((char*)player + 0x4a0) = (char)0x4; - } - } - - if (authFail) - { - // set persistent data as ready, we use 0x3 internally to mark the client as using local persistence - *((char*)player + 0x4a0) = (char)0x3; - - if (!CVar_ns_auth_allow_insecure->GetBool()) // no auth data and insecure connections aren't allowed, so dc the client - return false; - - // insecure connections are allowed, try reading from disk - // uuid - strcpy((char*)player + 0xF500, strUid.c_str()); - - // try reading pdata file for player - std::string pdataPath = GetNorthstarPrefix() + "/playerdata_"; - pdataPath += strUid; - pdataPath += ".pdata"; - - std::fstream pdataStream(pdataPath, std::ios_base::in); - if (pdataStream.fail()) // file doesn't exist, use placeholder - pdataStream = std::fstream(GetNorthstarPrefix() + "/placeholder_playerdata.pdata"); - - // get file length - pdataStream.seekg(0, pdataStream.end); - auto length = pdataStream.tellg(); - pdataStream.seekg(0, pdataStream.beg); - - // copy pdata into buffer - pdataStream.read((char*)player + 0x4FA, length); - - pdataStream.close(); - } - - return true; // auth successful, client stays on -} - -bool ServerAuthenticationManager::RemovePlayerAuthData(void* player) -{ - if (!Cvar_ns_erase_auth_info->GetBool()) - return false; - - // hack for special case where we're on a local server, so we erase our own newly created auth data on disconnect - if (m_bNeedLocalAuthForNewgame && !strcmp((char*)player + 0xF500, g_LocalPlayerUserID)) - return false; - - // we don't have our auth token at this point, so lookup authdata by uid - for (auto& auth : m_authData) - { - if (!strcmp((char*)player + 0xF500, auth.second.uid)) - { - // Log UID - spdlog::info("Erasing auth data from UID \"{}\"", auth.second.uid); - // pretty sure this is fine, since we don't iterate after the erase - // i think if we iterated after it'd be undefined behaviour tho - std::lock_guard<std::mutex> guard(m_authDataMutex); - - delete[] auth.second.pdata; - m_authData.erase(auth.first); - return true; - } - } - - return false; -} - -void ServerAuthenticationManager::WritePersistentData(void* player) -{ - // we use 0x4 internally to mark clients as using remote persistence - if (*((char*)player + 0x4A0) == (char)0x4) - { - g_MasterServerManager->WritePlayerPersistentData( - (char*)player + 0xF500, (char*)player + 0x4FA, m_additionalPlayerData[player].pdataSize); - } - else if (CVar_ns_auth_allow_insecure_write->GetBool()) - { - // todo: write pdata to disk here - } -} - -bool ServerAuthenticationManager::CheckPlayerChatRatelimit(void* player) -{ - if (Plat_FloatTime() - m_additionalPlayerData[player].lastSayTextLimitStart >= 1.0) - { - m_additionalPlayerData[player].lastSayTextLimitStart = Plat_FloatTime(); - m_additionalPlayerData[player].sayTextLimitCount = 0; - } - - if (m_additionalPlayerData[player].sayTextLimitCount >= Cvar_sv_max_chat_messages_per_sec->GetInt()) - return false; - - m_additionalPlayerData[player].sayTextLimitCount++; - return true; -} - -// auth hooks - -// store these in vars so we can use them in CBaseClient::Connect -// this is fine because ptrs won't decay by the time we use this, just don't use it outside of cbaseclient::connect -char* nextPlayerToken; -uint64_t nextPlayerUid; - -void* CBaseServer__ConnectClientHook( - void* server, - void* a2, - void* a3, - uint32_t a4, - uint32_t a5, - int32_t a6, - void* a7, - void* a8, - char* serverFilter, - void* a10, - char a11, - void* a12, - char a13, - char a14, - int64_t uid, - uint32_t a16, - uint32_t a17) -{ - // auth tokens are sent with serverfilter, can't be accessed from player struct to my knowledge, so have to do this here - nextPlayerToken = serverFilter; - nextPlayerUid = uid; - - // Random UID log - spdlog::info("CBaseServer__ConnectClientHook says UID \"{}\"", uid); - - return CBaseServer__ConnectClient(server, a2, a3, a4, a5, a6, a7, a8, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17); -} - -bool CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7) -{ - // try changing name before all else - name = g_ServerAuthenticationManager->VerifyPlayerName(self, nextPlayerToken, name); - - // try to auth player, dc if it fails - // we connect irregardless of auth, because returning bad from this function can fuck client state p bad - bool ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7); - - // Another UID log - spdlog::info("CBaseClient__ConnectHook says UID \"{}\"", nextPlayerUid); - - if (!ret) - return ret; - - if (!g_ServerBanSystem->IsUIDAllowed(nextPlayerUid)) - { - CBaseClient__Disconnect(self, 1, "Banned from server"); - return ret; - } - - if (strlen(name) >= 64) // fix for name overflow bug - CBaseClient__Disconnect(self, 1, "Invalid name"); - else if ( - !g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerUid, nextPlayerToken) && - g_MasterServerManager->m_bRequireClientAuth) - CBaseClient__Disconnect(self, 1, "Authentication Failed"); - - if (!g_ServerAuthenticationManager->m_additionalPlayerData.count(self)) - { - AdditionalPlayerData additionalData; - additionalData.pdataSize = g_ServerAuthenticationManager->m_authData[nextPlayerToken].pdataSize; - additionalData.usingLocalPdata = *((char*)self + 0x4a0) == (char)0x3; - - g_ServerAuthenticationManager->m_additionalPlayerData.insert(std::make_pair(self, additionalData)); - - g_ServerAuthenticationManager->m_additionalPlayerData[self].uid = nextPlayerUid; - } - - return ret; -} - -void CBaseClient__ActivatePlayerHook(void* self) -{ - bool uidMatches = false; - if (g_ServerAuthenticationManager->m_additionalPlayerData.count(self)) - { - std::string strUid = std::to_string(g_ServerAuthenticationManager->m_additionalPlayerData[self].uid); - if (!strcmp(strUid.c_str(), (char*)self + 0xF500)) // connecting client's uid is the same as auth's uid - { - uidMatches = true; - } - } - if (!uidMatches) - { - CBaseClient__Disconnect(self, 1, "Authentication Failed"); - return; - } - - // if we're authed, write our persistent data - // RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call - // (since this func is called on map loads) - if (*((char*)self + 0x4A0) >= (char)0x3 && !g_ServerAuthenticationManager->RemovePlayerAuthData(self)) - { - g_ServerAuthenticationManager->m_bForceReadLocalPlayerPersistenceFromDisk = false; - g_ServerAuthenticationManager->WritePersistentData(self); - g_MasterServerManager->UpdateServerPlayerCount(g_ServerAuthenticationManager->m_additionalPlayerData.size()); - } - // Log UID - spdlog::info("In CBaseClient__ActivatePlayerHook, activating UID \"{}\"", (char*)self + 0xF500); - - CBaseClient__ActivatePlayer(self); -} - -void CBaseClient__DisconnectHook(void* self, uint32_t unknownButAlways1, const char* reason, ...) -{ - // have to manually format message because can't pass varargs to original func - char buf[1024]; - - va_list va; - va_start(va, reason); - vsprintf(buf, reason, va); - va_end(va); - - // this reason is used while connecting to a local server, hacky, but just ignore it - if (strcmp(reason, "Connection closing")) - { - spdlog::info("Player {} disconnected: \"{}\"", (char*)self + 0x16, buf); - - // dcing, write persistent data - if (g_ServerAuthenticationManager->m_additionalPlayerData[self].needPersistenceWriteOnLeave) - g_ServerAuthenticationManager->WritePersistentData(self); - g_ServerAuthenticationManager->RemovePlayerAuthData(self); // won't do anything 99% of the time, but just in case - } - - if (g_ServerAuthenticationManager->m_additionalPlayerData.count(self)) - { - g_ServerAuthenticationManager->m_additionalPlayerData.erase(self); - g_MasterServerManager->UpdateServerPlayerCount(g_ServerAuthenticationManager->m_additionalPlayerData.size()); - } - - CBaseClient__Disconnect(self, unknownButAlways1, buf); -} - -// maybe this should be done outside of auth code, but effort to refactor rn and it sorta fits -typedef bool (*CCommand__TokenizeType)(CCommand& self, const char* pCommandString, cmd_source_t commandSource); -CCommand__TokenizeType CCommand__Tokenize; - -char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const char* pCommandString) -{ - if (CVar_sv_quota_stringcmdspersecond->GetInt() != -1) - { - // note: this isn't super perfect, legit clients can trigger it in lobby, mostly good enough tho imo - // https://github.com/perilouswithadollarsign/cstrike15_src/blob/f82112a2388b841d72cb62ca48ab1846dfcc11c8/engine/sv_client.cpp#L1513 - if (Plat_FloatTime() - g_ServerAuthenticationManager->m_additionalPlayerData[self].lastClientCommandQuotaStart >= 1.0) - { - // reset quota - g_ServerAuthenticationManager->m_additionalPlayerData[self].lastClientCommandQuotaStart = Plat_FloatTime(); - g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota = 0; - } - - g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota++; - if (g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota > - CVar_sv_quota_stringcmdspersecond->GetInt()) - { - // too many stringcmds, dc player - CBaseClient__Disconnect(self, 1, "Sent too many stringcmd commands"); - return false; - } - } - - // verify the command we're trying to execute is FCVAR_CLIENTCMD_CAN_EXECUTE, if it's a concommand - char* commandBuf[1040]; // assumedly this is the size of CCommand since we don't have an actual constructor - memset(commandBuf, 0, sizeof(commandBuf)); - CCommand tempCommand = *(CCommand*)&commandBuf; - - if (!CCommand__Tokenize(tempCommand, pCommandString, cmd_source_t::kCommandSrcCode) || !tempCommand.ArgC()) - return false; - - ConCommand* command = g_pCVar->FindCommand(tempCommand.Arg(0)); - - // if the command doesn't exist pass it on to ExecuteStringCommand for script clientcommands and stuff - if (command && !command->IsFlagSet(FCVAR_CLIENTCMD_CAN_EXECUTE)) - { - // ensure FCVAR_GAMEDLL concommands without FCVAR_CLIENTCMD_CAN_EXECUTE can't be executed by remote clients - if (IsDedicated()) - return false; - - if (strcmp((char*)self + 0xF500, g_LocalPlayerUserID)) - return false; - } - - // todo later, basically just limit to CVar_sv_quota_stringcmdspersecond->GetInt() stringcmds per client per second - return CGameClient__ExecuteStringCommand(self, unknown, pCommandString); -} - -char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf) -{ - double startTime = Plat_FloatTime(); - char ret = CNetChan___ProcessMessages(self, buf); - - // check processing limits, unless we're in a level transition - if (g_pHostState->m_iCurrentState == HostState_t::HS_RUN && ThreadInServerFrameThread()) - { - // player that sent the message - void* sender = *(void**)((char*)self + 368); - - // if no sender, return - // relatively certain this is fine? - if (!sender || !g_ServerAuthenticationManager->m_additionalPlayerData.count(sender)) - return ret; - - // reset every second - if (startTime - g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart >= 1.0 || - g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart == -1.0) - { - g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart = startTime; - g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime = 0.0; - } - g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime += - (Plat_FloatTime() * 1000) - (startTime * 1000); - - if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >= - Cvar_net_chan_limit_msec_per_sec->GetInt()) - { - spdlog::warn( - "Client {} hit netchan processing limit with {}ms of processing time this second (max is {})", - (char*)sender + 0x16, - g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime, - Cvar_net_chan_limit_msec_per_sec->GetInt()); - - // nonzero = kick, 0 = warn, but never kick local player - if (Cvar_net_chan_limit_mode->GetInt() && strcmp(g_LocalPlayerUserID, (char*)sender + 0xF500)) - { - CBaseClient__Disconnect(sender, 1, "Exceeded net channel processing limit"); - return false; - } - } - } - - return ret; -} - -bool bWasWritingStringTableSuccessful; - -void CBaseClient__SendServerInfoHook(void* self) -{ - bWasWritingStringTableSuccessful = true; - CBaseClient__SendServerInfo(self); - if (!bWasWritingStringTableSuccessful) - CBaseClient__Disconnect( - self, 1, "Overflowed CNetworkStringTableContainer::WriteBaselines, try restarting your client and reconnecting"); -} - -bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet) -{ - if (packet->adr.type == NA_IP && - (!(packet->data[4] == 'N' && Cvar_net_datablock_enabled->GetBool()) || !Cvar_net_datablock_enabled->GetBool())) - { - // bad lookup: optimise later tm - UnconnectedPlayerSendData* sendData = nullptr; - for (UnconnectedPlayerSendData& foundSendData : g_ServerAuthenticationManager->m_unconnectedPlayerSendData) - { - if (!memcmp(packet->adr.ip, foundSendData.ip, 16)) - { - sendData = &foundSendData; - break; - } - } - - if (!sendData) - { - sendData = &g_ServerAuthenticationManager->m_unconnectedPlayerSendData.emplace_back(); - memcpy(sendData->ip, packet->adr.ip, 16); - } - - if (Plat_FloatTime() < sendData->timeoutEnd) - return false; - - if (Plat_FloatTime() - sendData->lastQuotaStart >= 1.0) - { - sendData->lastQuotaStart = Plat_FloatTime(); - sendData->packetCount = 0; - } - - sendData->packetCount++; - - if (sendData->packetCount >= Cvar_sv_querylimit_per_sec->GetInt()) - { - spdlog::warn( - "Client went over connectionless ratelimit of {} per sec with packet of type {}", - Cvar_sv_querylimit_per_sec->GetInt(), - packet->data[4]); - - // timeout for a minute - sendData->timeoutEnd = Plat_FloatTime() + 60.0; - return false; - } - } - - return ProcessConnectionlessPacket(a1, packet); -} - -void ResetPdataCommand(const CCommand& args) -{ - if (*sv_m_State == server_state_t::ss_active) - { - spdlog::error("ns_resetpersistence must be entered from the main menu"); - return; - } - - spdlog::info("resetting persistence on next lobby load..."); - g_ServerAuthenticationManager->m_bForceReadLocalPlayerPersistenceFromDisk = true; -} - -void InitialiseServerAuthentication(HMODULE baseAddress) -{ - g_ServerAuthenticationManager = new ServerAuthenticationManager; - - Cvar_ns_erase_auth_info = - new ConVar("ns_erase_auth_info", "1", FCVAR_GAMEDLL, "Whether auth info should be erased from this server on disconnect or crash"); - CVar_ns_auth_allow_insecure = - new ConVar("ns_auth_allow_insecure", "0", FCVAR_GAMEDLL, "Whether this server will allow unauthenicated players to connect"); - CVar_ns_auth_allow_insecure_write = new ConVar( - "ns_auth_allow_insecure_write", - "0", - FCVAR_GAMEDLL, - "Whether the pdata of unauthenticated clients will be written to disk when changed"); - // literally just stolen from a fix valve used in csgo - CVar_sv_quota_stringcmdspersecond = new ConVar( - "sv_quota_stringcmdspersecond", - "60", - FCVAR_GAMEDLL, - "How many string commands per second clients are allowed to submit, 0 to disallow all string commands"); - // https://blog.counter-strike.net/index.php/2019/07/24922/ but different because idk how to check what current tick number is - Cvar_net_chan_limit_mode = - new ConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = log, 1 = kick"); - Cvar_net_chan_limit_msec_per_sec = new ConVar( - "net_chan_limit_msec_per_sec", - "0", - FCVAR_GAMEDLL, - "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget"); - Cvar_ns_player_auth_port = new ConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, ""); - Cvar_sv_querylimit_per_sec = new ConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, ""); - Cvar_sv_max_chat_messages_per_sec = new ConVar("sv_max_chat_messages_per_sec", "5", FCVAR_GAMEDLL, ""); - - Cvar_net_datablock_enabled = g_pCVar->FindVar("net_datablock_enabled"); - - RegisterConCommand("ns_resetpersistence", ResetPdataCommand, "resets your pdata when you next enter the lobby", FCVAR_NONE); - - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x114430, &CBaseServer__ConnectClientHook, reinterpret_cast<LPVOID*>(&CBaseServer__ConnectClient)); - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x101740, &CBaseClient__ConnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Connect)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x1012C0, &CBaseClient__DisconnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Disconnect)); - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x1022E0, - &CGameClient__ExecuteStringCommandHook, - reinterpret_cast<LPVOID*>(&CGameClient__ExecuteStringCommand)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x2140A0, &CNetChan___ProcessMessagesHook, reinterpret_cast<LPVOID*>(&CNetChan___ProcessMessages)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x104FB0, &CBaseClient__SendServerInfoHook, reinterpret_cast<LPVOID*>(&CBaseClient__SendServerInfo)); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x117800, &ProcessConnectionlessPacketHook, reinterpret_cast<LPVOID*>(&ProcessConnectionlessPacket)); - - CCommand__Tokenize = (CCommand__TokenizeType)((char*)baseAddress + 0x418380); - - uintptr_t ba = (uintptr_t)baseAddress; - - // patch to disable kicking based on incorrect serverfilter in connectclient, since we repurpose it for use as an auth token - { - NSMem::BytePatch( - ba + 0x114655, - "EB" // jz => jmp - ); - } - - // patch to disable fairfight marking players as cheaters and kicking them - { - NSMem::BytePatch( - ba + 0x101012, - "E9 90 00" // jz => jmp - ); - } - - // patch to allow same of multiple account - if (CommandLine()->CheckParm("-allowdupeaccounts")) - { - NSMem::BytePatch( - ba + 0x114510, - "EB" // jz => jmp - ); - } - - // patch to set bWasWritingStringTableSuccessful in CNetworkStringTableContainer::WriteBaselines if it fails - { - uintptr_t writeAddress = (uintptr_t)(&bWasWritingStringTableSuccessful - (ba + 0x234EDC)); - - auto addr = ba + 0x234ED2; - NSMem::BytePatch(addr, "C7 05"); - NSMem::BytePatch(addr + 2, (BYTE*)&writeAddress, sizeof(writeAddress)); - - NSMem::BytePatch(addr + 6, "00 00 00 00"); - - NSMem::NOP(addr + 10, 5); - } -} diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h deleted file mode 100644 index e79577e6..00000000 --- a/NorthstarDedicatedTest/serverauthentication.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once -#include "convar.h" -#include "httplib.h" -#include <unordered_map> -#include <string> - -struct AuthData -{ - char uid[33]; - char username[64]; - - // pdata - char* pdata; - size_t pdataSize; -}; - -struct AdditionalPlayerData -{ - bool usingLocalPdata; - size_t pdataSize; - bool needPersistenceWriteOnLeave = true; - - double lastClientCommandQuotaStart = -1.0; - int numClientCommandsInQuota = 0; - - double lastNetChanProcessingLimitStart = -1.0; - double netChanProcessingLimitTime = 0.0; - - double lastSayTextLimitStart = -1.0; - int sayTextLimitCount = 0; - - uint64_t uid; -}; - -#pragma once -typedef enum -{ - NA_NULL = 0, - NA_LOOPBACK, - NA_IP, -} netadrtype_t; - -#pragma pack(push, 1) -typedef struct netadr_s -{ - netadrtype_t type; - unsigned char ip[16]; // IPv6 - // IPv4's 127.0.0.1 is [::ffff:127.0.0.1], that is: - // 00 00 00 00 00 00 00 00 00 00 FF FF 7F 00 00 01 - unsigned short port; -} netadr_t; -#pragma pack(pop) - -#pragma pack(push, 1) -typedef struct netpacket_s -{ - netadr_t adr; // sender address - // int source; // received source - char unk[10]; - double received_time; - unsigned char* data; // pointer to raw packet data - void* message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer) - char unk2[16]; - int size; - - // bf_read message; // easy bitbuf data access // 'inpacket.message' etc etc (pointer) - // int size; // size in bytes - // int wiresize; // size in bytes before decompression - // bool stream; // was send as stream - // struct netpacket_s* pNext; // for internal use, should be NULL in public -} netpacket_t; -#pragma pack(pop) - -struct UnconnectedPlayerSendData -{ - char ip[16]; - double lastQuotaStart = 0.0; - int packetCount = 0; - double timeoutEnd = -1.0; -}; - -class ServerAuthenticationManager -{ - private: - httplib::Server m_playerAuthServer; - - public: - std::mutex m_authDataMutex; - std::unordered_map<std::string, AuthData> m_authData; - std::unordered_map<void*, AdditionalPlayerData> m_additionalPlayerData; - std::vector<UnconnectedPlayerSendData> m_unconnectedPlayerSendData; - bool m_runningPlayerAuthThread = false; - bool m_bNeedLocalAuthForNewgame = false; - bool m_bForceReadLocalPlayerPersistenceFromDisk = false; - - public: - void StartPlayerAuthServer(); - void StopPlayerAuthServer(); - bool AuthenticatePlayer(void* player, int64_t uid, char* authToken); - char* VerifyPlayerName(void* player, char* authToken, char* name); - bool RemovePlayerAuthData(void* player); - void WritePersistentData(void* player); - bool CheckPlayerChatRatelimit(void* player); -}; - -typedef void (*CBaseClient__DisconnectType)(void* self, uint32_t unknownButAlways1, const char* reason, ...); -extern CBaseClient__DisconnectType CBaseClient__Disconnect; - -void InitialiseServerAuthentication(HMODULE baseAddress); - -extern ServerAuthenticationManager* g_ServerAuthenticationManager; -extern ConVar* Cvar_ns_player_auth_port; diff --git a/NorthstarDedicatedTest/serverchathooks.cpp b/NorthstarDedicatedTest/serverchathooks.cpp deleted file mode 100644 index 985d3d1b..00000000 --- a/NorthstarDedicatedTest/serverchathooks.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "pch.h" -#include "serverchathooks.h" -#include <rapidjson/document.h> -#include <rapidjson/stringbuffer.h> -#include <rapidjson/writer.h> -#include "serverauthentication.h" -#include "squirrel.h" -#include "miscserverscript.h" - -class CServerGameDLL; -class CBasePlayer; - -class CRecipientFilter -{ - char unknown[58]; -}; - -CServerGameDLL* g_pServerGameDLL; - -typedef void(__fastcall* CServerGameDLL__OnReceivedSayTextMessageType)( - CServerGameDLL* self, unsigned int senderPlayerId, const char* text, int channelId); -CServerGameDLL__OnReceivedSayTextMessageType CServerGameDLL__OnReceivedSayTextMessage; -CServerGameDLL__OnReceivedSayTextMessageType CServerGameDLL__OnReceivedSayTextMessageHookBase; - -typedef CBasePlayer*(__fastcall* UTIL_PlayerByIndexType)(int playerIndex); -UTIL_PlayerByIndexType UTIL_PlayerByIndex; - -typedef void(__fastcall* CRecipientFilter__ConstructType)(CRecipientFilter* self); -CRecipientFilter__ConstructType CRecipientFilter__Construct; - -typedef void(__fastcall* CRecipientFilter__DestructType)(CRecipientFilter* self); -CRecipientFilter__DestructType CRecipientFilter__Destruct; - -typedef void(__fastcall* CRecipientFilter__AddAllPlayersType)(CRecipientFilter* self); -CRecipientFilter__AddAllPlayersType CRecipientFilter__AddAllPlayers; - -typedef void(__fastcall* CRecipientFilter__AddRecipientType)(CRecipientFilter* self, const CBasePlayer* player); -CRecipientFilter__AddRecipientType CRecipientFilter__AddRecipient; - -typedef void(__fastcall* CRecipientFilter__MakeReliableType)(CRecipientFilter* self); -CRecipientFilter__MakeReliableType CRecipientFilter__MakeReliable; - -typedef void(__fastcall* UserMessageBeginType)(CRecipientFilter* filter, const char* messagename); -UserMessageBeginType UserMessageBegin; - -typedef void(__fastcall* MessageEndType)(); -MessageEndType MessageEnd; - -typedef void(__fastcall* MessageWriteByteType)(int iValue); -MessageWriteByteType MessageWriteByte; - -typedef void(__fastcall* MessageWriteStringType)(const char* sz); -MessageWriteStringType MessageWriteString; - -typedef void(__fastcall* MessageWriteBoolType)(bool bValue); -MessageWriteBoolType MessageWriteBool; - -bool isSkippingHook = false; - -static void CServerGameDLL__OnReceivedSayTextMessageHook(CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam) -{ - // MiniHook doesn't allow calling the base function outside of anywhere but the hook function. - // To allow bypassing the hook, isSkippingHook can be set. - if (isSkippingHook) - { - isSkippingHook = false; - CServerGameDLL__OnReceivedSayTextMessageHookBase(self, senderPlayerId, text, isTeam); - return; - } - - void* sender = GetPlayerByIndex(senderPlayerId - 1); - - // check chat ratelimits - if (!g_ServerAuthenticationManager->CheckPlayerChatRatelimit(sender)) - { - return; - } - - if (g_ServerSquirrelManager->setupfunc("CServerGameDLL_ProcessMessageStartThread") != SQRESULT_ERROR) - { - g_ServerSquirrelManager->pusharg((int)senderPlayerId - 1); - g_ServerSquirrelManager->pusharg(text); - g_ServerSquirrelManager->pusharg(isTeam); - g_ServerSquirrelManager->call(3); - } - else - CServerGameDLL__OnReceivedSayTextMessageHookBase(self, senderPlayerId, text, isTeam); -} - -void ChatSendMessage(unsigned int playerIndex, const char* text, bool isteam) -{ - isSkippingHook = true; - CServerGameDLL__OnReceivedSayTextMessage( - g_pServerGameDLL, - // Ensure the first bit isn't set, since this indicates a custom message - (playerIndex + 1) & CUSTOM_MESSAGE_INDEX_MASK, - text, - isteam); -} - -void ChatBroadcastMessage(int fromPlayerIndex, int toPlayerIndex, const char* text, bool isTeam, bool isDead, CustomMessageType messageType) -{ - CBasePlayer* toPlayer = NULL; - if (toPlayerIndex >= 0) - { - toPlayer = UTIL_PlayerByIndex(toPlayerIndex + 1); - if (toPlayer == NULL) - return; - } - - // Build a new string where the first byte is the message type - char sendText[256]; - sendText[0] = (char)messageType; - strncpy(sendText + 1, text, 255); - sendText[255] = 0; - - // Anonymous custom messages use playerId=0, non-anonymous ones use a player ID with the first bit set - unsigned int fromPlayerId = fromPlayerIndex < 0 ? 0 : ((fromPlayerIndex + 1) | CUSTOM_MESSAGE_INDEX_BIT); - - CRecipientFilter filter; - CRecipientFilter__Construct(&filter); - if (toPlayer == NULL) - { - CRecipientFilter__AddAllPlayers(&filter); - } - else - { - CRecipientFilter__AddRecipient(&filter, toPlayer); - } - CRecipientFilter__MakeReliable(&filter); - - UserMessageBegin(&filter, "SayText"); - MessageWriteByte(fromPlayerId); - MessageWriteString(sendText); - MessageWriteBool(isTeam); - MessageWriteBool(isDead); - MessageEnd(); - - CRecipientFilter__Destruct(&filter); -} - -SQRESULT SQ_SendMessage(void* sqvm) -{ - int playerIndex = ServerSq_getinteger(sqvm, 1); - const char* text = ServerSq_getstring(sqvm, 2); - bool isTeam = ServerSq_getbool(sqvm, 3); - - ChatSendMessage(playerIndex, text, isTeam); - - return SQRESULT_NULL; -} - -SQRESULT SQ_BroadcastMessage(void* sqvm) -{ - int fromPlayerIndex = ServerSq_getinteger(sqvm, 1); - int toPlayerIndex = ServerSq_getinteger(sqvm, 2); - const char* text = ServerSq_getstring(sqvm, 3); - bool isTeam = ServerSq_getbool(sqvm, 4); - bool isDead = ServerSq_getbool(sqvm, 5); - int messageType = ServerSq_getinteger(sqvm, 6); - - if (messageType < 1) - { - ServerSq_pusherror(sqvm, fmt::format("Invalid message type {}", messageType).c_str()); - return SQRESULT_ERROR; - } - - ChatBroadcastMessage(fromPlayerIndex, toPlayerIndex, text, isTeam, isDead, (CustomMessageType)messageType); - - return SQRESULT_NULL; -} - -void InitialiseServerChatHooks_Engine(HMODULE baseAddress) -{ - g_pServerGameDLL = (CServerGameDLL*)((char*)baseAddress + 0x13F0AA98); -} - -void InitialiseServerChatHooks_Server(HMODULE baseAddress) -{ - CServerGameDLL__OnReceivedSayTextMessage = (CServerGameDLL__OnReceivedSayTextMessageType)((char*)baseAddress + 0x1595C0); - UTIL_PlayerByIndex = (UTIL_PlayerByIndexType)((char*)baseAddress + 0x26AA10); - CRecipientFilter__Construct = (CRecipientFilter__ConstructType)((char*)baseAddress + 0x1E9440); - CRecipientFilter__Destruct = (CRecipientFilter__DestructType)((char*)baseAddress + 0x1E9700); - CRecipientFilter__AddAllPlayers = (CRecipientFilter__AddAllPlayersType)((char*)baseAddress + 0x1E9940); - CRecipientFilter__AddRecipient = (CRecipientFilter__AddRecipientType)((char*)baseAddress + 0x1E9b30); - CRecipientFilter__MakeReliable = (CRecipientFilter__MakeReliableType)((char*)baseAddress + 0x1EA4E0); - - UserMessageBegin = (UserMessageBeginType)((char*)baseAddress + 0x15C520); - MessageEnd = (MessageEndType)((char*)baseAddress + 0x158880); - MessageWriteByte = (MessageWriteByteType)((char*)baseAddress + 0x158A90); - MessageWriteString = (MessageWriteStringType)((char*)baseAddress + 0x158D00); - MessageWriteBool = (MessageWriteBoolType)((char*)baseAddress + 0x158A00); - - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, - CServerGameDLL__OnReceivedSayTextMessage, - &CServerGameDLL__OnReceivedSayTextMessageHook, - reinterpret_cast<LPVOID*>(&CServerGameDLL__OnReceivedSayTextMessageHookBase)); - - // Chat sending functions - g_ServerSquirrelManager->AddFuncRegistration("void", "NSSendMessage", "int playerIndex, string text, bool isTeam", "", SQ_SendMessage); - g_ServerSquirrelManager->AddFuncRegistration( - "void", - "NSBroadcastMessage", - "int fromPlayerIndex, int toPlayerIndex, string text, bool isTeam, bool isDead, int messageType", - "", - SQ_BroadcastMessage); -} diff --git a/NorthstarDedicatedTest/sigscanning.cpp b/NorthstarDedicatedTest/sigscanning.cpp deleted file mode 100644 index 761f9f08..00000000 --- a/NorthstarDedicatedTest/sigscanning.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "pch.h" -#include "sigscanning.h" -#include <map> - -// note: sigscanning is only really intended to be used for resolving stuff like shared function definitions -// we mostly use raw function addresses for stuff - -size_t GetModuleLength(HMODULE moduleHandle) -{ - // based on sigscn code from ttf2sdk, which is in turn based on CSigScan from https://wiki.alliedmods.net/Signature_Scanning - MEMORY_BASIC_INFORMATION mem; - VirtualQuery(moduleHandle, &mem, sizeof(mem)); - - IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)mem.AllocationBase; - IMAGE_NT_HEADERS* pe = (IMAGE_NT_HEADERS*)((unsigned char*)dos + dos->e_lfanew); - - return pe->OptionalHeader.SizeOfImage; -} - -void* FindSignature(std::string dllName, const char* sig, const char* mask) -{ - HMODULE module = GetModuleHandleA(dllName.c_str()); - - unsigned char* dllAddress = (unsigned char*)module; - unsigned char* dllEnd = dllAddress + GetModuleLength(module); - - size_t sigLength = strlen(mask); - - for (auto i = dllAddress; i < dllEnd - sigLength + 1; i++) - { - int j = 0; - for (; j < sigLength; j++) - if (mask[j] != '?' && sig[j] != i[j]) - break; - - if (j == sigLength) // loop finished of its own accord - return i; - } - - return nullptr; -} diff --git a/NorthstarDedicatedTest/sigscanning.h b/NorthstarDedicatedTest/sigscanning.h deleted file mode 100644 index 56979fbc..00000000 --- a/NorthstarDedicatedTest/sigscanning.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include <string> - -// note: sigscanning is only really intended to be used for resolving stuff like shared function definitions -// we mostly use raw function addresses for stuff - -void* FindSignature(std::string dllName, const char* sig, const char* mask);
\ No newline at end of file diff --git a/NorthstarDedicatedTest/sourceconsole.cpp b/NorthstarDedicatedTest/sourceconsole.cpp deleted file mode 100644 index a6d54989..00000000 --- a/NorthstarDedicatedTest/sourceconsole.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "pch.h" -#include "convar.h" -#include "sourceconsole.h" -#include "sourceinterface.h" -#include "concommand.h" -#include "hookutils.h" - -SourceInterface<CGameConsole>* g_SourceGameConsole; - -void ConCommand_toggleconsole(const CCommand& arg) -{ - if ((*g_SourceGameConsole)->IsConsoleVisible()) - (*g_SourceGameConsole)->Hide(); - else - (*g_SourceGameConsole)->Activate(); -} - -typedef void (*OnCommandSubmittedType)(CConsoleDialog* consoleDialog, const char* pCommand); -OnCommandSubmittedType onCommandSubmittedOriginal; -void OnCommandSubmittedHook(CConsoleDialog* consoleDialog, const char* pCommand) -{ - consoleDialog->m_pConsolePanel->Print("] "); - consoleDialog->m_pConsolePanel->Print(pCommand); - consoleDialog->m_pConsolePanel->Print("\n"); - - // todo: call the help command in the future - - onCommandSubmittedOriginal(consoleDialog, pCommand); -} - -// called from sourceinterface.cpp in client createinterface hooks, on GameClientExports001 -void InitialiseConsoleOnInterfaceCreation() -{ - (*g_SourceGameConsole)->Initialize(); - - auto consoleLogger = std::make_shared<SourceConsoleSink>(); - consoleLogger->set_pattern("[%l] %v"); - - spdlog::default_logger()->sinks().push_back(consoleLogger); - - // hook OnCommandSubmitted so we print inputted commands - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, - (void*)((*g_SourceGameConsole)->m_pConsole->m_vtable->OnCommandSubmitted), - &OnCommandSubmittedHook, - reinterpret_cast<LPVOID*>(&onCommandSubmittedOriginal)); -} - -void InitialiseSourceConsole(HMODULE baseAddress) -{ - g_SourceGameConsole = new SourceInterface<CGameConsole>("client.dll", "GameConsole004"); - RegisterConCommand("toggleconsole", ConCommand_toggleconsole, "toggles the console", FCVAR_DONTRECORD); -} - -// logging stuff - -SourceConsoleSink::SourceConsoleSink() -{ - logColours.emplace(spdlog::level::trace, SourceColor(0, 255, 255, 255)); - logColours.emplace(spdlog::level::debug, SourceColor(0, 255, 255, 255)); - logColours.emplace(spdlog::level::info, SourceColor(255, 255, 255, 255)); - logColours.emplace(spdlog::level::warn, SourceColor(255, 255, 0, 255)); - logColours.emplace(spdlog::level::err, SourceColor(255, 0, 0, 255)); - logColours.emplace(spdlog::level::critical, SourceColor(255, 0, 0, 255)); - logColours.emplace(spdlog::level::off, SourceColor(0, 0, 0, 0)); -} - -void SourceConsoleSink::sink_it_(const spdlog::details::log_msg& msg) -{ - if (!(*g_SourceGameConsole)->m_bInitialized) - return; - - spdlog::memory_buf_t formatted; - spdlog::sinks::base_sink<std::mutex>::formatter_->format(msg, formatted); - (*g_SourceGameConsole) - ->m_pConsole->m_pConsolePanel->ColorPrint(logColours[msg.level], fmt::to_string(formatted).c_str()); // todo needs colour support -} - -void SourceConsoleSink::flush_() {}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/sourceinterface.cpp b/NorthstarDedicatedTest/sourceinterface.cpp deleted file mode 100644 index 2cc4733d..00000000 --- a/NorthstarDedicatedTest/sourceinterface.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "pch.h" -#include "sourceinterface.h" -#include "hooks.h" -#include "hookutils.h" - -#include "sourceconsole.h" -#include "context.h" -#include "convar.h" -#include <iostream> - -// really wanted to do a modular callback system here but honestly couldn't be bothered so hardcoding stuff for now: todo later - -CreateInterfaceFn clientCreateInterfaceOriginal; -void* ClientCreateInterfaceHook(const char* pName, int* pReturnCode) -{ - void* ret = clientCreateInterfaceOriginal(pName, pReturnCode); - - spdlog::info("CreateInterface CLIENT {}", pName); - if (!strcmp(pName, "GameClientExports001")) - InitialiseConsoleOnInterfaceCreation(); - - return ret; -} - -CreateInterfaceFn serverCreateInterfaceOriginal; -void* ServerCreateInterfaceHook(const char* pName, int* pReturnCode) -{ - void* ret = serverCreateInterfaceOriginal(pName, pReturnCode); - - std::cout << "CreateInterface SERVER " << pName << std::endl; - - return ret; -} - -CreateInterfaceFn engineCreateInterfaceOriginal; -void* EngineCreateInterfaceHook(const char* pName, int* pReturnCode) -{ - void* ret = engineCreateInterfaceOriginal(pName, pReturnCode); - - std::cout << "CreateInterface ENGINE " << pName << std::endl; - - return ret; -} - -void HookClientCreateInterface(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, - GetProcAddress(baseAddress, "CreateInterface"), - &ClientCreateInterfaceHook, - reinterpret_cast<LPVOID*>(&clientCreateInterfaceOriginal)); -} - -void HookServerCreateInterface(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, - GetProcAddress(baseAddress, "CreateInterface"), - &ServerCreateInterfaceHook, - reinterpret_cast<LPVOID*>(&serverCreateInterfaceOriginal)); -} - -void HookEngineCreateInterface(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK( - hook, - GetProcAddress(baseAddress, "CreateInterface"), - &EngineCreateInterfaceHook, - reinterpret_cast<LPVOID*>(&engineCreateInterfaceOriginal)); -} - -void InitialiseInterfaceCreationHooks() -{ - AddDllLoadCallback("client.dll", HookClientCreateInterface); - - // not used atm - // AddDllLoadCallback("server.dll", HookServerCreateInterface); - // AddDllLoadCallback("engine.dll", HookEngineCreateInterface); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp deleted file mode 100644 index 84caa389..00000000 --- a/NorthstarDedicatedTest/squirrel.cpp +++ /dev/null @@ -1,450 +0,0 @@ -#include "pch.h" -#include "squirrel.h" -#include "hooks.h" -#include "hookutils.h" -#include "sigscanning.h" -#include "concommand.h" -#include "modmanager.h" -#include <iostream> - -// hook forward declarations -typedef SQInteger (*SQPrintType)(void* sqvm, char* fmt, ...); -SQPrintType ClientSQPrint; -SQPrintType UISQPrint; -SQPrintType ServerSQPrint; -template <ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...); - -typedef void* (*CreateNewVMType)(void* a1, ScriptContext contextArg); -CreateNewVMType ClientCreateNewVM; // only need a client one since ui doesn't have its own func for this -CreateNewVMType ServerCreateNewVM; -template <ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext contextArg); - -typedef void (*DestroyVMType)(void* a1, void* sqvm); -DestroyVMType ClientDestroyVM; // only need a client one since ui doesn't have its own func for this -DestroyVMType ServerDestroyVM; -template <ScriptContext context> void DestroyVMHook(void* a1, void* sqvm); - -typedef void (*ScriptCompileError)(void* sqvm, const char* error, const char* file, int line, int column); -ScriptCompileError ClientSQCompileError; // only need a client one since ui doesn't have its own func for this -ScriptCompileError ServerSQCompileError; -template <ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column); - -typedef char (*CallScriptInitCallbackType)(void* sqvm, const char* callback); -CallScriptInitCallbackType ClientCallScriptInitCallback; -CallScriptInitCallbackType ServerCallScriptInitCallback; -template <ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, const char* callback); - -// core sqvm funcs -sq_compilebufferType ClientSq_compilebuffer; -sq_compilebufferType ServerSq_compilebuffer; - -sq_pushroottableType ClientSq_pushroottable; -sq_pushroottableType ServerSq_pushroottable; - -sq_callType ClientSq_call; -sq_callType ServerSq_call; - -RegisterSquirrelFuncType ClientRegisterSquirrelFunc; -RegisterSquirrelFuncType ServerRegisterSquirrelFunc; - -// sq stack array funcs -sq_newarrayType ClientSq_newarray; -sq_newarrayType ServerSq_newarray; - -sq_arrayappendType ClientSq_arrayappend; -sq_arrayappendType ServerSq_arrayappend; - -// sq stack push funcs -sq_pushstringType ClientSq_pushstring; -sq_pushstringType ServerSq_pushstring; - -sq_pushintegerType ClientSq_pushinteger; -sq_pushintegerType ServerSq_pushinteger; - -sq_pushfloatType ClientSq_pushfloat; -sq_pushfloatType ServerSq_pushfloat; - -sq_pushboolType ClientSq_pushbool; -sq_pushboolType ServerSq_pushbool; - -sq_pusherrorType ClientSq_pusherror; -sq_pusherrorType ServerSq_pusherror; - -// sq stack get funcs -sq_getstringType ClientSq_getstring; -sq_getstringType ServerSq_getstring; - -sq_getintegerType ClientSq_getinteger; -sq_getintegerType ServerSq_getinteger; - -sq_getfloatType ClientSq_getfloat; -sq_getfloatType ServerSq_getfloat; - -sq_getboolType ClientSq_getbool; -sq_getboolType ServerSq_getbool; - -sq_getType ClientSq_sq_get; -sq_getType ServerSq_sq_get; - -template <ScriptContext context> void ExecuteCodeCommand(const CCommand& args); - -// inits -SquirrelManager<ScriptContext::CLIENT>* g_ClientSquirrelManager; -SquirrelManager<ScriptContext::SERVER>* g_ServerSquirrelManager; -SquirrelManager<ScriptContext::UI>* g_UISquirrelManager; - -SQInteger NSTestFunc(void* sqvm) -{ - return 1; -} - -void InitialiseClientSquirrel(HMODULE baseAddress) -{ - HookEnabler hook; - - // client inits - g_ClientSquirrelManager = new SquirrelManager<ScriptContext::CLIENT>(); - - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x12B00, - &SQPrintHook<ScriptContext::CLIENT>, - reinterpret_cast<LPVOID*>(&ClientSQPrint)); // client print function - RegisterConCommand( - "script_client", ExecuteCodeCommand<ScriptContext::CLIENT>, "Executes script code on the client vm", FCVAR_CLIENTDLL); - - // ui inits - g_UISquirrelManager = new SquirrelManager<ScriptContext::UI>(); - - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x12BA0, &SQPrintHook<ScriptContext::UI>, reinterpret_cast<LPVOID*>(&UISQPrint)); // ui print function - RegisterConCommand("script_ui", ExecuteCodeCommand<ScriptContext::UI>, "Executes script code on the ui vm", FCVAR_CLIENTDLL); - - // inits for both client and ui, since they share some functions - ClientSq_compilebuffer = (sq_compilebufferType)((char*)baseAddress + 0x3110); - ClientSq_pushroottable = (sq_pushroottableType)((char*)baseAddress + 0x5860); - ClientSq_call = (sq_callType)((char*)baseAddress + 0x8650); - ClientRegisterSquirrelFunc = (RegisterSquirrelFuncType)((char*)baseAddress + 0x108E0); - - ClientSq_newarray = (sq_newarrayType)((char*)baseAddress + 0x39F0); - ClientSq_arrayappend = (sq_arrayappendType)((char*)baseAddress + 0x3C70); - - ClientSq_pushstring = (sq_pushstringType)((char*)baseAddress + 0x3440); - ClientSq_pushinteger = (sq_pushintegerType)((char*)baseAddress + 0x36A0); - ClientSq_pushfloat = (sq_pushfloatType)((char*)baseAddress + 0x3800); - ClientSq_pushbool = (sq_pushboolType)((char*)baseAddress + 0x3710); - ClientSq_pusherror = (sq_pusherrorType)((char*)baseAddress + 0x8470); - - ClientSq_getstring = (sq_getstringType)((char*)baseAddress + 0x60C0); - ClientSq_getinteger = (sq_getintegerType)((char*)baseAddress + 0x60E0); - ClientSq_getfloat = (sq_getfloatType)((char*)baseAddress + 0x6100); - ClientSq_getbool = (sq_getboolType)((char*)baseAddress + 0x6130); - - ClientSq_sq_get = (sq_getType)((char*)baseAddress + 0x7C30); - - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x26130, - &CreateNewVMHook<ScriptContext::CLIENT>, - reinterpret_cast<LPVOID*>(&ClientCreateNewVM)); // client createnewvm function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x26E70, - &DestroyVMHook<ScriptContext::CLIENT>, - reinterpret_cast<LPVOID*>(&ClientDestroyVM)); // client destroyvm function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x79A50, - &ScriptCompileErrorHook<ScriptContext::CLIENT>, - reinterpret_cast<LPVOID*>(&ClientSQCompileError)); // client compileerror function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x10190, - &CallScriptInitCallbackHook<ScriptContext::CLIENT>, - reinterpret_cast<LPVOID*>(&ClientCallScriptInitCallback)); // client callscriptinitcallback function -} - -void InitialiseServerSquirrel(HMODULE baseAddress) -{ - g_ServerSquirrelManager = new SquirrelManager<ScriptContext::SERVER>(); - - HookEnabler hook; - - ServerSq_compilebuffer = (sq_compilebufferType)((char*)baseAddress + 0x3110); - ServerSq_pushroottable = (sq_pushroottableType)((char*)baseAddress + 0x5840); - ServerSq_call = (sq_callType)((char*)baseAddress + 0x8620); - ServerRegisterSquirrelFunc = (RegisterSquirrelFuncType)((char*)baseAddress + 0x1DD10); - - ServerSq_newarray = (sq_newarrayType)((char*)baseAddress + 0x39F0); - ServerSq_arrayappend = (sq_arrayappendType)((char*)baseAddress + 0x3C70); - - ServerSq_pushstring = (sq_pushstringType)((char*)baseAddress + 0x3440); - ServerSq_pushinteger = (sq_pushintegerType)((char*)baseAddress + 0x36A0); - ServerSq_pushfloat = (sq_pushfloatType)((char*)baseAddress + 0x3800); - ServerSq_pushbool = (sq_pushboolType)((char*)baseAddress + 0x3710); - ServerSq_pusherror = (sq_pusherrorType)((char*)baseAddress + 0x8440); - - ServerSq_getstring = (sq_getstringType)((char*)baseAddress + 0x60A0); - ServerSq_getinteger = (sq_getintegerType)((char*)baseAddress + 0x60C0); - ServerSq_getfloat = (sq_getfloatType)((char*)baseAddress + 0x60E0); - ServerSq_getbool = (sq_getboolType)((char*)baseAddress + 0x6110); - - ServerSq_sq_get = (sq_getType)((char*)baseAddress + 0x7C00); - - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x1FE90, - &SQPrintHook<ScriptContext::SERVER>, - reinterpret_cast<LPVOID*>(&ServerSQPrint)); // server print function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x260E0, - &CreateNewVMHook<ScriptContext::SERVER>, - reinterpret_cast<LPVOID*>(&ServerCreateNewVM)); // server createnewvm function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x26E20, - &DestroyVMHook<ScriptContext::SERVER>, - reinterpret_cast<LPVOID*>(&ServerDestroyVM)); // server destroyvm function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x799E0, - &ScriptCompileErrorHook<ScriptContext::SERVER>, - reinterpret_cast<LPVOID*>(&ServerSQCompileError)); // server compileerror function - ENABLER_CREATEHOOK( - hook, - (char*)baseAddress + 0x1D5C0, - &CallScriptInitCallbackHook<ScriptContext::SERVER>, - reinterpret_cast<LPVOID*>(&ServerCallScriptInitCallback)); // server callscriptinitcallback function - - // cheat and clientcmd_can_execute allows clients to execute this, but since it's unsafe we only allow it when cheats are enabled - // for script_client and script_ui, we don't use cheats, so clients can execute them on themselves all they want - RegisterConCommand( - "script", - ExecuteCodeCommand<ScriptContext::SERVER>, - "Executes script code on the server vm", - FCVAR_GAMEDLL | FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_CHEAT); -} - -// hooks -template <ScriptContext context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...) -{ - va_list va; - va_start(va, fmt); - - SQChar buf[1024]; - int charsWritten = vsnprintf_s(buf, _TRUNCATE, fmt, va); - - if (charsWritten > 0) - { - if (buf[charsWritten - 1] == '\n') - buf[charsWritten - 1] = '\0'; - - spdlog::info("[{} SCRIPT] {}", GetContextName(context), buf); - } - - va_end(va); - return 0; -} - -template <ScriptContext context> void* CreateNewVMHook(void* a1, ScriptContext realContext) -{ - void* sqvm; - - if (context == ScriptContext::CLIENT) - { - sqvm = ClientCreateNewVM(a1, realContext); - - if (realContext == ScriptContext::UI) - g_UISquirrelManager->VMCreated(sqvm); - else - g_ClientSquirrelManager->VMCreated(sqvm); - } - else if (context == ScriptContext::SERVER) - { - sqvm = ServerCreateNewVM(a1, context); - g_ServerSquirrelManager->VMCreated(sqvm); - } - - spdlog::info("CreateNewVM {} {}", GetContextName(realContext), sqvm); - return sqvm; -} - -template <ScriptContext context> void DestroyVMHook(void* a1, void* sqvm) -{ - ScriptContext realContext = context; // ui and client use the same function so we use this for prints - - if (context == ScriptContext::CLIENT) - { - if (g_ClientSquirrelManager->sqvm == sqvm) - g_ClientSquirrelManager->VMDestroyed(); - else if (g_UISquirrelManager->sqvm == sqvm) - { - g_UISquirrelManager->VMDestroyed(); - realContext = ScriptContext::UI; - } - - ClientDestroyVM(a1, sqvm); - } - else if (context == ScriptContext::SERVER) - { - g_ServerSquirrelManager->VMDestroyed(); - ServerDestroyVM(a1, sqvm); - } - - spdlog::info("DestroyVM {} {}", GetContextName(realContext), sqvm); -} - -template <ScriptContext context> void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column) -{ - ScriptContext realContext = context; // ui and client use the same function so we use this for prints - if (context == ScriptContext::CLIENT && sqvm == g_UISquirrelManager->sqvm) - realContext = ScriptContext::UI; - - spdlog::error("{} SCRIPT COMPILE ERROR {}", GetContextName(realContext), error); - spdlog::error("{} line [{}] column [{}]", file, line, column); - - // dont call the original since it kills game - // in the future it'd be nice to do an actual error with UICodeCallback_ErrorDialog here, but only if we're compiling level scripts - // compilestring and stuff shouldn't tho - // though, that also has potential to be REALLY bad if we're compiling ui scripts lol -} - -template <ScriptContext context> char CallScriptInitCallbackHook(void* sqvm, const char* callback) -{ - char ret; - - if (context == ScriptContext::CLIENT) - { - ScriptContext realContext = context; // ui and client use the same function so we use this for prints - bool shouldCallCustomCallbacks = false; - - // since we don't hook arbitrary callbacks yet, make sure we're only doing callbacks on inits - if (!strcmp(callback, "UICodeCallback_UIInit")) - { - realContext = ScriptContext::UI; - shouldCallCustomCallbacks = true; - } - else if (!strcmp(callback, "ClientCodeCallback_MapSpawn")) - shouldCallCustomCallbacks = true; - - // run before callbacks - // todo: we need to verify if RunOn is valid for current state before calling callbacks - if (shouldCallCustomCallbacks) - { - for (Mod mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - for (ModScript script : mod.Scripts) - { - for (ModScriptCallback modCallback : script.Callbacks) - { - if (modCallback.Context == realContext && modCallback.BeforeCallback.length()) - { - spdlog::info( - "Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.BeforeCallback); - ClientCallScriptInitCallback(sqvm, modCallback.BeforeCallback.c_str()); - } - } - } - } - } - - spdlog::info("{} CodeCallback {} called", GetContextName(realContext), callback); - if (!shouldCallCustomCallbacks) - spdlog::info("Not executing custom callbacks for CodeCallback {}", callback); - ret = ClientCallScriptInitCallback(sqvm, callback); - - // run after callbacks - if (shouldCallCustomCallbacks) - { - for (Mod mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - for (ModScript script : mod.Scripts) - { - for (ModScriptCallback modCallback : script.Callbacks) - { - if (modCallback.Context == realContext && modCallback.AfterCallback.length()) - { - spdlog::info( - "Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.AfterCallback); - ClientCallScriptInitCallback(sqvm, modCallback.AfterCallback.c_str()); - } - } - } - } - } - } - else if (context == ScriptContext::SERVER) - { - // since we don't hook arbitrary callbacks yet, make sure we're only doing callbacks on inits - bool shouldCallCustomCallbacks = !strcmp(callback, "CodeCallback_MapSpawn"); - - // run before callbacks - // todo: we need to verify if RunOn is valid for current state before calling callbacks - if (shouldCallCustomCallbacks) - { - for (Mod mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - for (ModScript script : mod.Scripts) - { - for (ModScriptCallback modCallback : script.Callbacks) - { - if (modCallback.Context == ScriptContext::SERVER && modCallback.BeforeCallback.length()) - { - spdlog::info("Running custom {} script callback \"{}\"", GetContextName(context), modCallback.BeforeCallback); - ServerCallScriptInitCallback(sqvm, modCallback.BeforeCallback.c_str()); - } - } - } - } - } - - spdlog::info("{} CodeCallback {} called", GetContextName(context), callback); - if (!shouldCallCustomCallbacks) - spdlog::info("Not executing custom callbacks for CodeCallback {}", callback); - ret = ServerCallScriptInitCallback(sqvm, callback); - - // run after callbacks - if (shouldCallCustomCallbacks) - { - for (Mod mod : g_ModManager->m_loadedMods) - { - if (!mod.Enabled) - continue; - - for (ModScript script : mod.Scripts) - { - for (ModScriptCallback modCallback : script.Callbacks) - { - if (modCallback.Context == ScriptContext::SERVER && modCallback.AfterCallback.length()) - { - spdlog::info("Running custom {} script callback \"{}\"", GetContextName(context), modCallback.AfterCallback); - ServerCallScriptInitCallback(sqvm, modCallback.AfterCallback.c_str()); - } - } - } - } - } - } - - return ret; -} - -template <ScriptContext context> void ExecuteCodeCommand(const CCommand& args) -{ - if (context == ScriptContext::CLIENT) - g_ClientSquirrelManager->ExecuteCode(args.ArgS()); - else if (context == ScriptContext::UI) - g_UISquirrelManager->ExecuteCode(args.ArgS()); - else if (context == ScriptContext::SERVER) - g_ServerSquirrelManager->ExecuteCode(args.ArgS()); -}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h deleted file mode 100644 index cc39cc2a..00000000 --- a/NorthstarDedicatedTest/squirrel.h +++ /dev/null @@ -1,294 +0,0 @@ -#pragma once - -void InitialiseClientSquirrel(HMODULE baseAddress); -void InitialiseServerSquirrel(HMODULE baseAddress); - -// stolen from ttf2sdk: sqvm types -typedef float SQFloat; -typedef long SQInteger; -typedef unsigned long SQUnsignedInteger; -typedef char SQChar; - -typedef SQUnsignedInteger SQBool; -typedef SQInteger SQRESULT; - -const SQRESULT SQRESULT_ERROR = -1; -const SQRESULT SQRESULT_NULL = 0; -const SQRESULT SQRESULT_NOTNULL = 1; - -typedef SQInteger (*SQFunction)(void* sqvm); - -struct CompileBufferState -{ - const SQChar* buffer; - const SQChar* bufferPlusLength; - const SQChar* bufferAgain; - - CompileBufferState(const std::string& code) - { - buffer = code.c_str(); - bufferPlusLength = code.c_str() + code.size(); - bufferAgain = code.c_str(); - } -}; - -struct SQFuncRegistration -{ - const char* squirrelFuncName; - const char* cppFuncName; - const char* helpText; - const char* returnValueType; - const char* argTypes; - int16_t somethingThatsZero; - int16_t padding1; - int32_t unknown1; - int64_t unknown2; - int32_t unknown3; - int32_t padding2; - int64_t unknown4; - int64_t unknown5; - int64_t unknown6; - int32_t unknown7; - int32_t padding3; - void* funcPtr; - - SQFuncRegistration() - { - memset(this, 0, sizeof(SQFuncRegistration)); - this->padding2 = 32; - } -}; - -// core sqvm funcs -typedef SQRESULT (*sq_compilebufferType)(void* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, ScriptContext a2); -extern sq_compilebufferType ClientSq_compilebuffer; -extern sq_compilebufferType ServerSq_compilebuffer; - -typedef void (*sq_pushroottableType)(void* sqvm); -extern sq_pushroottableType ClientSq_pushroottable; -extern sq_pushroottableType ServerSq_pushroottable; - -typedef SQRESULT (*sq_callType)(void* sqvm, SQInteger s1, SQBool a2, SQBool a3); -extern sq_callType ClientSq_call; -extern sq_callType ServerSq_call; - -typedef int64_t (*RegisterSquirrelFuncType)(void* sqvm, SQFuncRegistration* funcReg, char unknown); -extern RegisterSquirrelFuncType ClientRegisterSquirrelFunc; -extern RegisterSquirrelFuncType ServerRegisterSquirrelFunc; - -// sq stack array funcs -typedef void (*sq_newarrayType)(void* sqvm, SQInteger stackpos); -extern sq_newarrayType ClientSq_newarray; -extern sq_newarrayType ServerSq_newarray; - -typedef SQRESULT (*sq_arrayappendType)(void* sqvm, SQInteger stackpos); -extern sq_arrayappendType ClientSq_arrayappend; -extern sq_arrayappendType ServerSq_arrayappend; - -// sq stack push funcs -typedef void (*sq_pushstringType)(void* sqvm, const SQChar* str, SQInteger stackpos); -extern sq_pushstringType ClientSq_pushstring; -extern sq_pushstringType ServerSq_pushstring; - -// weird how these don't take a stackpos arg? -typedef void (*sq_pushintegerType)(void* sqvm, SQInteger i); -extern sq_pushintegerType ClientSq_pushinteger; -extern sq_pushintegerType ServerSq_pushinteger; - -typedef void (*sq_pushfloatType)(void* sqvm, SQFloat f); -extern sq_pushfloatType ClientSq_pushfloat; -extern sq_pushfloatType ServerSq_pushfloat; - -typedef void (*sq_pushboolType)(void* sqvm, SQBool b); -extern sq_pushboolType ClientSq_pushbool; -extern sq_pushboolType ServerSq_pushbool; - -typedef SQInteger (*sq_pusherrorType)(void* sqvm, const SQChar* error); -extern sq_pusherrorType ClientSq_pusherror; -extern sq_pusherrorType ServerSq_pusherror; - -// sq stack get funcs -typedef const SQChar* (*sq_getstringType)(void* sqvm, SQInteger stackpos); -extern sq_getstringType ClientSq_getstring; -extern sq_getstringType ServerSq_getstring; - -typedef SQInteger (*sq_getintegerType)(void* sqvm, SQInteger stackpos); -extern sq_getintegerType ClientSq_getinteger; -extern sq_getintegerType ServerSq_getinteger; - -typedef SQFloat (*sq_getfloatType)(void*, SQInteger stackpos); -extern sq_getfloatType ClientSq_getfloat; -extern sq_getfloatType ServerSq_getfloat; - -typedef SQBool (*sq_getboolType)(void*, SQInteger stackpos); -extern sq_getboolType ClientSq_getbool; -extern sq_getboolType ServerSq_getbool; - -typedef SQRESULT (*sq_getType)(void* sqvm, SQInteger idx); -extern sq_getType ServerSq_sq_get; -extern sq_getType ClientSq_sq_get; - -template <ScriptContext context> class SquirrelManager -{ - private: - std::vector<SQFuncRegistration*> m_funcRegistrations; - - public: - void* sqvm; - void* sqvm2; - - public: - SquirrelManager() : sqvm(nullptr) {} - - void VMCreated(void* newSqvm) - { - sqvm = newSqvm; - sqvm2 = *((void**)((char*)sqvm + 8)); // honestly not 100% sure on what this is, but alot of functions take it - - for (SQFuncRegistration* funcReg : m_funcRegistrations) - { - spdlog::info("Registering {} function {}", GetContextName(context), funcReg->squirrelFuncName); - - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - ClientRegisterSquirrelFunc(sqvm, funcReg, 1); - else - ServerRegisterSquirrelFunc(sqvm, funcReg, 1); - } - } - - void VMDestroyed() - { - sqvm = nullptr; - } - - void ExecuteCode(const char* code) - { - // ttf2sdk checks ThreadIsInMainThread here, might be good to do that? doesn't seem like an issue rn tho - - if (!sqvm) - { - spdlog::error("Cannot execute code, {} squirrel vm is not initialised", GetContextName(context)); - return; - } - - spdlog::info("Executing {} script code {} ", GetContextName(context), code); - - std::string strCode(code); - CompileBufferState bufferState = CompileBufferState(strCode); - - SQRESULT compileResult; - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - compileResult = ClientSq_compilebuffer(sqvm2, &bufferState, "console", -1, context); - else if (context == ScriptContext::SERVER) - compileResult = ServerSq_compilebuffer(sqvm2, &bufferState, "console", -1, context); - - spdlog::info("sq_compilebuffer returned {}", compileResult); - if (compileResult >= 0) - { - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - { - ClientSq_pushroottable(sqvm2); - SQRESULT callResult = ClientSq_call(sqvm2, 1, false, false); - spdlog::info("sq_call returned {}", callResult); - } - else if (context == ScriptContext::SERVER) - { - ServerSq_pushroottable(sqvm2); - SQRESULT callResult = ServerSq_call(sqvm2, 1, false, false); - spdlog::info("sq_call returned {}", callResult); - } - } - } - - int setupfunc(const char* funcname) - { - int result = -2; - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - { - ClientSq_pushroottable(sqvm2); - ClientSq_pushstring(sqvm2, funcname, -1); - result = ClientSq_sq_get(sqvm2, -2); - if (result != SQRESULT_ERROR) - { - ClientSq_pushroottable(sqvm2); - } - } - else if (context == ScriptContext::SERVER) - { - ServerSq_pushroottable(sqvm2); - ServerSq_pushstring(sqvm2, funcname, -1); - result = ServerSq_sq_get(sqvm2, -2); - if (result != SQRESULT_ERROR) - { - ServerSq_pushroottable(sqvm2); - } - } - return result; - } - - void pusharg(int arg) - { - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - ClientSq_pushinteger(sqvm2, arg); - else if (context == ScriptContext::SERVER) - ServerSq_pushinteger(sqvm2, arg); - } - void pusharg(const char* arg) - { - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - ClientSq_pushstring(sqvm2, arg, -1); - else if (context == ScriptContext::SERVER) - ServerSq_pushstring(sqvm2, arg, -1); - } - void pusharg(float arg) - { - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - ClientSq_pushfloat(sqvm2, arg); - else if (context == ScriptContext::SERVER) - ServerSq_pushfloat(sqvm2, arg); - } - void pusharg(bool arg) - { - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - ClientSq_pushbool(sqvm2, arg); - else if (context == ScriptContext::SERVER) - ServerSq_pushbool(sqvm2, arg); - } - - int call(int args) - { - int result = -2; - if (context == ScriptContext::CLIENT || context == ScriptContext::UI) - result = ClientSq_call(sqvm2, args + 1, false, false); - else if (context == ScriptContext::SERVER) - result = ServerSq_call(sqvm2, args + 1, false, false); - - return result; - } - - void AddFuncRegistration(std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func) - { - SQFuncRegistration* reg = new SQFuncRegistration; - - reg->squirrelFuncName = new char[name.size() + 1]; - strcpy((char*)reg->squirrelFuncName, name.c_str()); - reg->cppFuncName = reg->squirrelFuncName; - - reg->helpText = new char[helpText.size() + 1]; - strcpy((char*)reg->helpText, helpText.c_str()); - - reg->returnValueType = new char[returnType.size() + 1]; - strcpy((char*)reg->returnValueType, returnType.c_str()); - - reg->argTypes = new char[argTypes.size() + 1]; - strcpy((char*)reg->argTypes, argTypes.c_str()); - - reg->funcPtr = func; - - m_funcRegistrations.push_back(reg); - } -}; - -extern SquirrelManager<ScriptContext::CLIENT>* g_ClientSquirrelManager; -extern SquirrelManager<ScriptContext::SERVER>* g_ServerSquirrelManager; -extern SquirrelManager<ScriptContext::UI>* g_UISquirrelManager; diff --git a/LauncherInjector/LauncherInjector.vcxproj b/NorthstarLauncher/NorthstarLauncher.vcxproj index 8870c732..1c3ebe37 100644 --- a/LauncherInjector/LauncherInjector.vcxproj +++ b/NorthstarLauncher/NorthstarLauncher.vcxproj @@ -56,7 +56,7 @@ <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> - <LanguageStandard>stdcpp17</LanguageStandard> + <LanguageStandard>stdcpp20</LanguageStandard> <AdditionalOptions>/F8000000 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <Link> @@ -65,6 +65,9 @@ <AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <StackReserveSize>8000000</StackReserveSize> </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(SolutionDir)..\..\"</Command> + </PostBuildEvent> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> @@ -74,7 +77,7 @@ <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> - <LanguageStandard>stdcpp17</LanguageStandard> + <LanguageStandard>stdcpp20</LanguageStandard> <AdditionalOptions>/F8000000 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <Link> @@ -85,6 +88,9 @@ <AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <StackReserveSize>8000000</StackReserveSize> </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(SolutionDir)..\..\"</Command> + </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="main.cpp" /> diff --git a/LauncherInjector/LauncherInjector.vcxproj.filters b/NorthstarLauncher/NorthstarLauncher.vcxproj.filters index 87e25fa8..76b907bf 100644 --- a/LauncherInjector/LauncherInjector.vcxproj.filters +++ b/NorthstarLauncher/NorthstarLauncher.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Source Files"> @@ -34,4 +34,4 @@ <Filter>Resource Files</Filter> </Image> </ItemGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/LauncherInjector/main.cpp b/NorthstarLauncher/main.cpp index 04aadf03..078cbc4a 100644 --- a/LauncherInjector/main.cpp +++ b/NorthstarLauncher/main.cpp @@ -1,12 +1,17 @@ #define WIN32_LEAN_AND_MEAN -#include <Windows.h> -#include <TlHelp32.h> +#include <windows.h> +#include <tlhelp32.h> #include <filesystem> #include <sstream> #include <fstream> -#include <Shlwapi.h> +#include <shlwapi.h> #include <iostream> +#pragma comment(lib, "Ws2_32.lib") + +#include <winsock2.h> +#include <WS2tcpip.h> + namespace fs = std::filesystem; extern "C" @@ -125,6 +130,41 @@ void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Error", 0); } +void AwaitOriginStartup() +{ + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); + SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock != INVALID_SOCKET) + { + const int LSX_PORT = 3216; + + sockaddr_in lsxAddr; + lsxAddr.sin_family = AF_INET; + inet_pton(AF_INET, "127.0.0.1", &(lsxAddr.sin_addr)); + lsxAddr.sin_port = htons(LSX_PORT); + + std::cout << "LSX: connect()" << std::endl; + connect(sock, (struct sockaddr*)&lsxAddr, sizeof(lsxAddr)); + + char buf[4096]; + memset(buf, 0, sizeof(buf)); + + do + { + recv(sock, buf, 4096, 0); + std::cout << buf << std::endl; + + // honestly really shit, this isn't needed for origin due to being able to check OriginClientService + // but for ea desktop we don't have anything like this, so atm we just have to wait to ensure that we start after logging in + Sleep(8000); + } while (!strstr(buf, "<LSX>")); // ensure we're actually getting data from lsx + } + + WSACleanup(); // cleanup sockets and such so game can contact lsx itself +} + void EnsureOriginStarted() { if (GetProcessByName(L"Origin.exe") || GetProcessByName(L"EADesktop.exe")) @@ -147,7 +187,7 @@ void EnsureOriginStarted() return; } - printf("[*] Starting Origin...\n"); + std::cout << "[*] Starting Origin..." << std::endl; PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); @@ -168,11 +208,16 @@ void EnsureOriginStarted() (LPSTARTUPINFOA)&si, &pi); - printf("[*] Waiting for Origin...\n"); + std::cout << "[*] Waiting for Origin..." << std::endl; + + // wait for origin process to boot + do + { + Sleep(500); + } while (!GetProcessByName(L"OriginClientService.exe") && !GetProcessByName(L"EADesktop.exe")); - // wait for origin to be ready, this process is created when origin is ready enough to launch game without any errors - while (!GetProcessByName(L"OriginClientService.exe") && !GetProcessByName(L"EADesktop.exe")) - Sleep(200); + // wait for origin to be ready to start + AwaitOriginStartup(); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -225,7 +270,7 @@ bool ShouldLoadNorthstar(int argc, char* argv[]) std::stringstream runNorthstarFileBuffer; runNorthstarFileBuffer << runNorthstarFile.rdbuf(); runNorthstarFile.close(); - if (runNorthstarFileBuffer.str()._Starts_with("0")) + if (runNorthstarFileBuffer.str().starts_with("0")) loadNorthstar = false; } return loadNorthstar; @@ -236,7 +281,7 @@ bool LoadNorthstar() FARPROC Hook_Init = nullptr; { swprintf_s(buffer, L"%s\\Northstar.dll", exePath); - hHookModule = LoadLibraryExW(buffer, 0i64, 8u); + hHookModule = LoadLibraryExW(buffer, 0, 8u); if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); if (!hHookModule || Hook_Init == nullptr) @@ -253,7 +298,7 @@ bool LoadNorthstar() LoadPlugins = GetProcAddress(hHookModule, "LoadPlugins"); if (!hHookModule || LoadPlugins == nullptr) { - printf("Failed to get function pointer to LoadPlugins of Northstar.dll\n"); + std::cout << "Failed to get function pointer to LoadPlugins of Northstar.dll" << std::endl; LibraryLoadError(GetLastError(), L"Northstar.dll", buffer); return false; } @@ -266,7 +311,7 @@ bool LoadNorthstar() HMODULE LoadDediStub(const char* name) { // this works because materialsystem_dx11.dll uses relative imports, and even a DLL loaded with an absolute path will take precedence - printf("[*] Loading %s\n", name); + std::cout << "[*] Loading " << name << std::endl; swprintf_s(buffer, L"%s\\bin\\x64_dedi\\%hs", exePath, name); HMODULE h = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH); if (!h) @@ -310,7 +355,7 @@ int main(int argc, char* argv[]) if (dedicated && !nostubs) { - printf("[*] Loading stubs\n"); + std::cout << "[*] Loading stubs" << std::endl; HMODULE gssao, gtxaa, d3d11; if (!(gssao = GetModuleHandleA("GFSDK_SSAO.win64.dll")) && !(gtxaa = GetModuleHandleA("GFSDK_TXAA.win64.dll")) && !(d3d11 = GetModuleHandleA("d3d11.dll"))) @@ -320,8 +365,9 @@ int main(int argc, char* argv[]) { if ((!gssao || FreeLibrary(gssao)) && (!gtxaa || FreeLibrary(gtxaa)) && (!d3d11 || FreeLibrary(d3d11))) { - printf("[*] WARNING: Failed to load d3d11/gfsdk stubs from bin/x64_dedi. " - "The stubs have been unloaded and the original libraries will be used instead.\n"); + std::cout << "[*] WARNING: Failed to load d3d11/gfsdk stubs from bin/x64_dedi. " + "The stubs have been unloaded and the original libraries will be used instead" + << std::endl; } else { @@ -339,8 +385,9 @@ int main(int argc, char* argv[]) else { // this should never happen - printf("[*] WARNING: Failed to load stubs because conflicting modules are already loaded, so those will be used instead " - "(did Northstar initialize too late?).\n"); + std::cout << "[*] WARNING: Failed to load stubs because conflicting modules are already loaded, so those will be used instead " + "(did Northstar initialize too late?)." + << std::endl; } } @@ -362,7 +409,7 @@ int main(int argc, char* argv[]) file.close(); } - printf("[*] Loading tier0.dll\n"); + std::cout << "[*] Loading tier0.dll" << std::endl; swprintf_s(buffer, L"%s\\bin\\x64_retail\\tier0.dll", exePath); hTier0Module = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH); if (!hTier0Module) @@ -374,14 +421,14 @@ int main(int argc, char* argv[]) bool loadNorthstar = ShouldLoadNorthstar(argc, argv); if (loadNorthstar) { - printf("[*] Loading Northstar\n"); + std::cout << "[*] Loading Northstar" << std::endl; if (!LoadNorthstar()) return 1; } else - printf("[*] Going to load the vanilla game\n"); + std::cout << "[*] Going to load the vanilla game" << std::endl; - printf("[*] Loading launcher.dll\n"); + std::cout << "[*] Loading launcher.dll" << std::endl; swprintf_s(buffer, L"%s\\bin\\x64_retail\\launcher.dll", exePath); hLauncherModule = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH); if (!hLauncherModule) @@ -391,7 +438,7 @@ int main(int argc, char* argv[]) } } - printf("[*] Launching the game...\n"); + std::cout << "[*] Launching the game..." << std::endl; auto LauncherMain = GetLauncherMain(); if (!LauncherMain) MessageBoxA( @@ -399,9 +446,8 @@ int main(int argc, char* argv[]) "Failed loading launcher.dll.\nThe game cannot continue and has to exit.", "Northstar Launcher Error", 0); - // auto result = ((__int64(__fastcall*)())LauncherMain)(); - // auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64); + std::cout.flush(); return ((int(/*__fastcall*/*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)( NULL, NULL, NULL, 0); // the parameters aren't really used anyways } diff --git a/LauncherInjector/ns_icon.ico b/NorthstarLauncher/ns_icon.ico Binary files differindex fc9ad166..fc9ad166 100644 --- a/LauncherInjector/ns_icon.ico +++ b/NorthstarLauncher/ns_icon.ico diff --git a/LauncherInjector/resource1.h b/NorthstarLauncher/resource1.h index bb584502..bb584502 100644 --- a/LauncherInjector/resource1.h +++ b/NorthstarLauncher/resource1.h diff --git a/LauncherInjector/resources.rc b/NorthstarLauncher/resources.rc index de16250b..32038499 100644 --- a/LauncherInjector/resources.rc +++ b/NorthstarLauncher/resources.rc @@ -1,7 +1,7 @@ // Microsoft Visual C++ generated resource script. // #include "resource1.h" -#include "../NorthstarDedicatedTest/ns_version.h" +#include "../NorthstarDLL/ns_version.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// diff --git a/R2Northstar.sln b/R2Northstar.sln index 3dfdb218..b66b0dcd 100644 --- a/R2Northstar.sln +++ b/R2Northstar.sln @@ -1,11 +1,11 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Northstar", "NorthstarDedicatedTest\NorthstarDedicatedTest.vcxproj", "{CFAD2623-064F-453C-8196-79EE10292E32}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Northstar", "NorthstarDLL\NorthstarDLL.vcxproj", "{CFAD2623-064F-453C-8196-79EE10292E32}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NorthstarLauncher", "LauncherInjector\LauncherInjector.vcxproj", "{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NorthstarLauncher", "NorthstarLauncher\NorthstarLauncher.vcxproj", "{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader_launcher_proxy", "loader_launcher_proxy\loader_launcher_proxy.vcxproj", "{F65C322D-66DF-4AF1-B650-70221DE334C0}" EndProject @@ -9,4 +9,4 @@ Check [BUILD.md](https://github.com/R2Northstar/NorthstarLauncher/blob/main/BUIL ## Format -This project uses [clang-format](https://clang.llvm.org/docs/ClangFormat.html), make sure you run `clang-format -i --style=file LauncherInjector/*.cpp LauncherInjector/*.h NorthstarDedicatedTest/*.cpp NorthstarDedicatedTest/*.h` when opening a Pull Request. Check the tool's website for instructions on how to integrate it with your IDE.
\ No newline at end of file +This project uses [clang-format](https://clang.llvm.org/docs/ClangFormat.html), make sure you run `clang-format -i --style=file NorthstarLauncher/*.cpp NorthstarLauncher/*.h NorthstarDLL/*.cpp NorthstarDLL/*.h` when opening a Pull Request. Check the tool's website for instructions on how to integrate it with your IDE. diff --git a/loader_launcher_proxy/Memory.cpp b/loader_launcher_proxy/Memory.cpp deleted file mode 100644 index 200246eb..00000000 --- a/loader_launcher_proxy/Memory.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "pch.h" - -extern HMODULE hTier0Module; -IMemAlloc** g_ppMemAllocSingleton; - -void LoadTier0Handle() -{ - if (!hTier0Module) - hTier0Module = GetModuleHandleA("tier0.dll"); - if (!hTier0Module) - return; - - g_ppMemAllocSingleton = (IMemAlloc**)GetProcAddress(hTier0Module, "g_pMemAllocSingleton"); -} - -const int STATIC_ALLOC_SIZE = 4096; - -size_t g_iStaticAllocated = 0; -void* g_pLastAllocated = nullptr; -char pStaticAllocBuf[STATIC_ALLOC_SIZE]; - -// they should never be used here, except in LibraryLoadError? - -void* malloc(size_t n) -{ - // allocate into static buffer - if (g_iStaticAllocated + n <= STATIC_ALLOC_SIZE) - { - void* ret = pStaticAllocBuf + g_iStaticAllocated; - g_iStaticAllocated += n; - return ret; - } - else - { - // try to fallback to g_pMemAllocSingleton - if (!hTier0Module || !g_ppMemAllocSingleton) - LoadTier0Handle(); - if (g_ppMemAllocSingleton && *g_ppMemAllocSingleton) - return (*g_ppMemAllocSingleton)->m_vtable->Alloc(*g_ppMemAllocSingleton, n); - else - throw "Cannot allocate"; - } -} - -void free(void* p) -{ - // if it was allocated into the static buffer, just do nothing, safest way to deal with it - if (p >= pStaticAllocBuf && p <= pStaticAllocBuf + STATIC_ALLOC_SIZE) - return; - - if (g_ppMemAllocSingleton && *g_ppMemAllocSingleton) - (*g_ppMemAllocSingleton)->m_vtable->Free(*g_ppMemAllocSingleton, p); -} - -void* realloc(void* old_ptr, size_t size) -{ - // it was allocated into the static buffer - if (old_ptr >= pStaticAllocBuf && old_ptr <= pStaticAllocBuf + STATIC_ALLOC_SIZE) - { - if (g_pLastAllocated == old_ptr) - { - // nothing was allocated after this - size_t old_size = g_iStaticAllocated - ((size_t)g_pLastAllocated - (size_t)pStaticAllocBuf); - size_t diff = size - old_size; - if (diff > 0) - g_iStaticAllocated += diff; - return old_ptr; - } - else - { - return malloc(size); - } - } - - if (g_ppMemAllocSingleton && *g_ppMemAllocSingleton) - return (*g_ppMemAllocSingleton)->m_vtable->Realloc(*g_ppMemAllocSingleton, old_ptr, size); - return nullptr; -} - -void* operator new(size_t n) { return malloc(n); } - -void operator delete(void* p) { return free(p); } diff --git a/loader_launcher_proxy/Memory.h b/loader_launcher_proxy/Memory.h deleted file mode 100644 index c983966c..00000000 --- a/loader_launcher_proxy/Memory.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -class IMemAlloc -{ -public: - struct VTable - { - void* unknown[1]; // alloc debug - void* (*Alloc) (IMemAlloc* memAlloc, size_t nSize); - void* unknown2[1]; // realloc debug - void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize); - void* unknown3[1]; // free #1 - void (*Free) (IMemAlloc* memAlloc, void* pMem); - void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag - size_t(*GetSize) (IMemAlloc* memAlloc, void* pMem); - void* unknown5[9]; // they all do literally nothing - void (*DumpStats) (IMemAlloc* memAlloc); - void (*DumpStatsFileBase) (IMemAlloc* memAlloc, const char* pchFileBase); - void* unknown6[4]; - int (*heapchk) (IMemAlloc* memAlloc); - }; - - VTable* m_vtable; -}; diff --git a/loader_launcher_proxy/dllmain.cpp b/loader_launcher_proxy/dllmain.cpp index 1215ca1f..a382bc97 100644 --- a/loader_launcher_proxy/dllmain.cpp +++ b/loader_launcher_proxy/dllmain.cpp @@ -2,7 +2,7 @@ #include <stdio.h> #include <string> #include <system_error> -#include <Shlwapi.h> +#include <shlwapi.h> #include <sstream> #include <fstream> #include <filesystem> @@ -14,61 +14,64 @@ HMODULE hTier0Module; using CreateInterfaceFn = void* (*)(const char* pName, int* pReturnCode); // does not seem to ever be used -extern "C" _declspec(dllexport) void* __fastcall CreateInterface(const char* pName, int* pReturnCode) +extern "C" __declspec(dllexport) void* __fastcall CreateInterface(const char* pName, int* pReturnCode) { - //AppSystemCreateInterfaceFn(pName, pReturnCode); - printf("external CreateInterface: name: %s\n", pName); + // AppSystemCreateInterfaceFn(pName, pReturnCode); + printf("external CreateInterface: name: %s\n", pName); - static CreateInterfaceFn launcher_CreateInterface = (CreateInterfaceFn)GetProcAddress(hLauncherModule, "CreateInterface"); - auto res = launcher_CreateInterface(pName, pReturnCode); + static CreateInterfaceFn launcher_CreateInterface = (CreateInterfaceFn)GetProcAddress(hLauncherModule, "CreateInterface"); + auto res = launcher_CreateInterface(pName, pReturnCode); - printf("external CreateInterface: return code: %p\n", res); - return res; + printf("external CreateInterface: return code: %p\n", res); + return res; } bool GetExePathWide(wchar_t* dest, DWORD destSize) { - if (!dest) return NULL; - if (destSize < MAX_PATH) return NULL; + if (!dest) + return NULL; + if (destSize < MAX_PATH) + return NULL; - DWORD length = GetModuleFileNameW(NULL, dest, destSize); - return length && PathRemoveFileSpecW(dest); + DWORD length = GetModuleFileNameW(NULL, dest, destSize); + return length && PathRemoveFileSpecW(dest); } FARPROC GetLauncherMain() { - static FARPROC Launcher_LauncherMain; - if (!Launcher_LauncherMain) - Launcher_LauncherMain = GetProcAddress(hLauncherModule, "LauncherMain"); - return Launcher_LauncherMain; + static FARPROC Launcher_LauncherMain; + if (!Launcher_LauncherMain) + Launcher_LauncherMain = GetProcAddress(hLauncherModule, "LauncherMain"); + return Launcher_LauncherMain; } void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location) { - char text[4096]; - std::string message = std::system_category().message(dwMessageId); - sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs", libName, location, dwMessageId, message.c_str()); - if (dwMessageId == 126 && std::filesystem::exists(location)) - { - sprintf_s(text, "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be found.", text); - } - MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Proxy Error", 0); + char text[4096]; + std::string message = std::system_category().message(dwMessageId); + sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs", libName, location, dwMessageId, message.c_str()); + if (dwMessageId == 126 && std::filesystem::exists(location)) + { + sprintf_s( + text, + "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be " + "found.", + text); + } + MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Proxy Error", 0); } -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; } wchar_t exePath[4096]; @@ -76,86 +79,96 @@ wchar_t dllPath[4096]; bool ShouldLoadNorthstar() { - bool loadNorthstar = !strstr(GetCommandLineA(), "-vanilla"); - - if (!loadNorthstar) - return loadNorthstar; - - auto runNorthstarFile = std::ifstream("run_northstar.txt"); - if (runNorthstarFile) - { - std::stringstream runNorthstarFileBuffer; - runNorthstarFileBuffer << runNorthstarFile.rdbuf(); - runNorthstarFile.close(); - if (runNorthstarFileBuffer.str()._Starts_with("0")) - loadNorthstar = false; - } - return loadNorthstar; + bool loadNorthstar = !strstr(GetCommandLineA(), "-vanilla"); + + if (!loadNorthstar) + return loadNorthstar; + + auto runNorthstarFile = std::ifstream("run_northstar.txt"); + if (runNorthstarFile) + { + std::stringstream runNorthstarFileBuffer; + runNorthstarFileBuffer << runNorthstarFile.rdbuf(); + runNorthstarFile.close(); + if (runNorthstarFileBuffer.str().starts_with("0")) + loadNorthstar = false; + } + return loadNorthstar; } bool LoadNorthstar() { - FARPROC Hook_Init = nullptr; - { - swprintf_s(dllPath, L"%s\\Northstar.dll", exePath); - hHookModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); - if (!hHookModule || Hook_Init == nullptr) - { - LibraryLoadError(GetLastError(), L"Northstar.dll", dllPath); - return false; - } - } - - ((bool (*)()) Hook_Init)(); - return true; + FARPROC Hook_Init = nullptr; + { + swprintf_s(dllPath, L"%s\\Northstar.dll", exePath); + hHookModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (hHookModule) + Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); + if (!hHookModule || Hook_Init == nullptr) + { + LibraryLoadError(GetLastError(), L"Northstar.dll", dllPath); + return false; + } + } + + ((bool (*)())Hook_Init)(); + return true; } extern "C" __declspec(dllexport) int LauncherMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - { - if (!GetExePathWide(exePath, 4096)) - { - MessageBoxA(GetForegroundWindow(), "Failed getting game directory.\nThe game cannot continue and has to exit.", "Northstar Launcher Proxy Error", 0); - return 1; - } - - bool loadNorthstar = ShouldLoadNorthstar(); - - if (loadNorthstar) - { - swprintf_s(dllPath, L"%s\\bin\\x64_retail\\tier0.dll", exePath); - hTier0Module = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (!hTier0Module) - { - LibraryLoadError(GetLastError(), L"tier0.dll", dllPath); - return 1; - } - - if (!LoadNorthstar()) - return 1; - } - //else printf("\n\n WILL !!!NOT!!! LOAD NORTHSTAR\n\n"); - - swprintf_s(dllPath, L"%s\\bin\\x64_retail\\launcher.org.dll", exePath); - hLauncherModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (!hLauncherModule) - { - LibraryLoadError(GetLastError(), L"launcher.org.dll", dllPath); - return 1; - } - } - - auto LauncherMain = GetLauncherMain(); - if (!LauncherMain) - MessageBoxA(GetForegroundWindow(), "Failed loading launcher.org.dll.\nThe game cannot continue and has to exit.", "Northstar Launcher Proxy Error", 0); - //auto result = ((__int64(__fastcall*)())LauncherMain)(); - //auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64); - return ((int(__fastcall*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + { + if (!GetExePathWide(exePath, 4096)) + { + MessageBoxA( + GetForegroundWindow(), + "Failed getting game directory.\nThe game cannot continue and has to exit.", + "Northstar Launcher Proxy Error", + 0); + return 1; + } + + bool loadNorthstar = ShouldLoadNorthstar(); + + if (loadNorthstar) + { + swprintf_s(dllPath, L"%s\\bin\\x64_retail\\tier0.dll", exePath); + hTier0Module = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hTier0Module) + { + LibraryLoadError(GetLastError(), L"tier0.dll", dllPath); + return 1; + } + + if (!LoadNorthstar()) + return 1; + } + // else printf("\n\n WILL !!!NOT!!! LOAD NORTHSTAR\n\n"); + + swprintf_s(dllPath, L"%s\\bin\\x64_retail\\launcher.org.dll", exePath); + hLauncherModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hLauncherModule) + { + LibraryLoadError(GetLastError(), L"launcher.org.dll", dllPath); + return 1; + } + } + + auto LauncherMain = GetLauncherMain(); + if (!LauncherMain) + MessageBoxA( + GetForegroundWindow(), + "Failed loading launcher.org.dll.\nThe game cannot continue and has to exit.", + "Northstar Launcher Proxy Error", + 0); + // auto result = ((__int64(__fastcall*)())LauncherMain)(); + // auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64); + return ((int(__fastcall*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } // doubt that will help us here (in launcher.dll) though -extern "C" { - __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +extern "C" +{ + __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; } diff --git a/loader_launcher_proxy/framework.h b/loader_launcher_proxy/framework.h index d1b49600..1800e436 100644 --- a/loader_launcher_proxy/framework.h +++ b/loader_launcher_proxy/framework.h @@ -1,7 +1,7 @@ #pragma once -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define WIN32_EXTRA_LEAN #define VC_EXTRALEAN // Windows Header Files -#include <Windows.h> +#include <windows.h> diff --git a/loader_launcher_proxy/loader_launcher_proxy.vcxproj b/loader_launcher_proxy/loader_launcher_proxy.vcxproj index 24cdabc0..b62ac63f 100644 --- a/loader_launcher_proxy/loader_launcher_proxy.vcxproj +++ b/loader_launcher_proxy/loader_launcher_proxy.vcxproj @@ -59,7 +59,7 @@ <ConformanceMode>true</ConformanceMode> <PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> - <LanguageStandard>stdcpp17</LanguageStandard> + <LanguageStandard>stdcpp20</LanguageStandard> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -78,7 +78,7 @@ <ConformanceMode>true</ConformanceMode> <PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> - <LanguageStandard>stdcpp17</LanguageStandard> + <LanguageStandard>stdcpp20</LanguageStandard> </ClCompile> <Link> <SubSystem>Windows</SubSystem> diff --git a/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters b/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters index 1e57c7b1..4bf52578 100644 --- a/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters +++ b/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Source Files"> @@ -30,4 +30,4 @@ <Filter>Source Files</Filter> </ClCompile> </ItemGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/loader_launcher_proxy/pch.h b/loader_launcher_proxy/pch.h index 885d5d62..cc757129 100644 --- a/loader_launcher_proxy/pch.h +++ b/loader_launcher_proxy/pch.h @@ -10,4 +10,4 @@ // add headers that you want to pre-compile here #include "framework.h" -#endif //PCH_H +#endif // PCH_H diff --git a/loader_wsock32_proxy/dllmain.cpp b/loader_wsock32_proxy/dllmain.cpp index f4c0d604..7feb278d 100644 --- a/loader_wsock32_proxy/dllmain.cpp +++ b/loader_wsock32_proxy/dllmain.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include "loader.h" -#include <Shlwapi.h> +#include <shlwapi.h> #include <filesystem> HINSTANCE hLThis = 0; @@ -10,8 +10,10 @@ HINSTANCE hL = 0; bool GetExePathWide(wchar_t* dest, DWORD destSize) { - if (!dest) return NULL; - if (destSize < MAX_PATH) return NULL; + if (!dest) + return NULL; + if (destSize < MAX_PATH) + return NULL; DWORD length = GetModuleFileNameW(NULL, dest, destSize); return length && PathRemoveFileSpecW(dest); @@ -29,7 +31,11 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) if (!GetExePathWide(exePath, 4096)) { - MessageBoxA(GetForegroundWindow(), "Failed getting game directory.\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); + MessageBoxA( + GetForegroundWindow(), + "Failed getting game directory.\nThe game cannot continue and has to exit.", + "Northstar Wsock32 Proxy Error", + 0); return true; } @@ -59,7 +65,14 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) { if (!std::filesystem::exists(temp_dir)) { - swprintf_s(buffer2, L"Failed copying wsock32.dll from system32 to \"%s\"\n\n%S\n\nFurthermore, we failed copying wsock32.dll into temporary directory at \"%s\"\n\n%S", buffer1, e1.what(), temp_dir.c_str(), e2.what()); + swprintf_s( + buffer2, + L"Failed copying wsock32.dll from system32 to \"%s\"\n\n%S\n\nFurthermore, we failed copying wsock32.dll into " + L"temporary directory at \"%s\"\n\n%S", + buffer1, + e1.what(), + temp_dir.c_str(), + e2.what()); MessageBoxW(GetForegroundWindow(), buffer2, L"Northstar Wsock32 Proxy Error", 0); return false; } @@ -68,7 +81,8 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) } } hL = LoadLibraryExW(buffer1, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (!hL) { + if (!hL) + { LibraryLoadError(GetLastError(), L"wsock32.org.dll", buffer1); return false; } @@ -104,52 +118,64 @@ extern "C" FARPROC PA = NULL; int RunASM(); - void PROXY_EnumProtocolsA() { + void PROXY_EnumProtocolsA() + { PA = p[1]; RunASM(); } - void PROXY_EnumProtocolsW() { + void PROXY_EnumProtocolsW() + { PA = p[2]; RunASM(); } - void PROXY_GetAddressByNameA() { + void PROXY_GetAddressByNameA() + { PA = p[4]; RunASM(); } - void PROXY_GetAddressByNameW() { + void PROXY_GetAddressByNameW() + { PA = p[5]; RunASM(); } - void PROXY_WEP() { + void PROXY_WEP() + { PA = p[17]; RunASM(); } - void PROXY_WSARecvEx() { + void PROXY_WSARecvEx() + { PA = p[30]; RunASM(); } - void PROXY___WSAFDIsSet() { + void PROXY___WSAFDIsSet() + { PA = p[36]; RunASM(); } - void PROXY_getnetbyname() { + void PROXY_getnetbyname() + { PA = p[45]; RunASM(); } - void PROXY_getsockopt() { + void PROXY_getsockopt() + { PA = p[52]; RunASM(); } - void PROXY_inet_network() { + void PROXY_inet_network() + { PA = p[56]; RunASM(); } - void PROXY_s_perror() { + void PROXY_s_perror() + { PA = p[67]; RunASM(); } - void PROXY_setsockopt() { + void PROXY_setsockopt() + { PA = p[72]; RunASM(); } -}
\ No newline at end of file +} diff --git a/loader_wsock32_proxy/hookutils.cpp b/loader_wsock32_proxy/hookutils.cpp deleted file mode 100644 index f933f993..00000000 --- a/loader_wsock32_proxy/hookutils.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "pch.h" -#include "../NorthstarDedicatedTest/hookutils.h" - -#define ERROR(...) { char err[2048]; sprintf_s(err, __VA_ARGS__); MessageBoxA(GetForegroundWindow(), err, "Northstar Wsock32 Proxy Error", 0); } - -void HookEnabler::CreateHook(LPVOID ppTarget, LPVOID ppDetour, LPVOID* ppOriginal, const char* targetName) -{ - // the macro for this uses ppTarget's name as targetName, and this typically starts with & - // targetname is used for debug stuff and debug output is nicer if we don't have this - if (*targetName == '&') - targetName++; - - if (MH_CreateHook(ppTarget, ppDetour, ppOriginal) == MH_OK) - { - HookTarget* target = new HookTarget; - target->targetAddress = ppTarget; - target->targetName = (char*)targetName; - - m_hookTargets.push_back(target); - } - else - { - if (targetName != nullptr) - { - ERROR("MH_CreateHook failed for function %s", targetName); - } - else - { - ERROR("MH_CreateHook failed for unknown function"); - } - } -} - -HookEnabler::~HookEnabler() -{ - for (auto& hook : m_hookTargets) - { - if (MH_EnableHook(hook->targetAddress) != MH_OK) - { - if (hook->targetName != nullptr) - { - ERROR("MH_EnableHook failed for function %s", hook->targetName); - } - else - { - ERROR("MH_EnableHook failed for unknown function"); - } - } - else - { - //ERROR("Enabling hook %s", hook->targetName); - } - } -}
\ No newline at end of file diff --git a/loader_wsock32_proxy/include/MinHook.h b/loader_wsock32_proxy/include/MinHook.h new file mode 100644 index 00000000..15c0a875 --- /dev/null +++ b/loader_wsock32_proxy/include/MinHook.h @@ -0,0 +1,186 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) + #error MinHook supports only x86 and x64 systems. +#endif + +#include <windows.h> + +// MinHook Error Codes. +typedef enum MH_STATUS +{ + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already + // disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated + // and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT, + + // The specified module is not loaded. + MH_ERROR_MODULE_NOT_FOUND, + + // The specified function is not found. + MH_ERROR_FUNCTION_NOT_FOUND +} +MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, +// MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a Hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + // ppTarget [out] A pointer to the target function, which will be used + // with other functions. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // enabled in one go. + MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); + + // Disables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // disabled in one go. + MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); + + // Queues to enable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); + + // Queues to disable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + + // Translates the MH_STATUS to its name as a string. + const char * WINAPI MH_StatusToString(MH_STATUS status); + +#ifdef __cplusplus +} +#endif + diff --git a/loader_wsock32_proxy/include/MinHook.x64.lib b/loader_wsock32_proxy/include/MinHook.x64.lib Binary files differnew file mode 100644 index 00000000..a346f386 --- /dev/null +++ b/loader_wsock32_proxy/include/MinHook.x64.lib diff --git a/loader_wsock32_proxy/loader.cpp b/loader_wsock32_proxy/loader.cpp index 61b4daf3..4af4daa1 100644 --- a/loader_wsock32_proxy/loader.cpp +++ b/loader_wsock32_proxy/loader.cpp @@ -1,6 +1,6 @@ #include "pch.h" #include "loader.h" -#include "../NorthstarDedicatedTest/hookutils.h" +#include "include/MinHook.h" #include <string> #include <system_error> #include <sstream> @@ -14,7 +14,11 @@ void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs", libName, location, dwMessageId, message.c_str()); if (dwMessageId == 126 && std::filesystem::exists(location)) { - sprintf_s(text, "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be found.", text); + sprintf_s( + text, + "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be " + "found.", + text); } MessageBoxA(GetForegroundWindow(), text, "Northstar Wsock32 Proxy Error", 0); } @@ -44,7 +48,8 @@ bool LoadNorthstar() { swprintf_s(buffer1, L"%s\\Northstar.dll", exePath); auto hHookModule = LoadLibraryExW(buffer1, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); + if (hHookModule) + Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); if (!hHookModule || Hook_Init == nullptr) { LibraryLoadError(GetLastError(), L"Northstar.dll", buffer1); @@ -52,11 +57,11 @@ bool LoadNorthstar() } } - ((bool (*)()) Hook_Init)(); + ((bool (*)())Hook_Init)(); return true; } -typedef int(*LauncherMainType)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); +typedef int (*LauncherMainType)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); LauncherMainType LauncherMainOriginal; int LauncherMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) @@ -73,19 +78,26 @@ bool ProvisionNorthstar() if (MH_Initialize() != MH_OK) { - MessageBoxA(GetForegroundWindow(), "MH_Initialize failed\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); + MessageBoxA( + GetForegroundWindow(), "MH_Initialize failed\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); return false; } auto launcherHandle = GetModuleHandleA("launcher.dll"); if (!launcherHandle) { - MessageBoxA(GetForegroundWindow(), "Launcher isn't loaded yet.\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); + MessageBoxA( + GetForegroundWindow(), + "Launcher isn't loaded yet.\nThe game cannot continue and has to exit.", + "Northstar Wsock32 Proxy Error", + 0); return false; } - HookEnabler hook; - ENABLER_CREATEHOOK(hook, GetProcAddress(launcherHandle, "LauncherMain"), &LauncherMainHook, reinterpret_cast<LPVOID*>(&LauncherMainOriginal)); + LPVOID pTarget = GetProcAddress(launcherHandle, "LauncherMain"); + if (MH_CreateHook(pTarget, &LauncherMainHook, reinterpret_cast<LPVOID*>(&LauncherMainOriginal)) != MH_OK || + MH_EnableHook(pTarget) != MH_OK) + MessageBoxA(GetForegroundWindow(), "Hook creation failed for function LauncherMain.", "Northstar Wsock32 Proxy Error", 0); return true; -}
\ No newline at end of file +} diff --git a/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj b/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj index 9866d368..d65a8f12 100644 --- a/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj +++ b/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj @@ -60,7 +60,7 @@ <ConformanceMode>true</ConformanceMode> <PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> - <LanguageStandard>stdcpp17</LanguageStandard> + <LanguageStandard>stdcpp20</LanguageStandard> <AdditionalIncludeDirectories>..\NorthstarDedicatedTest\</AdditionalIncludeDirectories> </ClCompile> <Link> @@ -68,7 +68,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableUAC>false</EnableUAC> <ModuleDefinitionFile>wsock32.def</ModuleDefinitionFile> - <AdditionalDependencies>..\NorthstarDedicatedTest\include\MinHook.x64.lib;mswsock.lib;ws2_32.lib;Shlwapi.lib;imagehlp.lib;dbghelp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>.\include\MinHook.x64.lib;mswsock.lib;ws2_32.lib;Shlwapi.lib;imagehlp.lib;dbghelp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -82,7 +82,7 @@ <PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <AdditionalIncludeDirectories>..\NorthstarDedicatedTest\</AdditionalIncludeDirectories> - <LanguageStandard>stdcpp17</LanguageStandard> + <LanguageStandard>stdcpp20</LanguageStandard> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -91,16 +91,16 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableUAC>false</EnableUAC> <ModuleDefinitionFile>wsock32.def</ModuleDefinitionFile> - <AdditionalDependencies>..\NorthstarDedicatedTest\include\MinHook.x64.lib;mswsock.lib;ws2_32.lib;Shlwapi.lib;imagehlp.lib;dbghelp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;wsock32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>.\include\MinHook.x64.lib;mswsock.lib;ws2_32.lib;Shlwapi.lib;imagehlp.lib;dbghelp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;wsock32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> + <ClInclude Include="include\MinHook.h" /> <ClInclude Include="loader.h" /> <ClInclude Include="pch.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="dllmain.cpp" /> - <ClCompile Include="hookutils.cpp" /> <ClCompile Include="loader.cpp" /> <ClCompile Include="pch.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> diff --git a/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj.filters b/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj.filters index 6d131e5b..d3c022de 100644 --- a/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj.filters +++ b/loader_wsock32_proxy/loader_wsock32_proxy.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Source Files"> @@ -13,6 +13,9 @@ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> </Filter> + <Filter Include="Header Files\include"> + <UniqueIdentifier>{1b1575f7-3332-478b-9e85-9c0978249a70}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClInclude Include="pch.h"> @@ -21,6 +24,9 @@ <ClInclude Include="loader.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="include\MinHook.h"> + <Filter>Header Files\include</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="dllmain.cpp"> @@ -32,9 +38,6 @@ <ClCompile Include="loader.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="hookutils.cpp"> - <Filter>Source Files</Filter> - </ClCompile> </ItemGroup> <ItemGroup> <MASM Include="wsock32.asm"> @@ -46,4 +49,4 @@ <Filter>Source Files</Filter> </None> </ItemGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/loader_wsock32_proxy/pch.h b/loader_wsock32_proxy/pch.h index 0103ff59..6e8873a1 100644 --- a/loader_wsock32_proxy/pch.h +++ b/loader_wsock32_proxy/pch.h @@ -7,10 +7,10 @@ #ifndef PCH_H #define PCH_H -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files #include <windows.h> #include "include/MinHook.h" -#endif //PCH_H +#endif // PCH_H |