mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Merge branch 'indev' into launcher_rework
This commit is contained in:
commit
3e281d785c
@ -14,7 +14,7 @@ apply_project_settings()
|
||||
|
||||
include_directories( "${ENGINE_SOURCE_DIR}" )
|
||||
include_directories( "${ENGINE_SOURCE_DIR}/public" )
|
||||
include_directories( "${ENGINE_SOURCE_DIR}/thirdparty" )
|
||||
include_directories( "${THIRDPARTY_SOURCE_DIR}" )
|
||||
|
||||
# Include the subdirectories that contain the individual projects
|
||||
add_subdirectory( "${ENGINE_SOURCE_DIR}" )
|
||||
|
@ -42,10 +42,6 @@ which are located in `<gamedir>\platform\cfg\startup_*.cfg`.
|
||||
This is not a cheat or hack; attempting to use the SDK on the live version of the game could result in a permanent account ban.<br />
|
||||
The supported game versions are:
|
||||
|
||||
* S0 `R5pc_r5launch_J1557_CL387233_2019_01_28_07_43_PM`.
|
||||
* S0 `R5pc_r5launch_J1624A_CL394493_2019_02_24_09_29_PM`.
|
||||
* S1 `R5pc_r5launch_N52A_CL399039_2019_03_12_03_21_PM`.
|
||||
* S2 `R5pc_r5launch_N428_CL436418_2019_08_07_09_35_PM`.
|
||||
* S3 `R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM`.
|
||||
|
||||
## Pylon [DISCLAIMER]
|
||||
|
@ -29,6 +29,47 @@ Microsoft Detours
|
||||
// SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
NVIDIA NvAPI
|
||||
************************************************************************************
|
||||
|
||||
// Copyright © 2012 NVIDIA Corporation. All rights reserved.
|
||||
//
|
||||
// NOTICE TO USER:
|
||||
//
|
||||
// This software is subject to NVIDIA ownership rights under U.S.
|
||||
// and international Copyright laws.
|
||||
//
|
||||
// This software and the information contained herein are PROPRIETARY and
|
||||
// CONFIDENTIAL to NVIDIA and are being provided solely under the terms and
|
||||
// conditions of an NVIDIA software license agreement.
|
||||
// Otherwise, you have no rights to use or access this software in any manner.
|
||||
//
|
||||
// If not covered by the applicable NVIDIA software license agreement:
|
||||
// NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
|
||||
// PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY
|
||||
// KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, AND
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY
|
||||
// SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
|
||||
//
|
||||
// U.S. Government End Users.
|
||||
// This software is a "commercial item" as that term is defined at
|
||||
// 48 C.F.R. 2.101 (OCT 1995), consisting of "commercial computer software" and
|
||||
// "commercial computer software documentation" as such terms are used in
|
||||
// 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government only as a
|
||||
// commercial end item. Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1
|
||||
// through 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
|
||||
// software with only those rights set forth herein.
|
||||
//
|
||||
// Any use of this software in individual and commercial software must include,
|
||||
// in the user documentation and internal comments to the code,
|
||||
// the above Disclaimer (as applicable) and U.S. Government End Users Notice.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
Recast & Detour
|
||||
************************************************************************************
|
||||
@ -96,7 +137,7 @@ Dear ImGui
|
||||
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2014-2022 Omar Cornut
|
||||
// Copyright (c) 2014-2024 Omar Cornut
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@ -286,30 +327,22 @@ VDF Parser
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
Nlohmann JSON
|
||||
RapidJSON
|
||||
************************************************************************************
|
||||
|
||||
// MIT License
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (c) 2013-2022 Niels Lohmann
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
// http://opensource.org/licenses/MIT
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed
|
||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
@ -340,6 +373,396 @@ Curl
|
||||
// in this Software without prior written authorization of the copyright holder.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
Mbed TLS & l8w8jwt
|
||||
************************************************************************************
|
||||
|
||||
// Apache License
|
||||
// Version 2.0, January 2004
|
||||
// http://www.apache.org/licenses/
|
||||
//
|
||||
// TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
//
|
||||
// 1. Definitions.
|
||||
//
|
||||
// "License" shall mean the terms and conditions for use, reproduction,
|
||||
// and distribution as defined by Sections 1 through 9 of this document.
|
||||
//
|
||||
// "Licensor" shall mean the copyright owner or entity authorized by
|
||||
// the copyright owner that is granting the License.
|
||||
//
|
||||
// "Legal Entity" shall mean the union of the acting entity and all
|
||||
// other entities that control, are controlled by, or are under common
|
||||
// control with that entity. For the purposes of this definition,
|
||||
// "control" means (i) the power, direct or indirect, to cause the
|
||||
// direction or management of such entity, whether by contract or
|
||||
// otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
// outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
//
|
||||
// "You" (or "Your") shall mean an individual or Legal Entity
|
||||
// exercising permissions granted by this License.
|
||||
//
|
||||
// "Source" form shall mean the preferred form for making modifications,
|
||||
// including but not limited to software source code, documentation
|
||||
// source, and configuration files.
|
||||
//
|
||||
// "Object" form shall mean any form resulting from mechanical
|
||||
// transformation or translation of a Source form, including but
|
||||
// not limited to compiled object code, generated documentation,
|
||||
// and conversions to other media types.
|
||||
//
|
||||
// "Work" shall mean the work of authorship, whether in Source or
|
||||
// Object form, made available under the License, as indicated by a
|
||||
// copyright notice that is included in or attached to the work
|
||||
// (an example is provided in the Appendix below).
|
||||
//
|
||||
// "Derivative Works" shall mean any work, whether in Source or Object
|
||||
// form, that is based on (or derived from) the Work and for which the
|
||||
// editorial revisions, annotations, elaborations, or other modifications
|
||||
// represent, as a whole, an original work of authorship. For the purposes
|
||||
// of this License, Derivative Works shall not include works that remain
|
||||
// separable from, or merely link (or bind by name) to the interfaces of,
|
||||
// the Work and Derivative Works thereof.
|
||||
//
|
||||
// "Contribution" shall mean any work of authorship, including
|
||||
// the original version of the Work and any modifications or additions
|
||||
// to that Work or Derivative Works thereof, that is intentionally
|
||||
// submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
// or by an individual or Legal Entity authorized to submit on behalf of
|
||||
// the copyright owner. For the purposes of this definition, "submitted"
|
||||
// means any form of electronic, verbal, or written communication sent
|
||||
// to the Licensor or its representatives, including but not limited to
|
||||
// communication on electronic mailing lists, source code control systems,
|
||||
// and issue tracking systems that are managed by, or on behalf of, the
|
||||
// Licensor for the purpose of discussing and improving the Work, but
|
||||
// excluding communication that is conspicuously marked or otherwise
|
||||
// designated in writing by the copyright owner as "Not a Contribution."
|
||||
//
|
||||
// "Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
// on behalf of whom a Contribution has been received by Licensor and
|
||||
// subsequently incorporated within the Work.
|
||||
//
|
||||
// 2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
// this License, each Contributor hereby grants to You a perpetual,
|
||||
// worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
// copyright license to reproduce, prepare Derivative Works of,
|
||||
// publicly display, publicly perform, sublicense, and distribute the
|
||||
// Work and such Derivative Works in Source or Object form.
|
||||
//
|
||||
// 3. Grant of Patent License. Subject to the terms and conditions of
|
||||
// this License, each Contributor hereby grants to You a perpetual,
|
||||
// worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
// (except as stated in this section) patent license to make, have made,
|
||||
// use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
// where such license applies only to those patent claims licensable
|
||||
// by such Contributor that are necessarily infringed by their
|
||||
// Contribution(s) alone or by combination of their Contribution(s)
|
||||
// with the Work to which such Contribution(s) was submitted. If You
|
||||
// institute patent litigation against any entity (including a
|
||||
// cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
// or a Contribution incorporated within the Work constitutes direct
|
||||
// or contributory patent infringement, then any patent licenses
|
||||
// granted to You under this License for that Work shall terminate
|
||||
// as of the date such litigation is filed.
|
||||
//
|
||||
// 4. Redistribution. You may reproduce and distribute copies of the
|
||||
// Work or Derivative Works thereof in any medium, with or without
|
||||
// modifications, and in Source or Object form, provided that You
|
||||
// meet the following conditions:
|
||||
//
|
||||
// (a) You must give any other recipients of the Work or
|
||||
// Derivative Works a copy of this License; and
|
||||
//
|
||||
// (b) You must cause any modified files to carry prominent notices
|
||||
// stating that You changed the files; and
|
||||
//
|
||||
// (c) You must retain, in the Source form of any Derivative Works
|
||||
// that You distribute, all copyright, patent, trademark, and
|
||||
// attribution notices from the Source form of the Work,
|
||||
// excluding those notices that do not pertain to any part of
|
||||
// the Derivative Works; and
|
||||
//
|
||||
// (d) If the Work includes a "NOTICE" text file as part of its
|
||||
// distribution, then any Derivative Works that You distribute must
|
||||
// include a readable copy of the attribution notices contained
|
||||
// within such NOTICE file, excluding those notices that do not
|
||||
// pertain to any part of the Derivative Works, in at least one
|
||||
// of the following places: within a NOTICE text file distributed
|
||||
// as part of the Derivative Works; within the Source form or
|
||||
// documentation, if provided along with the Derivative Works; or,
|
||||
// within a display generated by the Derivative Works, if and
|
||||
// wherever such third-party notices normally appear. The contents
|
||||
// of the NOTICE file are for informational purposes only and
|
||||
// do not modify the License. You may add Your own attribution
|
||||
// notices within Derivative Works that You distribute, alongside
|
||||
// or as an addendum to the NOTICE text from the Work, provided
|
||||
// that such additional attribution notices cannot be construed
|
||||
// as modifying the License.
|
||||
//
|
||||
// You may add Your own copyright statement to Your modifications and
|
||||
// may provide additional or different license terms and conditions
|
||||
// for use, reproduction, or distribution of Your modifications, or
|
||||
// for any such Derivative Works as a whole, provided Your use,
|
||||
// reproduction, and distribution of the Work otherwise complies with
|
||||
// the conditions stated in this License.
|
||||
//
|
||||
// 5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
// any Contribution intentionally submitted for inclusion in the Work
|
||||
// by You to the Licensor shall be under the terms and conditions of
|
||||
// this License, without any additional terms or conditions.
|
||||
// Notwithstanding the above, nothing herein shall supersede or modify
|
||||
// the terms of any separate license agreement you may have executed
|
||||
// with Licensor regarding such Contributions.
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor,
|
||||
// except as required for reasonable and customary use in describing the
|
||||
// origin of the Work and reproducing the content of the NOTICE file.
|
||||
//
|
||||
// 7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
// agreed to in writing, Licensor provides the Work (and each
|
||||
// Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied, including, without limitation, any warranties or conditions
|
||||
// of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
// appropriateness of using or redistributing the Work and assume any
|
||||
// risks associated with Your exercise of permissions under this License.
|
||||
//
|
||||
// 8. Limitation of Liability. In no event and under no legal theory,
|
||||
// whether in tort (including negligence), contract, or otherwise,
|
||||
// unless required by applicable law (such as deliberate and grossly
|
||||
// negligent acts) or agreed to in writing, shall any Contributor be
|
||||
// liable to You for damages, including any direct, indirect, special,
|
||||
// incidental, or consequential damages of any character arising as a
|
||||
// result of this License or out of the use or inability to use the
|
||||
// Work (including but not limited to damages for loss of goodwill,
|
||||
// work stoppage, computer failure or malfunction, or any and all
|
||||
// other commercial damages or losses), even if such Contributor
|
||||
// has been advised of the possibility of such damages.
|
||||
//
|
||||
// 9. Accepting Warranty or Additional Liability. While redistributing
|
||||
// the Work or Derivative Works thereof, You may choose to offer,
|
||||
// and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
// or other liability obligations and/or rights consistent with this
|
||||
// License. However, in accepting such obligations, You may act only
|
||||
// on Your own behalf and on Your sole responsibility, not on behalf
|
||||
// of any other Contributor, and only if You agree to indemnify,
|
||||
// defend, and hold each Contributor harmless for any liability
|
||||
// incurred by, or claims asserted against, such Contributor by reason
|
||||
// of your accepting any such warranty or additional liability.
|
||||
//
|
||||
// END OF TERMS AND CONDITIONS
|
||||
//
|
||||
// APPENDIX: How to apply the Apache License to your work.
|
||||
//
|
||||
// To apply the Apache License to your work, attach the following
|
||||
// boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
// replaced with your own identifying information. (Don't include
|
||||
// the brackets!) The text should be enclosed in the appropriate
|
||||
// comment syntax for the file format. We also recommend that a
|
||||
// file or class name and description of purpose be included on the
|
||||
// same "printed page" as the copyright notice for easier
|
||||
// identification within third-party archives.
|
||||
//
|
||||
// Copyright [yyyy] [name of copyright owner]
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
DirtySDK (EA WebKit)
|
||||
************************************************************************************
|
||||
|
||||
// Copyright (C) 1999-2007, 2009-2010, 2012-2013 Electronic Arts Inc
|
||||
//
|
||||
// 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.
|
||||
// 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS 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 ELECTRONIC ARTS OR ITS 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.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
EAThread (EA WebKit)
|
||||
************************************************************************************
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Copyright (C) 2017 Electronic Arts Inc. 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.
|
||||
// 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS 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 ELECTRONIC ARTS OR ITS 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.
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Additional licenses also apply to this software package as detailed below.
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Copyright (c) 2015 Jeff Preshing
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//--------------------------------------------------------------------------
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
EABase (EA WebKit)
|
||||
************************************************************************************
|
||||
|
||||
// Copyright (C) 2002-2013 Electronic Arts Inc
|
||||
//
|
||||
// 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.
|
||||
// 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS 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 ELECTRONIC ARTS OR ITS 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.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
Zstandard
|
||||
************************************************************************************
|
||||
|
||||
// BSD License
|
||||
//
|
||||
// For Zstandard software
|
||||
//
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// * 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.
|
||||
//
|
||||
// * Neither the name Facebook, nor Meta, nor the names of its contributors may
|
||||
// be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// 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.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
LZ4
|
||||
************************************************************************************
|
||||
|
||||
// LZ4 Library
|
||||
// Copyright (c) 2011-2020, Yann Collet
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// * 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.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
LZHAM
|
||||
************************************************************************************
|
||||
@ -365,46 +788,6 @@ LZHAM
|
||||
// THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
SHA256
|
||||
************************************************************************************
|
||||
|
||||
// Updated to C++, zedwood.com 2012
|
||||
// Based on Olivier Gay's version
|
||||
// See Modified BSD License below:
|
||||
//
|
||||
// FIPS 180-2 SHA-224/256/384/512 implementation
|
||||
// Issue date: 04/30/2005
|
||||
// http://www.ouah.org/ogay/sha2/
|
||||
//
|
||||
// Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
|
||||
// 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.
|
||||
// 3. Neither the name of the project nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
************************************************************************************
|
||||
CRC32
|
||||
************************************************************************************
|
||||
|
@ -15,6 +15,7 @@ add_subdirectory( vstdlib )
|
||||
add_subdirectory( vphysics )
|
||||
add_subdirectory( ebisusdk )
|
||||
add_subdirectory( codecs )
|
||||
add_subdirectory( geforce )
|
||||
|
||||
set( FOLDER_CONTEXT "Protocols" )
|
||||
add_subdirectory( protoc )
|
||||
@ -23,31 +24,43 @@ set( FOLDER_CONTEXT "Respawn" )
|
||||
add_subdirectory( rtech )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty" )
|
||||
add_subdirectory( thirdparty/cppnet )
|
||||
add_subdirectory( thirdparty/curl )
|
||||
add_subdirectory( thirdparty/sdl )
|
||||
add_subdirectory( thirdparty/imgui )
|
||||
add_subdirectory( thirdparty/spdlog )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty/Recast" )
|
||||
add_subdirectory( thirdparty/recast )
|
||||
add_subdirectory( thirdparty/detours )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty/Compression" )
|
||||
add_subdirectory( thirdparty/lzham )
|
||||
add_subdirectory( thirdparty/fastlz )
|
||||
add_subdirectory( thirdparty/bzip2 )
|
||||
add_subdirectory( thirdparty/zlib )
|
||||
add_subdirectory( thirdparty/lzma )
|
||||
add_subdirectory( thirdparty/zstd )
|
||||
add_subdirectory( thirdparty/lz4 )
|
||||
add_subdirectory( thirdparty/zip )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty/Recast" )
|
||||
add_subdirectory( thirdparty/recast )
|
||||
set( FOLDER_CONTEXT "Thirdparty/Security" )
|
||||
add_subdirectory( thirdparty/mbedtls )
|
||||
add_subdirectory( thirdparty/jwt )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty/Microsoft" )
|
||||
add_subdirectory( thirdparty/detours )
|
||||
set( FOLDER_CONTEXT "Thirdparty/Multimedia" )
|
||||
add_subdirectory( thirdparty/sdl )
|
||||
add_subdirectory( thirdparty/imgui )
|
||||
add_subdirectory( thirdparty/cppnet )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty/Google" )
|
||||
set( FOLDER_CONTEXT "Thirdparty/Networking" )
|
||||
add_subdirectory( thirdparty/protobuf )
|
||||
add_subdirectory( thirdparty/curl )
|
||||
add_subdirectory( thirdparty/dirtysdk )
|
||||
|
||||
set( FOLDER_CONTEXT "Thirdparty/Threading" )
|
||||
add_subdirectory( thirdparty/ea/EAThread )
|
||||
|
||||
set( FOLDER_CONTEXT "Tools" )
|
||||
add_subdirectory( sdklauncher )
|
||||
add_subdirectory( netconsole )
|
||||
add_subdirectory( naveditor )
|
||||
add_subdirectory( revpk )
|
||||
|
||||
set( FOLDER_CONTEXT "System" )
|
||||
add_subdirectory( networksystem )
|
||||
|
@ -14,7 +14,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAppSystemGroup::StaticDestroy(CAppSystemGroup* pModAppSystemGroup)
|
||||
{
|
||||
CAppSystemGroup_Destroy(pModAppSystemGroup);
|
||||
CAppSystemGroup__Destroy(pModAppSystemGroup);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -25,11 +25,48 @@ CAppSystemGroup::AppSystemGroupStage_t CAppSystemGroup::GetCurrentStage() const
|
||||
return m_nCurrentStage;
|
||||
}
|
||||
|
||||
void VAppSystemGroup::Attach(void) const
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods to find various global singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CAppSystemGroup::FindSystem(const char* pSystemName)
|
||||
{
|
||||
DetourAttach(&CAppSystemGroup_Destroy, &CAppSystemGroup::StaticDestroy);
|
||||
}
|
||||
void VAppSystemGroup::Detach(void) const
|
||||
unsigned short i = m_SystemDict.Find(pSystemName);
|
||||
if (i != m_SystemDict.InvalidIndex())
|
||||
return m_Systems[m_SystemDict[i]];
|
||||
|
||||
// If it's not an interface we know about, it could be an older
|
||||
// version of an interface, or maybe something implemented by
|
||||
// one of the instantiated interfaces...
|
||||
|
||||
// QUESTION: What order should we iterate this in?
|
||||
// It controls who wins if multiple ones implement the same interface
|
||||
for (i = 0; i < m_Systems.Count(); ++i)
|
||||
{
|
||||
DetourDetach(&CAppSystemGroup_Destroy, &CAppSystemGroup::StaticDestroy);
|
||||
void* pInterface = m_Systems[i]->QueryInterface(pSystemName);
|
||||
if (pInterface)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
int nExternalCount = m_NonAppSystemFactories.Count();
|
||||
for (i = 0; i < nExternalCount; ++i)
|
||||
{
|
||||
void* pInterface = m_NonAppSystemFactories[i](pSystemName, NULL);
|
||||
if (pInterface)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
if (m_pParentAppSystem)
|
||||
{
|
||||
void* pInterface = m_pParentAppSystem->FindSystem(pSystemName);
|
||||
if (pInterface)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
// No dice..
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VAppSystemGroup::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&CAppSystemGroup__Destroy, &CAppSystemGroup::StaticDestroy, bAttach);
|
||||
}
|
@ -51,14 +51,8 @@ macro( add_module MODULE_TYPE MODULE_NAME REUSE_PCH FOLDER_NAME WARNINGS_AS_ERRO
|
||||
add_library( ${PROJECT_NAME} )
|
||||
elseif( ${MODULE_TYPE} STREQUAL "shared_lib" )
|
||||
add_library( ${PROJECT_NAME} SHARED )
|
||||
target_link_options( ${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Release>:/LTCG>"
|
||||
)
|
||||
elseif( ${MODULE_TYPE} STREQUAL "exe" )
|
||||
add_executable( ${PROJECT_NAME} )
|
||||
target_link_options( ${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Release>:/LTCG>"
|
||||
)
|
||||
else()
|
||||
message( FATAL_ERROR "Invalid module type: ${MODULE_TYPE}; expected 'lib', 'shared_lib', or 'exe'." )
|
||||
endif()
|
||||
@ -69,7 +63,7 @@ macro( add_module MODULE_TYPE MODULE_NAME REUSE_PCH FOLDER_NAME WARNINGS_AS_ERRO
|
||||
|
||||
set_target_properties( ${MODULE_NAME} PROPERTIES FOLDER ${FOLDER_NAME} )
|
||||
|
||||
if( ${GLOBAL_WARNINGS_AS_ERRORS} )
|
||||
if( ${OPTION_WARNINGS_AS_ERRORS} )
|
||||
warnings_as_errors( ${PROJECT_NAME} ${WARNINGS_AS_ERRORS} )
|
||||
endif()
|
||||
|
||||
@ -80,6 +74,7 @@ macro( add_module MODULE_TYPE MODULE_NAME REUSE_PCH FOLDER_NAME WARNINGS_AS_ERRO
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/Ot>
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/GS->
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/Gy>
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/GT>
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/fp:fast>
|
||||
)
|
||||
endif()
|
||||
@ -101,12 +96,13 @@ macro( define_compiler_variables )
|
||||
endmacro()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Apply whole program optimization for this target in release ( !slow! )
|
||||
# Apply whole program optimization for this target in release and profile ( !slow! )
|
||||
# -----------------------------------------------------------------------------
|
||||
macro( whole_program_optimization )
|
||||
target_compile_options( ${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:/GL>
|
||||
)
|
||||
if( ${OPTION_LTCG_MODE} STREQUAL "ON" )
|
||||
set_property( TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
|
||||
set_property( TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION_PROFILE TRUE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -134,18 +130,25 @@ endmacro()
|
||||
macro( thirdparty_suppress_warnings )
|
||||
if( MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
target_compile_options( ${PROJECT_NAME} PRIVATE
|
||||
/wd4057 # 'function': 'int *' differs in indirection to slightly different base types from 'unsigned int [4]'
|
||||
/wd4100 # Unreferenced formal parameter.
|
||||
/wd4131 # Using old-style declarations
|
||||
/wd4131 # Using old-style declarations.
|
||||
/wd4152 # Function/data pointer conversion in expression.
|
||||
/wd4200 # Zero-sized array in union; SDL2 uses this for compiler compatibility.
|
||||
/wd4201 # Nameless struct/union.
|
||||
/wd4204 # nonstandard extension used: non-constant aggregate initializer.
|
||||
/wd4221 # nonstandard extension used: 'value': cannot be initialized using address of automatic variable 'symbol'
|
||||
/wd4244 # Type conversion truncation; protobuf has many, but this appears intentional.
|
||||
/wd4245 # 'return': conversion signed/unsigned mismatch
|
||||
/wd4267 # Type conversion truncation; protobuf has many, but this appears intentional.
|
||||
/wd4295 # Array is too small to include terminating null character.
|
||||
/wd4307 # Integral constant overflow.
|
||||
/wd4389 # Signed/unsigned mismatch.
|
||||
/wd4456 # Declaration hides previous local declaration.
|
||||
/wd4457 # Declaration hides function parameter.
|
||||
/wd4505 # Unreferenced local function has been removed.
|
||||
/wd4701 # potentially uninitialized local variable.
|
||||
/wd4702 # Unreachable code.
|
||||
)
|
||||
endif()
|
||||
warnings_as_errors( ${PROJECT_NAME} FALSE )
|
||||
|
@ -20,27 +20,52 @@ macro( apply_project_settings )
|
||||
)
|
||||
|
||||
# Some thirdparty code have Warnings as Errors disabled; this option won't override those.
|
||||
option( GLOBAL_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" ON )
|
||||
option( ENABLE_LTCG "Enable link-time code generation (significantly increases compile times)" OFF )
|
||||
option( OPTION_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" ON )
|
||||
|
||||
set( GAMEDLL_OPTION "GAMEDLL_S3" CACHE STRING "Game DLL version" )
|
||||
set_property( CACHE GAMEDLL_OPTION PROPERTY STRINGS
|
||||
"GAMEDLL_S0"
|
||||
"GAMEDLL_S1"
|
||||
"GAMEDLL_S2"
|
||||
"GAMEDLL_S3"
|
||||
set( OPTION_LTCG_MODE "OFF" CACHE STRING "Enables link-time code generation (significantly increases compile times)" )
|
||||
set_property( CACHE OPTION_LTCG_MODE PROPERTY STRINGS
|
||||
"OFF"
|
||||
"ON" # Only on projects that specified LTCG
|
||||
"ALL" # All projects, whether or not LTCG was specified
|
||||
)
|
||||
|
||||
option( OPTION_CERTAIN "This build is certain; debug statements (such as DevMsg(...)) will NOT be compiled" OFF )
|
||||
option( OPTION_RETAIL "This build is retail; enable this among with 'OPTION_CERTAIN' to form a release build" OFF )
|
||||
|
||||
# Set common defines
|
||||
add_compile_definitions(
|
||||
"_CRT_SECURE_NO_WARNINGS"
|
||||
"SPDLOG_COMPILED_LIB"
|
||||
"SPDLOG_NO_EXCEPTIONS"
|
||||
"CURL_STATICLIB"
|
||||
"PLATFORM_64BITS" # Target is 64bits only.
|
||||
"${GAMEDLL_OPTION}"
|
||||
|
||||
# Must be explicitly defined to toggle SIMD optimizations for RapidJSON.
|
||||
# Don't set this to anything higher than SSE2, as the game supports from
|
||||
# SSE3 and higher, and the next level of optimizations in RapidJSON is SSE4.2.
|
||||
"RAPIDJSON_SSE2"
|
||||
|
||||
# Use iterative parsing to protect against stack overflows in rare cases; see:
|
||||
# https://rapidjson.org/md_doc_features.html
|
||||
# https://github.com/Tencent/rapidjson/issues/1227
|
||||
# https://github.com/Tencent/rapidjson/issues/2260
|
||||
"RAPIDJSON_PARSE_DEFAULT_FLAGS=kParseIterativeFlag|kParseValidateEncodingFlag"
|
||||
|
||||
# Target is 64bits only.
|
||||
"PLATFORM_64BITS"
|
||||
)
|
||||
|
||||
if( ${OPTION_CERTAIN} )
|
||||
add_compile_definitions(
|
||||
"_CERT"
|
||||
)
|
||||
endif()
|
||||
|
||||
if( ${OPTION_RETAIL} )
|
||||
add_compile_definitions(
|
||||
"_RETAIL"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Set settings for Debug configuration
|
||||
add_compile_options(
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Debug>>:/MTd>
|
||||
@ -61,11 +86,9 @@ macro( apply_project_settings )
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/EHsc>
|
||||
)
|
||||
|
||||
if( ${ENABLE_LTCG} )
|
||||
add_compile_options(
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Profile>>:/GL>
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release>>:/GL>
|
||||
)
|
||||
if( ${OPTION_LTCG_MODE} STREQUAL "ALL" )
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_PROFILE ON)
|
||||
endif()
|
||||
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE
|
||||
@ -81,9 +104,9 @@ macro( apply_project_settings )
|
||||
include_directories(
|
||||
"${ENGINE_SOURCE_DIR}/"
|
||||
"${ENGINE_SOURCE_DIR}/public/"
|
||||
"${ENGINE_SOURCE_DIR}/thirdparty/"
|
||||
"${ENGINE_SOURCE_DIR}/thirdparty/imgui/"
|
||||
"${ENGINE_SOURCE_DIR}/thirdparty/recast/"
|
||||
"${THIRDPARTY_SOURCE_DIR}/"
|
||||
"${THIRDPARTY_SOURCE_DIR}/imgui/"
|
||||
"${THIRDPARTY_SOURCE_DIR}/recast/"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "miles_impl.h"
|
||||
#include "tier0/fasttimer.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
|
||||
static ConVar miles_debug("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System", "1 = print; 0 (zero) = no print");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: logs debug output emitted from the Miles Sound System
|
||||
@ -10,7 +14,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
void AIL_LogFunc(int64_t nLogLevel, const char* pszMessage)
|
||||
{
|
||||
DevMsg(eDLL_T::AUDIO, "%s\n", pszMessage);
|
||||
Msg(eDLL_T::AUDIO, "%s\n", pszMessage);
|
||||
v_AIL_LogFunc(nLogLevel, pszMessage);
|
||||
}
|
||||
|
||||
@ -22,48 +26,93 @@ bool Miles_Initialize()
|
||||
{
|
||||
const char* pszLanguage = miles_language->GetString();
|
||||
if (!pszLanguage[0])
|
||||
{
|
||||
pszLanguage = MILES_DEFAULT_LANGUAGE;
|
||||
|
||||
const bool isEnglishLanguage = _stricmp(pszLanguage, "english") == 0;
|
||||
|
||||
if (!isEnglishLanguage)
|
||||
{
|
||||
const bool useShipSound = !CommandLine()->FindParm("-devsound") || CommandLine()->FindParm("-shipsound");
|
||||
|
||||
const std::string baseStreamFilePath = Format("%s/general_%s.mstr", useShipSound ? "audio/ship" : "audio/dev", pszLanguage);
|
||||
|
||||
// if the requested language for miles does not have a MSTR file present, throw a non-fatal error and force english as a fallback
|
||||
// if we are loading english and the file is still not found, we can let it hit the regular engine error, since that is not recoverable
|
||||
if (!FileSystem()->FileExists(baseStreamFilePath.c_str()))
|
||||
{
|
||||
Error(eDLL_T::AUDIO, NO_ERROR, "%s: attempted to load language '%s' but the required streaming source file (%s) was not found. falling back to english...\n", __FUNCTION__, pszLanguage, baseStreamFilePath.c_str());
|
||||
|
||||
pszLanguage = MILES_DEFAULT_LANGUAGE;
|
||||
miles_language->SetValue(pszLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::AUDIO, "%s: initializing MSS with language: '%s'\n", __FUNCTION__, pszLanguage);
|
||||
Msg(eDLL_T::AUDIO, "%s: initializing MSS with language: '%s'\n", __FUNCTION__, pszLanguage);
|
||||
CFastTimer initTimer;
|
||||
|
||||
initTimer.Start();
|
||||
bool bResult = v_Miles_Initialize();
|
||||
initTimer.End();
|
||||
|
||||
DevMsg(eDLL_T::AUDIO, "%s: %s ('%f' seconds)\n", __FUNCTION__, bResult ? "success" : "failure", initTimer.GetDuration().GetSeconds());
|
||||
Msg(eDLL_T::AUDIO, "%s: %s ('%f' seconds)\n", __FUNCTION__, bResult ? "success" : "failure", initTimer.GetDuration().GetSeconds());
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void MilesQueueEventRun(Miles::Queue* queue, const char* eventName)
|
||||
{
|
||||
if(miles_debug->GetBool())
|
||||
DevMsg(eDLL_T::AUDIO, "%s: running event: '%s'\n", __FUNCTION__, eventName);
|
||||
if(miles_debug.GetBool())
|
||||
Msg(eDLL_T::AUDIO, "%s: running event: '%s'\n", __FUNCTION__, eventName);
|
||||
|
||||
v_MilesQueueEventRun(queue, eventName);
|
||||
}
|
||||
|
||||
void MilesBankPatch(Miles::Bank* bank, char* streamPatch, char* localizedStreamPatch)
|
||||
{
|
||||
// TODO [REXX]: add print for patch loading when Miles::Bank struct is mapped out a bit better with file name
|
||||
if (miles_debug.GetBool())
|
||||
{
|
||||
Msg(eDLL_T::AUDIO,
|
||||
"%s: patching bank \"%s\". stream patches: \"%s\", \"%s\"\n",
|
||||
__FUNCTION__,
|
||||
bank->GetBankName(),
|
||||
V_UnqualifiedFileName(streamPatch), V_UnqualifiedFileName(localizedStreamPatch)
|
||||
);
|
||||
}
|
||||
|
||||
const Miles::BankHeader_t* header = bank->GetHeader();
|
||||
|
||||
if (header->bankIndex >= header->project->bankCount)
|
||||
Error(eDLL_T::AUDIO, EXIT_FAILURE,
|
||||
"%s: Attempted to patch bank '%s' that identified itself as bank idx %i.\nProject expects a highest index of %i\n",
|
||||
__FUNCTION__,
|
||||
bank->GetBankName(),
|
||||
header->bankIndex,
|
||||
header->project->bankCount - 1
|
||||
);
|
||||
|
||||
v_MilesBankPatch(bank, streamPatch, localizedStreamPatch);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void MilesCore::Attach() const
|
||||
void CSOM_AddEventToQueue(const char* eventName)
|
||||
{
|
||||
DetourAttach(&v_AIL_LogFunc, &AIL_LogFunc);
|
||||
DetourAttach(&v_Miles_Initialize, &Miles_Initialize);
|
||||
DetourAttach(&v_MilesQueueEventRun, &MilesQueueEventRun);
|
||||
DetourAttach(&v_MilesBankPatch, &MilesBankPatch);
|
||||
}
|
||||
if (miles_debug.GetBool())
|
||||
Msg(eDLL_T::AUDIO, "%s: queuing audio event '%s'\n", __FUNCTION__, eventName);
|
||||
|
||||
void MilesCore::Detach() const
|
||||
v_CSOM_AddEventToQueue(eventName);
|
||||
|
||||
if (g_milesGlobals->queuedEventHash == 1)
|
||||
Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; invalid event name '%s'\n", __FUNCTION__, eventName);
|
||||
|
||||
if (g_milesGlobals->queuedEventHash == 2)
|
||||
Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; event '%s' not found.\n", __FUNCTION__, eventName);
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void MilesCore::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourDetach(&v_AIL_LogFunc, &AIL_LogFunc);
|
||||
DetourDetach(&v_Miles_Initialize, &Miles_Initialize);
|
||||
DetourDetach(&v_MilesQueueEventRun, &MilesQueueEventRun);
|
||||
DetourDetach(&v_MilesBankPatch, &MilesBankPatch);
|
||||
DetourSetup(&v_AIL_LogFunc, &AIL_LogFunc, bAttach);
|
||||
DetourSetup(&v_Miles_Initialize, &Miles_Initialize, bAttach);
|
||||
DetourSetup(&v_MilesQueueEventRun, &MilesQueueEventRun, bAttach);
|
||||
DetourSetup(&v_MilesBankPatch, &MilesBankPatch, bAttach);
|
||||
DetourSetup(&v_CSOM_AddEventToQueue, &CSOM_AddEventToQueue, bAttach);
|
||||
}
|
@ -2,48 +2,76 @@
|
||||
#include "miles_types.h"
|
||||
|
||||
/* ==== WASAPI THREAD SERVICE =========================================================================================================================================== */
|
||||
inline CMemory p_AIL_LogFunc;
|
||||
inline void(*v_AIL_LogFunc)(int64_t nLogLevel, const char* pszMessage);
|
||||
|
||||
inline CMemory p_Miles_Initialize;
|
||||
inline bool(*v_Miles_Initialize)();
|
||||
|
||||
inline CMemory p_MilesQueueEventRun;
|
||||
inline void(*v_MilesQueueEventRun)(Miles::Queue*, const char*);
|
||||
|
||||
inline CMemory p_MilesBankPatch;
|
||||
inline void(*v_MilesBankPatch)(Miles::Bank*, char*, char*);
|
||||
inline void(*v_CSOM_AddEventToQueue)(const char* eventName);
|
||||
|
||||
struct MilesBankList_t
|
||||
{
|
||||
char banks[64][16];
|
||||
int bankCount;
|
||||
};
|
||||
|
||||
struct MilesGlobalState_t
|
||||
{
|
||||
char gap0[24];
|
||||
bool mismatchedBuildTag;
|
||||
char gap19[63];
|
||||
uintptr_t queuedEventHash;
|
||||
char gap60[4];
|
||||
Vector3D queuedSoundPosition;
|
||||
char gap70[24];
|
||||
float soundMasterVolume;
|
||||
char gap8c[28];
|
||||
void* samplesXlogType;
|
||||
char gapB0[8];
|
||||
void* dumpXlogType;
|
||||
char gapC0[48];
|
||||
void* driver;
|
||||
void* queue;
|
||||
char gap100[40];
|
||||
MilesBankList_t bankList;
|
||||
char gap52c[4];
|
||||
void* loadedBanks[16];
|
||||
char gap5b0[290448];
|
||||
HANDLE milesInitializedEvent;
|
||||
HANDLE milesThread;
|
||||
char gap47450[272];
|
||||
char milesOutputBuffer[1024];
|
||||
char unk[96];
|
||||
};
|
||||
|
||||
inline MilesGlobalState_t* g_milesGlobals;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class MilesCore : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("AIL_LogFunc", p_AIL_LogFunc.GetPtr());
|
||||
LogFunAdr("Miles_Initialize", p_Miles_Initialize.GetPtr());
|
||||
LogFunAdr("AIL_LogFunc", v_AIL_LogFunc);
|
||||
LogFunAdr("Miles_Initialize", v_Miles_Initialize);
|
||||
LogFunAdr("MilesQueueEventRun", v_MilesQueueEventRun);
|
||||
LogFunAdr("MilesBankPatch", v_MilesBankPatch);
|
||||
LogFunAdr("CSOM_AddEventToQueue", v_CSOM_AddEventToQueue);
|
||||
LogVarAdr("g_milesGlobals", g_milesGlobals);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_AIL_LogFunc = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B DA 48 8D 15 ?? ?? ?? ??");
|
||||
v_AIL_LogFunc = p_AIL_LogFunc.RCast<void(*)(int64_t, const char*)>();
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B DA 48 8D 15 ?? ?? ?? ??").GetPtr(v_AIL_LogFunc);
|
||||
g_GameDll.FindPatternSIMD("0F B6 11 4C 8B C1").GetPtr(v_CSOM_AddEventToQueue);
|
||||
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
p_Miles_Initialize = g_GameDll.FindPatternSIMD("40 53 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??");
|
||||
#else
|
||||
p_Miles_Initialize = g_GameDll.FindPatternSIMD("40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??");
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
v_Miles_Initialize = p_Miles_Initialize.RCast<bool(*)()>();
|
||||
CMemory milesInitializeFunc = g_GameDll.FindPatternSIMD("40 53 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??");
|
||||
milesInitializeFunc.GetPtr(v_Miles_Initialize);
|
||||
|
||||
p_MilesQueueEventRun = g_RadAudioSystemDll.GetExportedSymbol("MilesQueueEventRun");
|
||||
v_MilesQueueEventRun = p_MilesQueueEventRun.RCast<void(*)(Miles::Queue*, const char*)>();
|
||||
|
||||
p_MilesBankPatch = g_RadAudioSystemDll.GetExportedSymbol("MilesBankPatch");
|
||||
v_MilesBankPatch = p_MilesBankPatch.RCast<void(*)(Miles::Bank*, char*, char*)>();
|
||||
g_milesGlobals = milesInitializeFunc.FindPatternSelf("48 8D", CMemory::Direction::DOWN, 0x50).ResolveRelativeAddressSelf(0x3, 0x7).RCast<MilesGlobalState_t*>();
|
||||
|
||||
g_RadAudioSystemDll.GetExportedSymbol("MilesQueueEventRun").GetPtr(v_MilesQueueEventRun);
|
||||
g_RadAudioSystemDll.GetExportedSymbol("MilesBankPatch").GetPtr(v_MilesBankPatch);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4,6 +4,9 @@ constexpr char MILES_DEFAULT_LANGUAGE[] = "english";
|
||||
|
||||
namespace Miles
|
||||
{
|
||||
constexpr int TEMPLATEID_FLAG_SOURCE = 0x40000000;
|
||||
|
||||
|
||||
struct Queue
|
||||
{
|
||||
char gap0[0x8];
|
||||
@ -11,8 +14,107 @@ namespace Miles
|
||||
char gap10[0x20];
|
||||
};
|
||||
|
||||
struct BankHeader_t;
|
||||
|
||||
struct Source_t
|
||||
{
|
||||
BankHeader_t* bank; // reserved on disk - written at runtime
|
||||
char gap8[80];
|
||||
};
|
||||
|
||||
struct Event_t
|
||||
{
|
||||
int nameOffset;
|
||||
int unkOffset; // offset into BankHeader_t::unk_68 data - some sort of event metadata?
|
||||
};
|
||||
|
||||
// internal project data structure
|
||||
struct IntProjectData_t
|
||||
{
|
||||
char gap0[0xCF0];
|
||||
int bankCount;
|
||||
BankHeader_t** loadedBanks;
|
||||
};
|
||||
|
||||
struct BankHeader_t
|
||||
{
|
||||
int magic; // 'CBNK'
|
||||
int version; // 32
|
||||
uint32_t dataSize;
|
||||
|
||||
int bankMagic; // 'BANK'
|
||||
const char* bankName;
|
||||
|
||||
void* unk_18;
|
||||
IntProjectData_t* project;
|
||||
|
||||
void* unk_28;
|
||||
void* unk_30;
|
||||
void* unk_38;
|
||||
void* unk_40; // used to index into both sources and localised sources
|
||||
|
||||
Source_t* sources;
|
||||
Source_t* localizedSources;
|
||||
|
||||
void* unk_58;
|
||||
Event_t* events;
|
||||
|
||||
void* unk_68;
|
||||
const char* stringTable;
|
||||
|
||||
void* unk_78;
|
||||
void* unk_80;
|
||||
void* unk_88;
|
||||
|
||||
uint8_t bankIndex;
|
||||
// 3 byte padding
|
||||
|
||||
uint32_t localizedSourceCount;
|
||||
uint32_t sourceCount;
|
||||
|
||||
uint32_t patchCount;
|
||||
uint32_t eventCount;
|
||||
|
||||
uint32_t count_A4;
|
||||
uint32_t count_A8;
|
||||
uint32_t count_AC;
|
||||
|
||||
uint32_t buildTag;
|
||||
|
||||
uint32_t unk_B4;
|
||||
uint32_t someDataSize;
|
||||
|
||||
const char* GetBankName() const
|
||||
{
|
||||
return bankName;
|
||||
}
|
||||
|
||||
};
|
||||
static_assert(offsetof(BankHeader_t, project) == 0x20);
|
||||
static_assert(offsetof(BankHeader_t, stringTable) == 0x70);
|
||||
static_assert(offsetof(BankHeader_t, unk_B4) == 0xB4);
|
||||
|
||||
|
||||
struct Bank
|
||||
{
|
||||
// TODO [REXX]: map out this struct and its internal counterpart
|
||||
};
|
||||
void* internalData;
|
||||
void* unk_8;
|
||||
|
||||
char* fileData;
|
||||
|
||||
int unk_18;
|
||||
char gap_1c[4];
|
||||
|
||||
const Miles::BankHeader_t* GetHeader() const
|
||||
{
|
||||
return reinterpret_cast<Miles::BankHeader_t*>(fileData);
|
||||
}
|
||||
|
||||
const char* GetBankName() const
|
||||
{
|
||||
return GetHeader()->GetBankName();
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(Bank) == 0x20);
|
||||
}
|
@ -8,7 +8,7 @@ class VRadShal : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("WASAPI_GetAudioDevice", p_WASAPI_GetAudioDevice.GetPtr());
|
||||
LogFunAdr("WASAPI_GetAudioDevice", (void*)p_WASAPI_GetAudioDevice.GetPtr());
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
@ -17,7 +17,6 @@ class VRadShal : public IDetour
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -20,12 +20,7 @@ void* BinkOpen(HANDLE hBinkFile, UINT32 nFlags)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void BinkCore::Attach() const
|
||||
void BinkCore::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&v_BinkOpen, &BinkOpen);
|
||||
}
|
||||
|
||||
void BinkCore::Detach() const
|
||||
{
|
||||
DetourDetach(&v_BinkOpen, &BinkOpen);
|
||||
DetourSetup(&v_BinkOpen, &BinkOpen, bAttach);
|
||||
}
|
@ -1,12 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
inline CMemory p_BinkOpen;
|
||||
inline void*(*v_BinkOpen)(HANDLE hBinkFile, UINT32 nFlags);
|
||||
|
||||
inline CMemory p_BinkClose;
|
||||
inline void(*v_BinkClose)(HANDLE hBinkFile);
|
||||
|
||||
inline CMemory p_BinkGetError;
|
||||
inline const char*(*v_BinkGetError)(void);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -14,23 +9,18 @@ class BinkCore : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("BinkOpen", p_BinkOpen.GetPtr());
|
||||
LogFunAdr("BinkClose", p_BinkClose.GetPtr());
|
||||
LogFunAdr("BinkGetError", p_BinkGetError.GetPtr());
|
||||
LogFunAdr("BinkOpen", v_BinkOpen);
|
||||
LogFunAdr("BinkClose", v_BinkClose);
|
||||
LogFunAdr("BinkGetError", v_BinkGetError);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_BinkOpen = g_RadVideoToolsDll.GetExportedSymbol("BinkOpen");
|
||||
v_BinkOpen = p_BinkOpen.RCast<void*(*)(HANDLE, UINT32)>();
|
||||
p_BinkClose = g_RadVideoToolsDll.GetExportedSymbol("BinkClose");
|
||||
v_BinkClose = p_BinkClose.RCast<void(*)(HANDLE)>();
|
||||
p_BinkGetError = g_RadVideoToolsDll.GetExportedSymbol("BinkGetError");
|
||||
v_BinkGetError = p_BinkGetError.RCast<const char* (*)(void)>();
|
||||
g_RadVideoToolsDll.GetExportedSymbol("BinkOpen").GetPtr(v_BinkOpen);
|
||||
g_RadVideoToolsDll.GetExportedSymbol("BinkClose").GetPtr(v_BinkClose);
|
||||
g_RadVideoToolsDll.GetExportedSymbol("BinkGetError").GetPtr(v_BinkGetError);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,102 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
inline CMemory p_SetupGamemode;
|
||||
inline bool(*SetupGamemode)(const char* pszPlayList);
|
||||
inline bool(*v_SetupGamemode)(const char* pszPlayList);
|
||||
|
||||
/* ==== CONCOMMANDCALLBACK ============================================================================================================================================== */
|
||||
inline CMemory p_DownloadPlaylists_f;
|
||||
inline void(*_DownloadPlaylists_f)(void);
|
||||
inline void(*v__Cmd_Exec_f)(const CCommand& args);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void MP_GameMode_Changed_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void MP_HostName_Changed_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
#ifndef DEDICATED
|
||||
void ToggleConsole_f(const CCommand& args);
|
||||
void ToggleBrowser_f(const CCommand& args);
|
||||
#endif // !DEDICATED
|
||||
void MP_GameMode_Changed_f(IConVar* pConVar, const char* pOldString);
|
||||
#ifndef CLIENT_DLL
|
||||
void Host_Kick_f(const CCommand& args);
|
||||
void Host_KickID_f(const CCommand& args);
|
||||
void Host_Ban_f(const CCommand& args);
|
||||
void Host_BanID_f(const CCommand& args);
|
||||
void Host_Unban_f(const CCommand& args);
|
||||
void Host_ReloadBanList_f(const CCommand& args);
|
||||
void Host_ReloadPlaylists_f(const CCommand& args);
|
||||
void Host_Changelevel_f(const CCommand& args);
|
||||
void Detour_HotSwap_f(const CCommand& args);
|
||||
#endif // !CLIENT_DLL
|
||||
void Pak_ListPaks_f(const CCommand& args);
|
||||
void Pak_ListTypes_f(const CCommand& args);
|
||||
void Pak_RequestUnload_f(const CCommand& args);
|
||||
void Pak_RequestLoad_f(const CCommand& args);
|
||||
void Pak_Swap_f(const CCommand& args);
|
||||
void RTech_StringToGUID_f(const CCommand& args);
|
||||
void RTech_Decompress_f(const CCommand& args);
|
||||
void VPK_Pack_f(const CCommand& args);
|
||||
void VPK_Unpack_f(const CCommand& args);
|
||||
void VPK_Mount_f(const CCommand& args);
|
||||
void VPK_Unmount_f(const CCommand& args);
|
||||
void NET_SetKey_f(const CCommand& args);
|
||||
void NET_GenerateKey_f(const CCommand& args);
|
||||
void NET_UseRandomKeyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void NET_UseSocketsForLoopbackChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void SIG_GetAdr_f(const CCommand& args);
|
||||
void CON_Help_f(const CCommand& args);
|
||||
void NET_UseSocketsForLoopbackChanged_f(IConVar* pConVar, const char* pOldString);
|
||||
#ifndef DEDICATED
|
||||
void CON_LogHistory_f(const CCommand& args);
|
||||
void CON_RemoveLine_f(const CCommand& args);
|
||||
void CON_ClearLines_f(const CCommand& args);
|
||||
void CON_ClearHistory_f(const CCommand& args);
|
||||
|
||||
void RCON_CmdQuery_f(const CCommand& args);
|
||||
void RCON_Disconnect_f(const CCommand& args);
|
||||
void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString);
|
||||
#endif // !DEDICATED
|
||||
void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
#ifndef CLIENT_DLL
|
||||
void SV_LanguageChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void RCON_WhiteListAddresChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void RCON_ConnectionCountChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
|
||||
void SQVM_ServerScript_f(const CCommand& args);
|
||||
#endif // !CLIENT_DLL
|
||||
void LanguageChanged_f(IConVar* pConVar, const char* pOldString);
|
||||
#ifndef DEDICATED
|
||||
void SQVM_ClientScript_f(const CCommand& args);
|
||||
void SQVM_UIScript_f(const CCommand& args);
|
||||
void Mat_CrossHair_f(const CCommand& args);
|
||||
void Line_f(const CCommand& args);
|
||||
void Sphere_f(const CCommand& args);
|
||||
void Capsule_f(const CCommand& args);
|
||||
#endif // !DEDICATED
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
||||
void BHit_f(const CCommand& args);
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
|
||||
void CVHelp_f(const CCommand& args);
|
||||
void CVList_f(const CCommand& args);
|
||||
void CVDiff_f(const CCommand& args);
|
||||
void CVFlag_f(const CCommand& args);
|
||||
#ifndef CLIENT_DLL
|
||||
void CC_CreateFakePlayer_f(const CCommand& args);
|
||||
#endif // !CLIENT_DLL
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCallback : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("SetupGamemode", p_SetupGamemode.GetPtr());
|
||||
LogFunAdr("DownloadPlaylist_f", p_DownloadPlaylists_f.GetPtr());
|
||||
LogFunAdr("SetupGamemode", v_SetupGamemode);
|
||||
LogFunAdr("Cmd_Exec_f", v__Cmd_Exec_f);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_SetupGamemode = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B D9 48 C7 C0 ?? ?? ?? ??");
|
||||
p_DownloadPlaylists_f = g_GameDll.FindPatternSIMD("33 C9 C6 05 ?? ?? ?? ?? ?? E9 ?? ?? ?? ??");
|
||||
|
||||
SetupGamemode = p_SetupGamemode.RCast<bool(*)(const char*)>(); /*40 53 48 83 EC 20 48 8B D9 48 C7 C0 ?? ?? ?? ??*/
|
||||
_DownloadPlaylists_f = p_DownloadPlaylists_f.RCast<void(*)(void)>(); /*33 C9 C6 05 ?? ?? ?? ?? ?? E9 ?? ?? ?? ??*/
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B D9 48 C7 C0 ?? ?? ?? ??").GetPtr(v_SetupGamemode);
|
||||
g_GameDll.FindPatternSIMD("40 55 53 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9").GetPtr(v__Cmd_Exec_f);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -27,7 +27,7 @@ int _Host_Map_f_CompletionFunc(char const* cmdname, char const* partial, char co
|
||||
substring = (char*)partial + strlen(cmdname);
|
||||
}
|
||||
|
||||
const int mapcount = (int)g_InstalledMaps.size();
|
||||
const int mapcount = g_InstalledMaps.Count();
|
||||
const int longest = COMMAND_COMPLETION_ITEM_LENGTH;
|
||||
const int count = MIN(mapcount, COMMAND_COMPLETION_MAXITEMS);
|
||||
|
||||
@ -36,9 +36,9 @@ int _Host_Map_f_CompletionFunc(char const* cmdname, char const* partial, char co
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (strstr(g_InstalledMaps[i].c_str(), substring))
|
||||
if (strstr(g_InstalledMaps[i].String(), substring))
|
||||
{
|
||||
strncpy(commands[filtered_count], g_InstalledMaps[i].c_str(), longest);
|
||||
strncpy(commands[filtered_count], g_InstalledMaps[i].String(), longest);
|
||||
|
||||
char old[COMMAND_COMPLETION_ITEM_LENGTH];
|
||||
strncpy(old, commands[filtered_count], sizeof(old));
|
||||
@ -170,6 +170,18 @@ int RTech_PakUnload_f_CompletionFunc(char const* partial, char commands[COMMAND_
|
||||
return _Host_Pak_f_CompletionFunc(&s_PakUnloadAutoFileList, partial, commands);
|
||||
}
|
||||
|
||||
static CBaseAutoCompleteFileList s_PakCompress("pak_compress", "paks/Win64_override", "rpak");
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *partial -
|
||||
// **commands -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int RTech_PakCompress_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])
|
||||
{
|
||||
return _Host_Pak_f_CompletionFunc(&s_PakCompress, partial, commands);
|
||||
}
|
||||
|
||||
static CBaseAutoCompleteFileList s_PakDecompress("pak_decompress", "paks/Win64", "rpak");
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
|
@ -11,10 +11,10 @@ int Game_Give_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLE
|
||||
|
||||
int RTech_PakLoad_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
||||
int RTech_PakUnload_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
||||
int RTech_PakCompress_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
||||
int RTech_PakDecompress_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
||||
|
||||
inline CMemory p_CBaseAutoCompleteFileList_AutoCompletionFunc;
|
||||
inline int(*v_CBaseAutoCompleteFileList_AutoCompletionFunc)
|
||||
inline int(*CBaseAutoCompleteFileList__AutoCompletionFunc)
|
||||
(CBaseAutoCompleteFileList* thisp, const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -22,21 +22,14 @@ class VCompletion : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CBaseAutoCompleteFileList::AutoCompletionFunc", p_CBaseAutoCompleteFileList_AutoCompletionFunc.GetPtr());
|
||||
LogFunAdr("CBaseAutoCompleteFileList::AutoCompletionFunc", CBaseAutoCompleteFileList__AutoCompletionFunc);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CBaseAutoCompleteFileList_AutoCompletionFunc = g_GameDll.FindPatternSIMD("40 55 53 57 41 54 41 55 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 48 8B 39");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CBaseAutoCompleteFileList_AutoCompletionFunc = g_GameDll.FindPatternSIMD("48 8B C4 4C 89 40 18 55 41 54");
|
||||
#endif
|
||||
v_CBaseAutoCompleteFileList_AutoCompletionFunc = p_CBaseAutoCompleteFileList_AutoCompletionFunc.RCast<int(*)(
|
||||
CBaseAutoCompleteFileList*, const char*, char[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])>();
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 4C 89 40 18 55 41 54").GetPtr(CBaseAutoCompleteFileList__AutoCompletionFunc);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -10,9 +10,13 @@
|
||||
#include "callback.h"
|
||||
#include "global.h"
|
||||
|
||||
|
||||
ConVar curl_debug("curl_debug", "0", FCVAR_DEVELOPMENTONLY, "Determines whether or not to enable curl debug logging.", "1 = curl logs; 0 (zero) = no logs");
|
||||
ConVar curl_timeout("curl_timeout", "15", FCVAR_DEVELOPMENTONLY, "Maximum time in seconds a curl transfer operation could take.");
|
||||
ConVar ssl_verify_peer("ssl_verify_peer", "1", FCVAR_DEVELOPMENTONLY, "Verify the authenticity of the peer's SSL certificate.", "1 = curl verifies; 0 (zero) = no verification");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ENGINE |
|
||||
ConVar* sdk_fixedframe_tickinterval = nullptr;
|
||||
ConVar* single_frame_shutdown_for_reload = nullptr;
|
||||
ConVar* old_gather_props = nullptr;
|
||||
|
||||
@ -21,12 +25,14 @@ ConVar* debug_draw_box_depth_test = nullptr;
|
||||
|
||||
ConVar* developer = nullptr;
|
||||
ConVar* fps_max = nullptr;
|
||||
ConVar* fps_max_vsync = nullptr;
|
||||
|
||||
// Taken from S15:
|
||||
ConVar* usercmd_frametime_max = nullptr;
|
||||
ConVar* usercmd_frametime_min = nullptr;
|
||||
#ifndef DEDICATED
|
||||
ConVar* in_syncRT = nullptr;
|
||||
#endif // !DEDICATED
|
||||
|
||||
ConVar* usercmd_dualwield_enable = nullptr;
|
||||
ConVar* base_tickinterval_sp = nullptr;
|
||||
ConVar* base_tickinterval_mp = nullptr;
|
||||
|
||||
ConVar* staticProp_no_fade_scalar = nullptr;
|
||||
ConVar* staticProp_gather_size_weight = nullptr;
|
||||
@ -36,7 +42,6 @@ ConVar* model_defaultFadeDistMin = nullptr;
|
||||
|
||||
ConVar* ip_cvar = nullptr;
|
||||
ConVar* hostname = nullptr;
|
||||
ConVar* hostdesc = nullptr;
|
||||
ConVar* hostip = nullptr;
|
||||
ConVar* hostport = nullptr;
|
||||
|
||||
@ -45,17 +50,6 @@ ConVar* host_timescale = nullptr;
|
||||
|
||||
ConVar* mp_gamemode = nullptr;
|
||||
|
||||
ConVar* rcon_address = nullptr;
|
||||
ConVar* rcon_password = nullptr;
|
||||
|
||||
ConVar* r_debug_overlay_nodecay = nullptr;
|
||||
ConVar* r_debug_overlay_invisible = nullptr;
|
||||
ConVar* r_debug_overlay_wireframe = nullptr;
|
||||
ConVar* r_debug_draw_depth_test = nullptr;
|
||||
ConVar* r_drawWorldMeshes = nullptr;
|
||||
ConVar* r_drawWorldMeshesDepthOnly = nullptr;
|
||||
ConVar* r_drawWorldMeshesDepthAtTheEnd = nullptr;
|
||||
|
||||
#ifndef DEDICATED
|
||||
ConVar* r_visualizetraces = nullptr;
|
||||
ConVar* r_visualizetraces_duration = nullptr;
|
||||
@ -63,399 +57,75 @@ ConVar* r_visualizetraces_duration = nullptr;
|
||||
|
||||
ConVar* stream_overlay = nullptr;
|
||||
ConVar* stream_overlay_mode = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
// SHARED |
|
||||
ConVar* modsystem_enable = nullptr;
|
||||
ConVar* modsystem_debug = nullptr;
|
||||
|
||||
ConVar* eula_version = nullptr;
|
||||
ConVar* eula_version_accepted = nullptr;
|
||||
|
||||
ConVar* language_cvar = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SERVER |
|
||||
#ifndef CLIENT_DLL
|
||||
ConVar* ai_ainDumpOnLoad = nullptr;
|
||||
ConVar* ai_ainDebugConnect = nullptr;
|
||||
ConVar* ai_script_nodes_draw = nullptr;
|
||||
ConVar* ai_script_nodes_draw_range = nullptr;
|
||||
ConVar* ai_script_nodes_draw_nearest = nullptr;
|
||||
|
||||
ConVar* navmesh_always_reachable = nullptr;
|
||||
ConVar* navmesh_debug_type = nullptr;
|
||||
ConVar* navmesh_debug_tile_range = nullptr;
|
||||
ConVar* navmesh_debug_camera_range = nullptr;
|
||||
#ifndef DEDICATED
|
||||
ConVar* navmesh_draw_bvtree = nullptr;
|
||||
ConVar* navmesh_draw_portal = nullptr;
|
||||
ConVar* navmesh_draw_polys = nullptr;
|
||||
ConVar* navmesh_draw_poly_bounds = nullptr;
|
||||
ConVar* navmesh_draw_poly_bounds_inner = nullptr;
|
||||
#endif // !DEDICATED
|
||||
|
||||
ConVar* sv_language = nullptr;
|
||||
|
||||
ConVar* sv_showconnecting = nullptr;
|
||||
ConVar* sv_globalBanlist = nullptr;
|
||||
ConVar* sv_pylonVisibility = nullptr;
|
||||
ConVar* sv_pylonRefreshRate = nullptr;
|
||||
ConVar* sv_banlistRefreshRate = nullptr;
|
||||
ConVar* sv_statusRefreshRate = nullptr;
|
||||
ConVar* sv_forceChatToTeamOnly = nullptr;
|
||||
|
||||
ConVar* sv_single_core_dedi = nullptr;
|
||||
|
||||
ConVar* sv_updaterate_mp = nullptr;
|
||||
ConVar* sv_updaterate_sp = nullptr;
|
||||
ConVar* sv_autoReloadRate = nullptr;
|
||||
ConVar* sv_maxunlag = nullptr;
|
||||
ConVar* sv_clockcorrection_msecs = nullptr;
|
||||
|
||||
ConVar* sv_updaterate_sp = nullptr;
|
||||
ConVar* sv_updaterate_mp = nullptr;
|
||||
|
||||
ConVar* sv_simulateBots = nullptr;
|
||||
ConVar* sv_showhitboxes = nullptr;
|
||||
ConVar* sv_stats = nullptr;
|
||||
|
||||
ConVar* sv_quota_stringCmdsPerSecond = nullptr;
|
||||
|
||||
ConVar* sv_validatePersonaName = nullptr;
|
||||
ConVar* sv_minPersonaNameLength = nullptr;
|
||||
ConVar* sv_maxPersonaNameLength = nullptr;
|
||||
|
||||
ConVar* sv_voiceEcho = nullptr;
|
||||
ConVar* sv_voiceenable = nullptr;
|
||||
ConVar* sv_alltalk = nullptr;
|
||||
|
||||
ConVar* player_userCmdsQueueWarning = nullptr;
|
||||
|
||||
//#ifdef DEDICATED
|
||||
ConVar* sv_rcon_debug = nullptr;
|
||||
ConVar* sv_rcon_sendlogs = nullptr;
|
||||
//ConVar* sv_rcon_banpenalty = nullptr; // TODO
|
||||
ConVar* sv_rcon_maxfailures = nullptr;
|
||||
ConVar* sv_rcon_maxignores = nullptr;
|
||||
ConVar* sv_rcon_maxsockets = nullptr;
|
||||
ConVar* sv_rcon_maxconnections = nullptr;
|
||||
ConVar* sv_rcon_maxpacketsize = nullptr;
|
||||
ConVar* sv_rcon_whitelist_address = nullptr;
|
||||
//#endif // DEDICATED
|
||||
#endif // !CLIENT_DLL
|
||||
ConVar* sv_cheats = nullptr;
|
||||
ConVar* sv_visualizetraces = nullptr;
|
||||
ConVar* sv_visualizetraces_duration = nullptr;
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
||||
ConVar* bhit_enable = nullptr;
|
||||
ConVar* bhit_depth_test = nullptr;
|
||||
ConVar* bhit_abs_origin = nullptr;
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
//-----------------------------------------------------------------------------
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
ConVar* cl_rcon_inputonly = nullptr;
|
||||
ConVar* cl_quota_stringCmdsPerSecond = nullptr;
|
||||
|
||||
ConVar* cl_cmdrate = nullptr;
|
||||
ConVar* cl_move_use_dt = nullptr;
|
||||
|
||||
ConVar* cl_notify_invert_x = nullptr;
|
||||
ConVar* cl_notify_invert_y = nullptr;
|
||||
ConVar* cl_notify_offset_x = nullptr;
|
||||
ConVar* cl_notify_offset_y = nullptr;
|
||||
|
||||
ConVar* cl_showsimstats = nullptr;
|
||||
ConVar* cl_simstats_invert_x = nullptr;
|
||||
ConVar* cl_simstats_invert_y = nullptr;
|
||||
ConVar* cl_simstats_offset_x = nullptr;
|
||||
ConVar* cl_simstats_offset_y = nullptr;
|
||||
|
||||
ConVar* cl_showgpustats = nullptr;
|
||||
ConVar* cl_gpustats_invert_x = nullptr;
|
||||
ConVar* cl_gpustats_invert_y = nullptr;
|
||||
ConVar* cl_gpustats_offset_x = nullptr;
|
||||
ConVar* cl_gpustats_offset_y = nullptr;
|
||||
|
||||
ConVar* cl_showmaterialinfo = nullptr;
|
||||
ConVar* cl_materialinfo_offset_x = nullptr;
|
||||
ConVar* cl_materialinfo_offset_y = nullptr;
|
||||
ConVar* cl_updaterate_mp = nullptr;
|
||||
|
||||
ConVar* cl_threaded_bone_setup = nullptr;
|
||||
|
||||
ConVar* con_drawnotify = nullptr;
|
||||
ConVar* con_notifylines = nullptr;
|
||||
ConVar* con_notifytime = nullptr;
|
||||
|
||||
ConVar* con_notify_invert_x = nullptr;
|
||||
ConVar* con_notify_invert_y = nullptr;
|
||||
ConVar* con_notify_offset_x = nullptr;
|
||||
ConVar* con_notify_offset_y = nullptr;
|
||||
|
||||
ConVar* con_notify_script_server_clr = nullptr;
|
||||
ConVar* con_notify_script_client_clr = nullptr;
|
||||
ConVar* con_notify_script_ui_clr = nullptr;
|
||||
ConVar* con_notify_native_server_clr = nullptr;
|
||||
ConVar* con_notify_native_client_clr = nullptr;
|
||||
ConVar* con_notify_native_ui_clr = nullptr;
|
||||
ConVar* con_notify_native_engine_clr = nullptr;
|
||||
ConVar* con_notify_native_fs_clr = nullptr;
|
||||
ConVar* con_notify_native_rtech_clr = nullptr;
|
||||
ConVar* con_notify_native_ms_clr = nullptr;
|
||||
ConVar* con_notify_native_audio_clr = nullptr;
|
||||
ConVar* con_notify_native_video_clr = nullptr;
|
||||
ConVar* con_notify_netcon_clr = nullptr;
|
||||
ConVar* con_notify_common_clr = nullptr;
|
||||
ConVar* con_notify_warning_clr = nullptr;
|
||||
ConVar* con_notify_error_clr = nullptr;
|
||||
|
||||
ConVar* con_max_lines = nullptr;
|
||||
ConVar* con_max_history = nullptr;
|
||||
ConVar* con_suggest_limit = nullptr;
|
||||
ConVar* con_suggest_showhelptext = nullptr;
|
||||
ConVar* con_suggest_showflags = nullptr;
|
||||
|
||||
ConVar* origin_disconnectWhenOffline = nullptr;
|
||||
ConVar* discord_updatePresence = nullptr;
|
||||
|
||||
ConVar* serverbrowser_hideEmptyServers = nullptr;
|
||||
ConVar* serverbrowser_mapFilter = nullptr;
|
||||
ConVar* serverbrowser_gamemodeFilter = nullptr;
|
||||
#endif // !DEDICATED
|
||||
//-----------------------------------------------------------------------------
|
||||
// FILESYSTEM |
|
||||
ConVar* fs_showWarnings = nullptr;
|
||||
ConVar* fs_showAllReads = nullptr;
|
||||
ConVar* fs_packedstore_entryblock_stats = nullptr;
|
||||
ConVar* fs_packedstore_workspace = nullptr;
|
||||
ConVar* fs_packedstore_compression_level = nullptr;
|
||||
ConVar* fs_packedstore_max_helper_threads = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
// MATERIALSYSTEM |
|
||||
#ifndef DEDICATED
|
||||
ConVar* mat_alwaysComplain = nullptr;
|
||||
#endif // !DEDICATED
|
||||
//-----------------------------------------------------------------------------
|
||||
// SQUIRREL |
|
||||
ConVar* script_show_output = nullptr;
|
||||
ConVar* script_show_warning = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
// NETCHANNEL |
|
||||
ConVar* net_tracePayload = nullptr;
|
||||
ConVar* net_encryptionEnable = nullptr;
|
||||
ConVar* net_useRandomKey = nullptr;
|
||||
ConVar* net_usesocketsforloopback = nullptr;
|
||||
ConVar* net_processTimeBudget = nullptr;
|
||||
|
||||
ConVar* net_usesocketsforloopback;
|
||||
ConVar* net_data_block_enabled = nullptr;
|
||||
ConVar* net_datablock_networkLossForSlowSpeed = nullptr;
|
||||
ConVar* net_compressDataBlock = nullptr;
|
||||
|
||||
ConVar* pylon_matchmaking_hostname = nullptr;
|
||||
ConVar* pylon_host_update_interval = nullptr;
|
||||
ConVar* pylon_showdebuginfo = nullptr;
|
||||
|
||||
ConVar* ssl_verify_peer = nullptr;
|
||||
ConVar* curl_timeout = nullptr;
|
||||
ConVar* curl_debug = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
// RTECH API |
|
||||
ConVar* rtech_debug = nullptr;
|
||||
ConVar* net_showmsg = nullptr;
|
||||
ConVar* net_blockmsg = nullptr;
|
||||
ConVar* net_showpeaks = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
// RUI |
|
||||
#ifndef DEDICATED
|
||||
ConVar* rui_drawEnable = nullptr;
|
||||
ConVar* rui_defaultDebugFontFace = nullptr;
|
||||
#endif // !DEDICATED
|
||||
//-----------------------------------------------------------------------------
|
||||
// MILES |
|
||||
#ifndef DEDICATED
|
||||
ConVar* miles_debug = nullptr;
|
||||
ConVar* miles_language = nullptr;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: initialize ConVar's
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_StaticInit(void)
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// ENGINE |
|
||||
hostdesc = ConVar::StaticCreate("hostdesc", "", FCVAR_RELEASE, "Host game server description.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sdk_fixedframe_tickinterval = ConVar::StaticCreate("sdk_fixedframe_tickinterval", "0.01", FCVAR_RELEASE, "The tick interval used by the SDK fixed frame.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
curl_debug = ConVar::StaticCreate("curl_debug" , "0" , FCVAR_DEVELOPMENTONLY, "Determines whether or not to enable curl debug logging.", false, 0.f, false, 0.f, nullptr, "1 = curl logs; 0 (zero) = no logs");
|
||||
curl_timeout = ConVar::StaticCreate("curl_timeout" , "15", FCVAR_DEVELOPMENTONLY, "Maximum time in seconds a curl transfer operation could take.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
ssl_verify_peer = ConVar::StaticCreate("ssl_verify_peer", "1" , FCVAR_DEVELOPMENTONLY, "Verify the authenticity of the peer's SSL certificate.", false, 0.f, false, 0.f, nullptr, "1 = curl verifies; 0 (zero) = no verification");
|
||||
|
||||
rcon_address = ConVar::StaticCreate("rcon_address", "[loopback]:37015", FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access address.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
rcon_password = ConVar::StaticCreate("rcon_password", "" , FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access password (rcon is disabled if empty).", false, 0.f, false, 0.f, &RCON_PasswordChanged_f, nullptr);
|
||||
|
||||
r_debug_overlay_nodecay = ConVar::StaticCreate("r_debug_overlay_nodecay" , "0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Keeps all debug overlays alive regardless of their lifetime. Use command 'clear_debug_overlays' to clear everything.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
r_debug_overlay_invisible = ConVar::StaticCreate("r_debug_overlay_invisible" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Show invisible debug overlays (alpha < 1 = 255).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
r_debug_overlay_wireframe = ConVar::StaticCreate("r_debug_overlay_wireframe" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Use wireframe in debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
r_debug_draw_depth_test = ConVar::StaticCreate("r_debug_draw_depth_test" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Toggle depth test for other debug draw functionality.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
r_drawWorldMeshes = ConVar::StaticCreate("r_drawWorldMeshes" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
r_drawWorldMeshesDepthOnly = ConVar::StaticCreate("r_drawWorldMeshesDepthOnly" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes (depth only).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
r_drawWorldMeshesDepthAtTheEnd = ConVar::StaticCreate("r_drawWorldMeshesDepthAtTheEnd", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes (depth at the end).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// SHARED |
|
||||
modsystem_enable = ConVar::StaticCreate("modsystem_enable", "1", FCVAR_RELEASE, "Enable the modsystem.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
modsystem_debug = ConVar::StaticCreate("modsystem_debug" , "0", FCVAR_RELEASE, "Debug the modsystem." , false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// SERVER |
|
||||
#ifndef CLIENT_DLL
|
||||
ai_ainDumpOnLoad = ConVar::StaticCreate("ai_ainDumpOnLoad" , "0", FCVAR_DEVELOPMENTONLY, "Dumps AIN data from node graphs loaded from the disk on load.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
ai_ainDebugConnect = ConVar::StaticCreate("ai_ainDebugConnect" , "0", FCVAR_DEVELOPMENTONLY, "Debug AIN node connections.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
ai_script_nodes_draw_range = ConVar::StaticCreate("ai_script_nodes_draw_range" , "0", FCVAR_DEVELOPMENTONLY, "Debug draw AIN script nodes ranging from shift index to this cvar.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
ai_script_nodes_draw_nearest = ConVar::StaticCreate("ai_script_nodes_draw_nearest", "1", FCVAR_DEVELOPMENTONLY, "Debug draw AIN script node links to nearest node (build order is used if null).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
navmesh_always_reachable = ConVar::StaticCreate("navmesh_always_reachable" , "0" , FCVAR_DEVELOPMENTONLY, "Marks goal poly from agent poly as reachable regardless of table data ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
navmesh_debug_type = ConVar::StaticCreate("navmesh_debug_type" , "0" , FCVAR_DEVELOPMENTONLY, "NavMesh debug draw hull index.", true, 0.f, true, 4.f, nullptr, "0 = small, 1 = med_short, 2 = medium, 3 = large, 4 = extra large");
|
||||
navmesh_debug_tile_range = ConVar::StaticCreate("navmesh_debug_tile_range" , "0" , FCVAR_DEVELOPMENTONLY, "NavMesh debug draw tiles ranging from shift index to this cvar.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
navmesh_debug_camera_range = ConVar::StaticCreate("navmesh_debug_camera_range" , "2000" , FCVAR_DEVELOPMENTONLY, "Only debug draw tiles within this distance from camera origin.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
#ifndef DEDICATED
|
||||
navmesh_draw_bvtree = ConVar::StaticCreate("navmesh_draw_bvtree" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the BVTree of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
|
||||
navmesh_draw_portal = ConVar::StaticCreate("navmesh_draw_portal" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the portal of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
|
||||
navmesh_draw_polys = ConVar::StaticCreate("navmesh_draw_polys" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the polys of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
|
||||
navmesh_draw_poly_bounds = ConVar::StaticCreate("navmesh_draw_poly_bounds" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the bounds of the NavMesh polys.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
|
||||
navmesh_draw_poly_bounds_inner = ConVar::StaticCreate("navmesh_draw_poly_bounds_inner" , "0" , FCVAR_DEVELOPMENTONLY, "Draws the inner bounds of the NavMesh polys (requires navmesh_draw_poly_bounds).", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
|
||||
#endif // !DEDICATED
|
||||
|
||||
sv_language = ConVar::StaticCreate("sv_language", "english", FCVAR_RELEASE, "Language of the server. Sent to MasterServer for localising error messages.", false, 0.f, false, 0.f, SV_LanguageChanged_f, nullptr);
|
||||
sv_showconnecting = ConVar::StaticCreate("sv_showconnecting" , "1", FCVAR_RELEASE, "Logs information about the connecting client to the console.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_globalBanlist = ConVar::StaticCreate("sv_globalBanlist" , "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, nullptr, "0 = Disable, 1 = Enable.");
|
||||
sv_pylonVisibility = ConVar::StaticCreate("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", false, 0.f, false, 0.f, nullptr, "0 = Offline, 1 = Hidden, 2 = Public.");
|
||||
sv_pylonRefreshRate = ConVar::StaticCreate("sv_pylonRefreshRate" , "5.0" , FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds).", true, 2.f, true, 8.f, nullptr, nullptr);
|
||||
sv_banlistRefreshRate = ConVar::StaticCreate("sv_banlistRefreshRate", "30.0", FCVAR_DEVELOPMENTONLY, "Banned list refresh rate (seconds).", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
sv_statusRefreshRate = ConVar::StaticCreate("sv_statusRefreshRate" , "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_autoReloadRate = ConVar::StaticCreate("sv_autoReloadRate" , "0" , FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null).", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_simulateBots = ConVar::StaticCreate("sv_simulateBots", "1", FCVAR_RELEASE, "Simulate user commands for bots on the server.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
sv_rcon_debug = ConVar::StaticCreate("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_sendlogs = ConVar::StaticCreate("sv_rcon_sendlogs" , "0" , FCVAR_RELEASE, "Network console logs to connected and authenticated sockets.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
//sv_rcon_banpenalty = ConVar::StaticCreate("sv_rcon_banpenalty" , "10", FCVAR_RELEASE, "Number of minutes to ban users who fail rcon authentication.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_maxfailures = ConVar::StaticCreate("sv_rcon_maxfailures", "10", FCVAR_RELEASE, "Max number of times an user can fail rcon authentication before being banned.", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_maxignores = ConVar::StaticCreate("sv_rcon_maxignores" , "15", FCVAR_RELEASE, "Max number of times an user can ignore the instruction message before being banned.", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_maxsockets = ConVar::StaticCreate("sv_rcon_maxsockets" , "32", FCVAR_RELEASE, "Max number of accepted sockets before the server starts closing redundant sockets.", true, 1.f, true, MAX_PLAYERS, nullptr, nullptr);
|
||||
sv_rcon_maxconnections = ConVar::StaticCreate("sv_rcon_maxconnections" , "1" , FCVAR_RELEASE, "Max number of authenticated connections before the server closes the listen socket.", true, 1.f, true, MAX_PLAYERS, &RCON_ConnectionCountChanged_f, nullptr);
|
||||
sv_rcon_maxpacketsize = ConVar::StaticCreate("sv_rcon_maxpacketsize" , "1024", FCVAR_RELEASE, "Max number of bytes allowed in a command packet from a non-authenticated netconsole.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_whitelist_address = ConVar::StaticCreate("sv_rcon_whitelist_address", "" , FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentication attempts.", false, 0.f, false, 0.f, &RCON_WhiteListAddresChanged_f, "Format: '::ffff:127.0.0.1'");
|
||||
|
||||
sv_quota_stringCmdsPerSecond = ConVar::StaticCreate("sv_quota_stringCmdsPerSecond", "16", FCVAR_RELEASE, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_validatePersonaName = ConVar::StaticCreate("sv_validatePersonaName" , "1" , FCVAR_RELEASE, "Validate the client's textual persona name on connect.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_minPersonaNameLength = ConVar::StaticCreate("sv_minPersonaNameLength", "4" , FCVAR_RELEASE, "The minimum length of the client's textual persona name.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_maxPersonaNameLength = ConVar::StaticCreate("sv_maxPersonaNameLength", "16", FCVAR_RELEASE, "The maximum length of the client's textual persona name.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
#endif // !CLIENT_DLL
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
||||
bhit_depth_test = ConVar::StaticCreate("bhit_depth_test", "0", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Use depth test for bullet ray trace overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
bhit_abs_origin = ConVar::StaticCreate("bhit_abs_origin", "1", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Draw entity's predicted abs origin upon bullet impact for trajectory debugging (requires 'r_visualizetraces' to be set!).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
//-------------------------------------------------------------------------
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
cl_rcon_inputonly = ConVar::StaticCreate("cl_rcon_inputonly", "0" , FCVAR_RELEASE, "Tells the rcon server whether or not we are input only.", false, 0.f, false, 0.f, RCON_InputOnlyChanged_f, nullptr);
|
||||
cl_quota_stringCmdsPerSecond = ConVar::StaticCreate("cl_quota_stringCmdsPerSecond", "16" , FCVAR_RELEASE, "How many string commands per second user is allowed to submit, 0 to allow all submissions.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
cl_notify_invert_x = ConVar::StaticCreate("cl_notify_invert_x", "0", FCVAR_DEVELOPMENTONLY, "Inverts the X offset for console notify debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_notify_invert_y = ConVar::StaticCreate("cl_notify_invert_y", "0", FCVAR_DEVELOPMENTONLY, "Inverts the Y offset for console notify debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_notify_offset_x = ConVar::StaticCreate("cl_notify_offset_x", "10", FCVAR_DEVELOPMENTONLY, "X offset for console notify debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_notify_offset_y = ConVar::StaticCreate("cl_notify_offset_y", "10", FCVAR_DEVELOPMENTONLY, "Y offset for console notify debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
cl_showsimstats = ConVar::StaticCreate("cl_showsimstats" , "0" , FCVAR_DEVELOPMENTONLY, "Shows the tick counter for the server/client simulation and the render frame.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_simstats_invert_x = ConVar::StaticCreate("cl_simstats_invert_x", "1" , FCVAR_DEVELOPMENTONLY, "Inverts the X offset for simulation debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_simstats_invert_y = ConVar::StaticCreate("cl_simstats_invert_y", "1" , FCVAR_DEVELOPMENTONLY, "Inverts the Y offset for simulation debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_simstats_offset_x = ConVar::StaticCreate("cl_simstats_offset_x", "650", FCVAR_DEVELOPMENTONLY, "X offset for simulation debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_simstats_offset_y = ConVar::StaticCreate("cl_simstats_offset_y", "120", FCVAR_DEVELOPMENTONLY, "Y offset for simulation debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
cl_showgpustats = ConVar::StaticCreate("cl_showgpustats" , "0", FCVAR_DEVELOPMENTONLY, "Texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_gpustats_invert_x = ConVar::StaticCreate("cl_gpustats_invert_x", "1", FCVAR_DEVELOPMENTONLY, "Inverts the X offset for texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_gpustats_invert_y = ConVar::StaticCreate("cl_gpustats_invert_y", "1", FCVAR_DEVELOPMENTONLY, "Inverts the Y offset for texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_gpustats_offset_x = ConVar::StaticCreate("cl_gpustats_offset_x", "650", FCVAR_DEVELOPMENTONLY, "X offset for texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_gpustats_offset_y = ConVar::StaticCreate("cl_gpustats_offset_y", "105", FCVAR_DEVELOPMENTONLY, "Y offset for texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
cl_showmaterialinfo = ConVar::StaticCreate("cl_showmaterialinfo" , "0" , FCVAR_DEVELOPMENTONLY, "Draw info for the material under the crosshair on screen.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_materialinfo_offset_x = ConVar::StaticCreate("cl_materialinfo_offset_x", "0" , FCVAR_DEVELOPMENTONLY, "X offset for material debug info overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
cl_materialinfo_offset_y = ConVar::StaticCreate("cl_materialinfo_offset_y", "420", FCVAR_DEVELOPMENTONLY, "Y offset for material debug info overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
con_drawnotify = ConVar::StaticCreate("con_drawnotify", "0", FCVAR_RELEASE, "Draws the RUI console to the hud.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
con_notifylines = ConVar::StaticCreate("con_notifylines" , "3" , FCVAR_MATERIAL_SYSTEM_THREAD, "Number of console lines to overlay for debugging.", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
con_notifytime = ConVar::StaticCreate("con_notifytime" , "6" , FCVAR_MATERIAL_SYSTEM_THREAD, "How long to display recent console text to the upper part of the game window.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
|
||||
con_notify_invert_x = ConVar::StaticCreate("con_notify_invert_x", "0" , FCVAR_MATERIAL_SYSTEM_THREAD, "Inverts the X offset for RUI console overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
con_notify_invert_y = ConVar::StaticCreate("con_notify_invert_y", "0" , FCVAR_MATERIAL_SYSTEM_THREAD, "Inverts the Y offset for RUI console overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
con_notify_offset_x = ConVar::StaticCreate("con_notify_offset_x", "10", FCVAR_MATERIAL_SYSTEM_THREAD, "X offset for RUI console overlay.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_offset_y = ConVar::StaticCreate("con_notify_offset_y", "10", FCVAR_MATERIAL_SYSTEM_THREAD, "Y offset for RUI console overlay.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
|
||||
con_notify_script_server_clr = ConVar::StaticCreate("con_notify_script_server_clr", "130 120 245 255", FCVAR_MATERIAL_SYSTEM_THREAD, "Script SERVER VM RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_script_client_clr = ConVar::StaticCreate("con_notify_script_client_clr", "117 116 139 255", FCVAR_MATERIAL_SYSTEM_THREAD, "Script CLIENT VM RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_script_ui_clr = ConVar::StaticCreate("con_notify_script_ui_clr" , "200 110 110 255", FCVAR_MATERIAL_SYSTEM_THREAD, "Script UI VM RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
|
||||
con_notify_native_server_clr = ConVar::StaticCreate("con_notify_native_server_clr", "20 50 248 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native SERVER RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_client_clr = ConVar::StaticCreate("con_notify_native_client_clr", "70 70 70 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native CLIENT RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_ui_clr = ConVar::StaticCreate("con_notify_native_ui_clr" , "200 60 60 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native UI RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_engine_clr = ConVar::StaticCreate("con_notify_native_engine_clr", "255 255 255 255", FCVAR_MATERIAL_SYSTEM_THREAD, "Native engine RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_fs_clr = ConVar::StaticCreate("con_notify_native_fs_clr" , "0 100 225 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native FileSystem RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_rtech_clr = ConVar::StaticCreate("con_notify_native_rtech_clr" , "25 120 20 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native RTech RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_ms_clr = ConVar::StaticCreate("con_notify_native_ms_clr" , "200 20 180 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native MaterialSystem RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_audio_clr = ConVar::StaticCreate("con_notify_native_audio_clr" , "238 43 10 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native AudioSystem RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_native_video_clr = ConVar::StaticCreate("con_notify_native_video_clr" , "115 0 235 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Native VideoSystem RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
|
||||
con_notify_netcon_clr = ConVar::StaticCreate("con_notify_netcon_clr" , "255 255 255 255", FCVAR_MATERIAL_SYSTEM_THREAD, "Netconsole RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_common_clr = ConVar::StaticCreate("con_notify_common_clr" , "255 140 80 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Common RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
|
||||
con_notify_warning_clr = ConVar::StaticCreate("con_notify_warning_clr", "180 180 20 255", FCVAR_MATERIAL_SYSTEM_THREAD, "Warning RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
con_notify_error_clr = ConVar::StaticCreate("con_notify_error_clr" , "225 20 20 255" , FCVAR_MATERIAL_SYSTEM_THREAD, "Error RUI console overlay log color.", false, 1.f, false, 50.f, nullptr, nullptr);
|
||||
|
||||
con_max_lines = ConVar::StaticCreate("con_max_lines" , "1024", FCVAR_DEVELOPMENTONLY, "Maximum number of lines in the console before cleanup starts.", true, 1.f, false, 0.f, nullptr, nullptr);
|
||||
con_max_history = ConVar::StaticCreate("con_max_history" , "512" , FCVAR_DEVELOPMENTONLY, "Maximum number of command submission items before history cleanup starts.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
con_suggest_limit = ConVar::StaticCreate("con_suggest_limit" , "128" , FCVAR_DEVELOPMENTONLY, "Maximum number of suggestions the autocomplete window will show for the console.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
con_suggest_showhelptext = ConVar::StaticCreate("con_suggest_showhelptext" , "1" , FCVAR_DEVELOPMENTONLY, "Show CommandBase help text in autocomplete window.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
con_suggest_showflags = ConVar::StaticCreate("con_suggest_showflags" , "1" , FCVAR_DEVELOPMENTONLY, "Show CommandBase flags in autocomplete window.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
serverbrowser_hideEmptyServers = ConVar::StaticCreate("serverbrowser_hideEmptyServers", "0", FCVAR_RELEASE, "Hide empty servers in the server browser.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
serverbrowser_mapFilter = ConVar::StaticCreate("serverbrowser_mapFilter", "0", FCVAR_RELEASE, "Filter servers by map in the server browser.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
serverbrowser_gamemodeFilter = ConVar::StaticCreate("serverbrowser_gamemodeFilter", "0", FCVAR_RELEASE, "Filter servers by gamemode in the server browser.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
#endif // !DEDICATED
|
||||
// Taken from S15:
|
||||
usercmd_frametime_max = ConVar::StaticCreate("usercmd_frametime_max", "0.100", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "The largest amount of simulation seconds a UserCmd can have.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
usercmd_frametime_min = ConVar::StaticCreate("usercmd_frametime_min", "0.002857", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "The smallest amount of simulation seconds a UserCmd can have.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
usercmd_dualwield_enable = ConVar::StaticCreate("usercmd_dualwield_enable", "0", FCVAR_REPLICATED | FCVAR_RELEASE, "Allows setting dual wield cycle slots, and activating multiple inventory weapons from UserCmd.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// FILESYSTEM |
|
||||
fs_showWarnings = ConVar::StaticCreate("fs_showWarnings" , "0", FCVAR_DEVELOPMENTONLY, "Logs the FileSystem warnings to the console, filtered by 'fs_warning_level' ( !slower! ).", true, 0.f, true, 2.f, nullptr, "0 = log to file. 1 = 0 + log to console. 2 = 1 + log to notify");
|
||||
fs_packedstore_entryblock_stats = ConVar::StaticCreate("fs_packedstore_entryblock_stats" , "0", FCVAR_DEVELOPMENTONLY, "Logs the stats of each file entry in the VPK during decompression ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
fs_packedstore_workspace = ConVar::StaticCreate("fs_packedstore_workspace" , "ship", FCVAR_DEVELOPMENTONLY, "Determines the current VPK workspace.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
fs_packedstore_compression_level = ConVar::StaticCreate("fs_packedstore_compression_level", "default", FCVAR_DEVELOPMENTONLY, "Determines the VPK compression level.", false, 0.f, false, 0.f, nullptr, "fastest faster default better uber");
|
||||
fs_packedstore_max_helper_threads = ConVar::StaticCreate("fs_packedstore_max_helper_threads" , "-1", FCVAR_DEVELOPMENTONLY, "Max # of additional \"helper\" threads to create during compression.", true, -1, true, LZHAM_MAX_HELPER_THREADS, nullptr, "Must range between [-1,LZHAM_MAX_HELPER_THREADS], where -1=max practical");
|
||||
//-------------------------------------------------------------------------
|
||||
// MATERIALSYSTEM |
|
||||
#ifndef DEDICATED
|
||||
mat_alwaysComplain = ConVar::StaticCreate("mat_alwaysComplain", "0", FCVAR_RELEASE | FCVAR_MATERIAL_SYSTEM_THREAD, "Always complain when a material is missing.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// SQUIRREL |
|
||||
script_show_output = ConVar::StaticCreate("script_show_output" , "0", FCVAR_RELEASE, "Prints the VM output to the console ( !slower! ).", true, 0.f, true, 2.f, nullptr, "0 = log to file. 1 = 0 + log to console. 2 = 1 + log to notify");
|
||||
script_show_warning = ConVar::StaticCreate("script_show_warning", "0", FCVAR_RELEASE, "Prints the VM warning output to the console ( !slower! ).", true, 0.f, true, 2.f, nullptr, "0 = log to file. 1 = 0 + log to console. 2 = 1 + log to notify");
|
||||
//-------------------------------------------------------------------------
|
||||
// NETCHANNEL |
|
||||
net_tracePayload = ConVar::StaticCreate("net_tracePayload" , "0", FCVAR_DEVELOPMENTONLY , "Log the payload of the send/recv datagram to a file on the disk.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
net_encryptionEnable = ConVar::StaticCreate("net_encryptionEnable" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED , "Use AES encryption on game packets.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
net_useRandomKey = ConVar::StaticCreate("net_useRandomKey" , "1" , FCVAR_RELEASE , "Use random AES encryption key for game packets.", false, 0.f, false, 0.f, &NET_UseRandomKeyChanged_f, nullptr);
|
||||
net_processTimeBudget = ConVar::StaticCreate("net_processTimeBudget" ,"200" , FCVAR_RELEASE , "Net message process time budget in milliseconds (removing netchannel if exceeded).", true, 0.f, false, 0.f, nullptr, "0 = disabled");
|
||||
//-------------------------------------------------------------------------
|
||||
// NETWORKSYSTEM |
|
||||
pylon_matchmaking_hostname = ConVar::StaticCreate("pylon_matchmaking_hostname", "ms.r5reloaded.com", FCVAR_RELEASE, "Holds the pylon matchmaking hostname.", false, 0.f, false, 0.f, &MP_HostName_Changed_f, nullptr);
|
||||
pylon_host_update_interval = ConVar::StaticCreate("pylon_host_update_interval", "5" , FCVAR_RELEASE, "Length of time in seconds between each status update interval to master server.", true, 5.f, false, 0.f, nullptr, nullptr);
|
||||
pylon_showdebuginfo = ConVar::StaticCreate("pylon_showdebuginfo" , "0" , FCVAR_RELEASE, "Shows debug output for pylon.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// RTECH API |
|
||||
rtech_debug = ConVar::StaticCreate("rtech_debug", "0", FCVAR_DEVELOPMENTONLY, "Shows debug output for the RTech system.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// RUI |
|
||||
#ifndef DEDICATED
|
||||
rui_drawEnable = ConVar::StaticCreate("rui_drawEnable", "1", FCVAR_RELEASE, "Draws the RUI if set.", false, 0.f, false, 0.f, nullptr, "1 = draw; 0 (zero) = no draw");
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// MILES |
|
||||
#ifndef DEDICATED
|
||||
miles_debug = ConVar::StaticCreate("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System.", false, 0.f, false, 0.f, nullptr, "1 = print; 0 (zero) = no print");
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: initialize shipped ConVar's
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -463,16 +133,21 @@ void ConVar_InitShipped(void)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
ai_script_nodes_draw = g_pCVar->FindVar("ai_script_nodes_draw");
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
||||
bhit_enable = g_pCVar->FindVar("bhit_enable");
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
#endif // !CLIENT_DLL
|
||||
developer = g_pCVar->FindVar("developer");
|
||||
fps_max = g_pCVar->FindVar("fps_max");
|
||||
fps_max_vsync = g_pCVar->FindVar("fps_max_vsync");
|
||||
base_tickinterval_sp = g_pCVar->FindVar("base_tickinterval_sp");
|
||||
base_tickinterval_mp = g_pCVar->FindVar("base_tickinterval_mp");
|
||||
fs_showAllReads = g_pCVar->FindVar("fs_showAllReads");
|
||||
|
||||
eula_version = g_pCVar->FindVar("eula_version");
|
||||
eula_version_accepted = g_pCVar->FindVar("eula_version_accepted");
|
||||
|
||||
language_cvar = g_pCVar->FindVar("language");
|
||||
#ifndef DEDICATED
|
||||
cl_cmdrate = g_pCVar->FindVar("cl_cmdrate");
|
||||
cl_move_use_dt = g_pCVar->FindVar("cl_move_use_dt");
|
||||
cl_updaterate_mp = g_pCVar->FindVar("cl_updaterate_mp");
|
||||
cl_threaded_bone_setup = g_pCVar->FindVar("cl_threaded_bone_setup");
|
||||
#endif // !DEDICATED
|
||||
single_frame_shutdown_for_reload = g_pCVar->FindVar("single_frame_shutdown_for_reload");
|
||||
@ -483,6 +158,7 @@ void ConVar_InitShipped(void)
|
||||
#ifndef DEDICATED
|
||||
miles_language = g_pCVar->FindVar("miles_language");
|
||||
rui_defaultDebugFontFace = g_pCVar->FindVar("rui_defaultDebugFontFace");
|
||||
in_syncRT = g_pCVar->FindVar("in_syncRT");
|
||||
r_visualizetraces = g_pCVar->FindVar("r_visualizetraces");
|
||||
r_visualizetraces_duration = g_pCVar->FindVar("r_visualizetraces_duration");
|
||||
#endif // !DEDICATED
|
||||
@ -505,13 +181,24 @@ void ConVar_InitShipped(void)
|
||||
hostport = g_pCVar->FindVar("hostport");
|
||||
host_hasIrreversibleShutdown = g_pCVar->FindVar("host_hasIrreversibleShutdown");
|
||||
host_timescale = g_pCVar->FindVar("host_timescale");
|
||||
|
||||
net_data_block_enabled = g_pCVar->FindVar("net_data_block_enabled");
|
||||
net_compressDataBlock = g_pCVar->FindVar("net_compressDataBlock");
|
||||
net_datablock_networkLossForSlowSpeed = g_pCVar->FindVar("net_datablock_networkLossForSlowSpeed");
|
||||
|
||||
net_usesocketsforloopback = g_pCVar->FindVar("net_usesocketsforloopback");
|
||||
|
||||
net_showmsg = g_pCVar->FindVar("net_showmsg");
|
||||
net_blockmsg = g_pCVar->FindVar("net_blockmsg");
|
||||
net_showpeaks = g_pCVar->FindVar("net_showpeaks");
|
||||
#ifndef CLIENT_DLL
|
||||
sv_stats = g_pCVar->FindVar("sv_stats");
|
||||
|
||||
sv_updaterate_mp = g_pCVar->FindVar("sv_updaterate_mp");
|
||||
sv_maxunlag = g_pCVar->FindVar("sv_maxunlag");
|
||||
sv_clockcorrection_msecs = g_pCVar->FindVar("sv_clockcorrection_msecs");
|
||||
|
||||
sv_updaterate_sp = g_pCVar->FindVar("sv_updaterate_sp");
|
||||
sv_updaterate_mp = g_pCVar->FindVar("sv_updaterate_mp");
|
||||
|
||||
sv_showhitboxes = g_pCVar->FindVar("sv_showhitboxes");
|
||||
sv_forceChatToTeamOnly = g_pCVar->FindVar("sv_forceChatToTeamOnly");
|
||||
@ -523,6 +210,9 @@ void ConVar_InitShipped(void)
|
||||
sv_alltalk = g_pCVar->FindVar("sv_alltalk");
|
||||
player_userCmdsQueueWarning = g_pCVar->FindVar("player_userCmdsQueueWarning");
|
||||
|
||||
sv_updaterate_sp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
sv_updaterate_mp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
sv_showhitboxes->SetMin(-1); // Allow user to go over each entity manually without going out of bounds.
|
||||
sv_showhitboxes->SetMax(NUM_ENT_ENTRIES - 1);
|
||||
|
||||
@ -532,21 +222,29 @@ void ConVar_InitShipped(void)
|
||||
sv_single_core_dedi->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
ai_script_nodes_draw->SetValue(-1);
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
bhit_enable->SetValue(0);
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
#endif // !CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
cl_updaterate_mp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
cl_threaded_bone_setup->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
rui_defaultDebugFontFace->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
origin_disconnectWhenOffline->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
discord_updatePresence->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
#endif // !DEDICATED
|
||||
fps_max_vsync->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
base_tickinterval_sp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
base_tickinterval_mp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
mp_gamemode->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
mp_gamemode->RemoveChangeCallback(mp_gamemode->m_fnChangeCallbacks[0]);
|
||||
mp_gamemode->InstallChangeCallback(MP_GameMode_Changed_f, false);
|
||||
net_usesocketsforloopback->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
net_usesocketsforloopback->InstallChangeCallback(NET_UseSocketsForLoopbackChanged_f, false);
|
||||
#ifndef DEDICATED
|
||||
language_cvar->InstallChangeCallback(LanguageChanged_f, false);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -610,79 +308,19 @@ void ConVar_PurgeHostNames(void)
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ConCommand registration
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConCommand_StaticInit(void)
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// ENGINE DLL |
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
||||
ConCommand::StaticCreate("bhit", "Bullet-hit trajectory debug.", nullptr, FCVAR_DEVELOPMENTONLY | FCVAR_GAMEDLL, BHit_f, nullptr);
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
#ifndef DEDICATED
|
||||
ConCommand::StaticCreate("line", "Draw a debug line.", nullptr, FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, Line_f, nullptr);
|
||||
ConCommand::StaticCreate("sphere", "Draw a debug sphere.", nullptr, FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, Sphere_f, nullptr);
|
||||
ConCommand::StaticCreate("capsule", "Draw a debug capsule.", nullptr, FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, Capsule_f, nullptr);
|
||||
#endif //!DEDICATED
|
||||
ConCommand::StaticCreate("con_help", "Shows the colors and description of each context.", nullptr, FCVAR_RELEASE, CON_Help_f, nullptr);
|
||||
#ifndef CLIENT_DLL
|
||||
ConCommand::StaticCreate("reload_playlists", "Reloads the playlists file.", nullptr, FCVAR_RELEASE, Host_ReloadPlaylists_f, nullptr);
|
||||
#endif // !CLIENT_DLL
|
||||
//-------------------------------------------------------------------------
|
||||
// SERVER DLL |
|
||||
#ifndef CLIENT_DLL
|
||||
ConCommand::StaticCreate("script", "Run input code as SERVER script on the VM.", nullptr, FCVAR_GAMEDLL | FCVAR_CHEAT, SQVM_ServerScript_f, nullptr);
|
||||
ConCommand::StaticCreate("kick", "Kick a client from the server by user name.", "kick \"<userId>\"", FCVAR_RELEASE, Host_Kick_f, nullptr);
|
||||
ConCommand::StaticCreate("kickid", "Kick a client from the server by handle, nucleus id or ip address.", "kickid \"<handle>\"/\"<nucleusId>/<ipAddress>\"", FCVAR_RELEASE, Host_KickID_f, nullptr);
|
||||
ConCommand::StaticCreate("ban", "Bans a client from the server by user name.", "ban <userId>", FCVAR_RELEASE, Host_Ban_f, nullptr);
|
||||
ConCommand::StaticCreate("banid", "Bans a client from the server by handle, nucleus id or ip address.", "banid \"<handle>\"/\"<nucleusId>/<ipAddress>\"", FCVAR_RELEASE, Host_BanID_f, nullptr);
|
||||
ConCommand::StaticCreate("unban", "Unbans a client from the server by nucleus id or ip address.", "unban \"<nucleusId>\"/\"<ipAddress>\"", FCVAR_RELEASE, Host_Unban_f, nullptr);
|
||||
ConCommand::StaticCreate("sv_reloadbanlist", "Reloads the banned list.", nullptr, FCVAR_RELEASE, Host_ReloadBanList_f, nullptr);
|
||||
ConCommand::StaticCreate("sv_addbot", "Creates a bot on the server.", nullptr, FCVAR_RELEASE, CC_CreateFakePlayer_f, nullptr);
|
||||
ConCommand::StaticCreate("navmesh_hotswap", "Hot swap the NavMesh for all hulls.", nullptr, FCVAR_DEVELOPMENTONLY, Detour_HotSwap_f, nullptr);
|
||||
#endif // !CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// CLIENT DLL |
|
||||
ConCommand::StaticCreate("script_client", "Run input code as CLIENT script on the VM.", nullptr, FCVAR_CLIENTDLL | FCVAR_CHEAT, SQVM_ClientScript_f, nullptr);
|
||||
ConCommand::StaticCreate("rcon", "Forward RCON query to remote server.", "rcon \"<query>\"", FCVAR_CLIENTDLL | FCVAR_RELEASE, RCON_CmdQuery_f, nullptr);
|
||||
ConCommand::StaticCreate("rcon_disconnect", "Disconnect from RCON server.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, RCON_Disconnect_f, nullptr);
|
||||
static ConCommand bhit("bhit", BHit_f, "Bullet-hit trajectory debug", FCVAR_DEVELOPMENTONLY | FCVAR_GAMEDLL);
|
||||
|
||||
ConCommand::StaticCreate("con_history", "Shows the developer console submission history.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, CON_LogHistory_f, nullptr);
|
||||
ConCommand::StaticCreate("con_removeline", "Removes a range of lines from the developer console.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, CON_RemoveLine_f, nullptr);
|
||||
ConCommand::StaticCreate("con_clearlines", "Clears all lines from the developer console.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, CON_ClearLines_f, nullptr);
|
||||
ConCommand::StaticCreate("con_clearhistory", "Clears all submissions from the developer console history.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, CON_ClearHistory_f, nullptr);
|
||||
|
||||
ConCommand::StaticCreate("toggleconsole", "Show/hide the developer console.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, ToggleConsole_f, nullptr);
|
||||
ConCommand::StaticCreate("togglebrowser", "Show/hide the server browser.", nullptr, FCVAR_CLIENTDLL | FCVAR_RELEASE, ToggleBrowser_f, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// UI DLL |
|
||||
ConCommand::StaticCreate("script_ui", "Run input code as UI script on the VM.", nullptr, FCVAR_CLIENTDLL | FCVAR_CHEAT, SQVM_UIScript_f, nullptr);
|
||||
#ifndef DEDICATED
|
||||
static ConCommand line("line", Line_f, "Draw a debug line", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
|
||||
static ConCommand sphere("sphere", Sphere_f, "Draw a debug sphere", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
|
||||
static ConCommand capsule("capsule", Capsule_f, "Draw a debug capsule", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
|
||||
#endif //!DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// FILESYSTEM API |
|
||||
ConCommand::StaticCreate("fs_vpk_mount", "Mount a VPK file for FileSystem usage.", nullptr, FCVAR_DEVELOPMENTONLY, VPK_Mount_f, nullptr);
|
||||
ConCommand::StaticCreate("fs_vpk_unmount", "Unmount a VPK file and clear its cache.", nullptr, FCVAR_DEVELOPMENTONLY, VPK_Unmount_f, nullptr);
|
||||
ConCommand::StaticCreate("fs_vpk_pack", "Pack a VPK file from current workspace.", nullptr, FCVAR_DEVELOPMENTONLY, VPK_Pack_f, nullptr);
|
||||
ConCommand::StaticCreate("fs_vpk_unpack", "Unpack all files from a VPK file.", nullptr, FCVAR_DEVELOPMENTONLY, VPK_Unpack_f, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// RTECH API |
|
||||
ConCommand::StaticCreate("rtech_strtoguid", "Calculates the GUID from input data.", nullptr, FCVAR_DEVELOPMENTONLY, RTech_StringToGUID_f, nullptr);
|
||||
ConCommand::StaticCreate("pak_decompress", "Decompresses specified RPAK file.", nullptr, FCVAR_DEVELOPMENTONLY, RTech_Decompress_f, RTech_PakDecompress_f_CompletionFunc);
|
||||
ConCommand::StaticCreate("pak_requestload", "Requests asynchronous load for specified RPAK file.", nullptr, FCVAR_DEVELOPMENTONLY, Pak_RequestLoad_f, RTech_PakLoad_f_CompletionFunc);
|
||||
ConCommand::StaticCreate("pak_requestunload", "Requests unload for specified RPAK file or ID.", nullptr, FCVAR_DEVELOPMENTONLY, Pak_RequestUnload_f, RTech_PakUnload_f_CompletionFunc);
|
||||
ConCommand::StaticCreate("pak_swap", "Requests swap for specified RPAK file or ID", nullptr, FCVAR_DEVELOPMENTONLY, Pak_Swap_f, nullptr);
|
||||
ConCommand::StaticCreate("pak_listpaks", "Display a list of the loaded Pak files.", nullptr, FCVAR_RELEASE, Pak_ListPaks_f, nullptr);
|
||||
ConCommand::StaticCreate("pak_listtypes", "Display a list of the registered asset types.", nullptr, FCVAR_RELEASE, Pak_ListTypes_f, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// NETCHANNEL |
|
||||
ConCommand::StaticCreate("net_setkey", "Sets user specified base64 net key.", nullptr, FCVAR_RELEASE, NET_SetKey_f, nullptr);
|
||||
ConCommand::StaticCreate("net_generatekey", "Generates and sets a random base64 net key.", nullptr, FCVAR_RELEASE, NET_GenerateKey_f, nullptr);
|
||||
//-------------------------------------------------------------------------
|
||||
// TIER0 |
|
||||
ConCommand::StaticCreate("sig_getadr", "Logs the sigscan results to the console.", nullptr, FCVAR_DEVELOPMENTONLY | FCVAR_HIDDEN, SIG_GetAdr_f, nullptr);
|
||||
}
|
||||
|
||||
// TODO: move VPK building code to separate file and place this in 'packedstore.cpp'
|
||||
static ConCommand fs_vpk_mount("fs_vpk_mount", VPK_Mount_f, "Mount a VPK file for FileSystem usage", FCVAR_DEVELOPMENTONLY);
|
||||
static ConCommand fs_vpk_unmount("fs_vpk_unmount", VPK_Unmount_f, "Unmount a VPK file and clear its cache", FCVAR_DEVELOPMENTONLY);
|
||||
static ConCommand fs_vpk_pack("fs_vpk_pack", VPK_Pack_f, "Pack a VPK file from current workspace", FCVAR_DEVELOPMENTONLY);
|
||||
static ConCommand fs_vpk_unpack("fs_vpk_unpack", VPK_Unpack_f, "Unpack all files from a VPK file", FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: shipped ConCommand initialization
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ENGINE |
|
||||
extern ConVar* sdk_fixedframe_tickinterval;
|
||||
extern ConVar* single_frame_shutdown_for_reload;
|
||||
extern ConVar* old_gather_props;
|
||||
|
||||
@ -12,12 +11,14 @@ extern ConVar* debug_draw_box_depth_test;
|
||||
|
||||
extern ConVar* developer;
|
||||
extern ConVar* fps_max;
|
||||
extern ConVar* fps_max_vsync;
|
||||
|
||||
// taken from S15:
|
||||
extern ConVar* usercmd_frametime_max;
|
||||
extern ConVar* usercmd_frametime_min;
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* in_syncRT;
|
||||
#endif // !DEDICATED
|
||||
|
||||
extern ConVar* usercmd_dualwield_enable;
|
||||
extern ConVar* base_tickinterval_sp;
|
||||
extern ConVar* base_tickinterval_mp;
|
||||
|
||||
extern ConVar* staticProp_no_fade_scalar;
|
||||
extern ConVar* staticProp_gather_size_weight;
|
||||
@ -27,7 +28,6 @@ extern ConVar* model_defaultFadeDistMin;
|
||||
|
||||
extern ConVar* ip_cvar;
|
||||
extern ConVar* hostname;
|
||||
extern ConVar* hostdesc;
|
||||
extern ConVar* hostip;
|
||||
extern ConVar* hostport;
|
||||
|
||||
@ -36,17 +36,6 @@ extern ConVar* host_timescale;
|
||||
|
||||
extern ConVar* mp_gamemode;
|
||||
|
||||
extern ConVar* rcon_address;
|
||||
extern ConVar* rcon_password;
|
||||
|
||||
extern ConVar* r_debug_overlay_nodecay;
|
||||
extern ConVar* r_debug_overlay_invisible;
|
||||
extern ConVar* r_debug_overlay_wireframe;
|
||||
extern ConVar* r_debug_draw_depth_test;
|
||||
extern ConVar* r_drawWorldMeshes;
|
||||
extern ConVar* r_drawWorldMeshesDepthOnly;
|
||||
extern ConVar* r_drawWorldMeshesDepthAtTheEnd;
|
||||
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* r_visualizetraces;
|
||||
extern ConVar* r_visualizetraces_duration;
|
||||
@ -56,202 +45,80 @@ extern ConVar* stream_overlay;
|
||||
extern ConVar* stream_overlay_mode;
|
||||
//-------------------------------------------------------------------------
|
||||
// SHARED |
|
||||
extern ConVar* modsystem_enable;
|
||||
extern ConVar* modsystem_debug;
|
||||
extern ConVar* eula_version;
|
||||
extern ConVar* eula_version_accepted;
|
||||
|
||||
extern ConVar* language_cvar;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// SERVER |
|
||||
#ifndef CLIENT_DLL
|
||||
extern ConVar* ai_ainDumpOnLoad;
|
||||
extern ConVar* ai_ainDebugConnect;
|
||||
extern ConVar* ai_script_nodes_draw;
|
||||
extern ConVar* ai_script_nodes_draw_range;
|
||||
extern ConVar* ai_script_nodes_draw_nearest;
|
||||
|
||||
extern ConVar* navmesh_always_reachable;
|
||||
extern ConVar* navmesh_debug_type;
|
||||
extern ConVar* navmesh_debug_tile_range;
|
||||
extern ConVar* navmesh_debug_camera_range;
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* navmesh_draw_bvtree;
|
||||
extern ConVar* navmesh_draw_portal;
|
||||
extern ConVar* navmesh_draw_polys;
|
||||
extern ConVar* navmesh_draw_poly_bounds;
|
||||
extern ConVar* navmesh_draw_poly_bounds_inner;
|
||||
#endif // DEDICATED
|
||||
extern ConVar* sv_language;
|
||||
extern ConVar* sv_showconnecting;
|
||||
extern ConVar* sv_globalBanlist;
|
||||
extern ConVar* sv_pylonVisibility;
|
||||
extern ConVar* sv_pylonRefreshRate;
|
||||
extern ConVar* sv_banlistRefreshRate;
|
||||
extern ConVar* sv_statusRefreshRate;
|
||||
extern ConVar* sv_forceChatToTeamOnly;
|
||||
|
||||
extern ConVar* sv_single_core_dedi;
|
||||
|
||||
extern ConVar* sv_updaterate_mp;
|
||||
extern ConVar* sv_updaterate_sp;
|
||||
extern ConVar* sv_autoReloadRate;
|
||||
extern ConVar* sv_maxunlag;
|
||||
extern ConVar* sv_clockcorrection_msecs;
|
||||
|
||||
extern ConVar* sv_updaterate_sp;
|
||||
extern ConVar* sv_updaterate_mp;
|
||||
|
||||
extern ConVar* sv_simulateBots;
|
||||
extern ConVar* sv_showhitboxes;
|
||||
extern ConVar* sv_stats;
|
||||
|
||||
extern ConVar* sv_quota_stringCmdsPerSecond;
|
||||
|
||||
extern ConVar* sv_validatePersonaName;
|
||||
extern ConVar* sv_minPersonaNameLength;
|
||||
extern ConVar* sv_maxPersonaNameLength;
|
||||
|
||||
extern ConVar* sv_voiceEcho;
|
||||
extern ConVar* sv_voiceenable;
|
||||
extern ConVar* sv_alltalk;
|
||||
|
||||
extern ConVar* player_userCmdsQueueWarning;
|
||||
|
||||
//#ifdef DEDICATED
|
||||
extern ConVar* sv_rcon_debug;
|
||||
extern ConVar* sv_rcon_sendlogs;
|
||||
//extern ConVar* sv_rcon_banpenalty;
|
||||
extern ConVar* sv_rcon_maxfailures;
|
||||
extern ConVar* sv_rcon_maxignores;
|
||||
extern ConVar* sv_rcon_maxsockets;
|
||||
extern ConVar* sv_rcon_maxconnections;
|
||||
extern ConVar* sv_rcon_maxpacketsize;
|
||||
extern ConVar* sv_rcon_whitelist_address;
|
||||
//#endif // DEDICATED
|
||||
#endif // CLIENT_DLL
|
||||
extern ConVar* sv_cheats;
|
||||
extern ConVar* sv_visualizetraces;
|
||||
extern ConVar* sv_visualizetraces_duration;
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
||||
extern ConVar* bhit_enable;
|
||||
extern ConVar* bhit_depth_test;
|
||||
extern ConVar* bhit_abs_origin;
|
||||
#endif // !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
//-------------------------------------------------------------------------
|
||||
// CLIENT |
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* cl_rcon_inputonly;
|
||||
extern ConVar* cl_quota_stringCmdsPerSecond;
|
||||
|
||||
extern ConVar* cl_cmdrate;
|
||||
extern ConVar* cl_move_use_dt;
|
||||
|
||||
extern ConVar* cl_notify_invert_x;
|
||||
extern ConVar* cl_notify_invert_y;
|
||||
extern ConVar* cl_notify_offset_x;
|
||||
extern ConVar* cl_notify_offset_y;
|
||||
|
||||
extern ConVar* cl_showsimstats;
|
||||
extern ConVar* cl_simstats_invert_x;
|
||||
extern ConVar* cl_simstats_invert_y;
|
||||
extern ConVar* cl_simstats_offset_x;
|
||||
extern ConVar* cl_simstats_offset_y;
|
||||
|
||||
extern ConVar* cl_showgpustats;
|
||||
extern ConVar* cl_gpustats_invert_x;
|
||||
extern ConVar* cl_gpustats_invert_y;
|
||||
extern ConVar* cl_gpustats_offset_x;
|
||||
extern ConVar* cl_gpustats_offset_y;
|
||||
|
||||
extern ConVar* cl_showmaterialinfo;
|
||||
extern ConVar* cl_materialinfo_offset_x;
|
||||
extern ConVar* cl_materialinfo_offset_y;
|
||||
|
||||
extern ConVar* cl_threaded_bone_setup;
|
||||
|
||||
extern ConVar* con_drawnotify;
|
||||
extern ConVar* con_notifylines;
|
||||
extern ConVar* con_notifytime;
|
||||
|
||||
extern ConVar* con_notify_invert_x;
|
||||
extern ConVar* con_notify_invert_y;
|
||||
extern ConVar* con_notify_offset_x;
|
||||
extern ConVar* con_notify_offset_y;
|
||||
|
||||
extern ConVar* con_notify_script_server_clr;
|
||||
extern ConVar* con_notify_script_client_clr;
|
||||
extern ConVar* con_notify_script_ui_clr;
|
||||
extern ConVar* con_notify_native_server_clr;
|
||||
extern ConVar* con_notify_native_client_clr;
|
||||
extern ConVar* con_notify_native_ui_clr;
|
||||
extern ConVar* con_notify_native_engine_clr;
|
||||
extern ConVar* con_notify_native_fs_clr;
|
||||
extern ConVar* con_notify_native_rtech_clr;
|
||||
extern ConVar* con_notify_native_ms_clr;
|
||||
extern ConVar* con_notify_native_audio_clr;
|
||||
extern ConVar* con_notify_native_video_clr;
|
||||
extern ConVar* con_notify_netcon_clr;
|
||||
extern ConVar* con_notify_common_clr;
|
||||
extern ConVar* con_notify_warning_clr;
|
||||
extern ConVar* con_notify_error_clr;
|
||||
|
||||
extern ConVar* con_max_lines;
|
||||
extern ConVar* con_max_history;
|
||||
extern ConVar* con_suggest_limit;
|
||||
extern ConVar* con_suggest_showhelptext;
|
||||
extern ConVar* con_suggest_showflags;
|
||||
|
||||
extern ConVar* origin_disconnectWhenOffline;
|
||||
extern ConVar* discord_updatePresence;
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// FILESYSTEM |
|
||||
extern ConVar* fs_showWarnings;
|
||||
extern ConVar* fs_showAllReads;
|
||||
extern ConVar* fs_packedstore_entryblock_stats;
|
||||
extern ConVar* fs_packedstore_workspace;
|
||||
extern ConVar* fs_packedstore_compression_level;
|
||||
extern ConVar* fs_packedstore_max_helper_threads;
|
||||
//-------------------------------------------------------------------------
|
||||
// MATERIALSYSTEM |
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* mat_alwaysComplain;
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// SQUIRREL |
|
||||
extern ConVar* script_show_output;
|
||||
extern ConVar* script_show_warning;
|
||||
//-------------------------------------------------------------------------
|
||||
// NETCHANNEL |
|
||||
extern ConVar* net_tracePayload;
|
||||
extern ConVar* net_encryptionEnable;
|
||||
extern ConVar* net_useRandomKey;
|
||||
extern ConVar* net_usesocketsforloopback;
|
||||
extern ConVar* net_processTimeBudget;
|
||||
|
||||
extern ConVar* net_data_block_enabled;
|
||||
extern ConVar* net_datablock_networkLossForSlowSpeed;
|
||||
extern ConVar* net_compressDataBlock;
|
||||
|
||||
extern ConVar* pylon_matchmaking_hostname;
|
||||
extern ConVar* pylon_host_update_interval;
|
||||
extern ConVar* pylon_showdebuginfo;
|
||||
extern ConVar* net_showmsg;
|
||||
extern ConVar* net_blockmsg;
|
||||
extern ConVar* net_showpeaks;
|
||||
|
||||
extern ConVar* ssl_verify_peer;
|
||||
extern ConVar* curl_timeout;
|
||||
extern ConVar* curl_debug;
|
||||
//-------------------------------------------------------------------------
|
||||
// RTECH API |
|
||||
extern ConVar* rtech_debug;
|
||||
extern ConVar ssl_verify_peer;
|
||||
extern ConVar curl_timeout;
|
||||
extern ConVar curl_debug;
|
||||
//-------------------------------------------------------------------------
|
||||
// RUI |
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* rui_drawEnable;
|
||||
extern ConVar* rui_defaultDebugFontFace;
|
||||
#endif // !DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// MILES |
|
||||
#ifndef DEDICATED
|
||||
extern ConVar* miles_debug;
|
||||
extern ConVar* miles_language;
|
||||
#endif
|
||||
|
||||
void ConVar_StaticInit(void);
|
||||
void ConVar_InitShipped(void);
|
||||
void ConVar_PurgeShipped(void);
|
||||
void ConVar_PurgeHostNames(void);
|
||||
void ConCommand_StaticInit(void);
|
||||
void ConCommand_InitShipped(void);
|
||||
void ConCommand_PurgeShipped(void);
|
||||
|
||||
|
@ -28,7 +28,7 @@ bool SVC_Print::ProcessImpl()
|
||||
|
||||
if (len < sizeof(m_szTextBuffer))
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, m_szText[len-1] == '\n' ? "%s" : "%s\n", m_szText);
|
||||
Msg(eDLL_T::SERVER, m_szText[len-1] == '\n' ? "%s" : "%s\n", m_szText);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ bool SVC_UserMessage::ProcessImpl()
|
||||
|
||||
if (len && len < sizeof(text))
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, text[len - 1] == '\n' ? "%s" : "%s\n", text);
|
||||
Msg(eDLL_T::SERVER, text[len - 1] == '\n' ? "%s" : "%s\n", text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,6 +90,7 @@ bool CLC_SetPlaylistVarOverride::WriteToBufferImpl(CLC_SetPlaylistVarOverride* t
|
||||
return CLC_SetPlaylistVarOverride_WriteToBuffer(thisptr, buffer);
|
||||
}
|
||||
|
||||
static ConVar enable_CmdKeyValues("enable_CmdKeyValues", "0", FCVAR_DEVELOPMENTONLY, "Toggle CmdKeyValues transmit and receive.");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// below functions are hooked as 'CmdKeyValues' isn't really used in this game, but
|
||||
@ -98,8 +99,8 @@ bool CLC_SetPlaylistVarOverride::WriteToBufferImpl(CLC_SetPlaylistVarOverride* t
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
bool Base_CmdKeyValues::ReadFromBufferImpl(Base_CmdKeyValues* thisptr, bf_read* buffer)
|
||||
{
|
||||
// Abusable netmsg; only allow if cheats are enabled.
|
||||
if (!sv_cheats->GetBool())
|
||||
// Abusable netmsg; only allow if explicitly enabled by the client.
|
||||
if (!enable_CmdKeyValues.GetBool())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -108,8 +109,8 @@ bool Base_CmdKeyValues::ReadFromBufferImpl(Base_CmdKeyValues* thisptr, bf_read*
|
||||
}
|
||||
bool Base_CmdKeyValues::WriteToBufferImpl(Base_CmdKeyValues* thisptr, bf_write* buffer)
|
||||
{
|
||||
// Abusable netmsg; only allow if cheats are enabled.
|
||||
if (!sv_cheats->GetBool())
|
||||
// Abusable netmsg; only allow if explicitly enabled by the client.
|
||||
if (!enable_CmdKeyValues.GetBool())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -160,7 +161,9 @@ bool ShouldReplayMessage(const CNetMessage* msg)
|
||||
}
|
||||
}
|
||||
|
||||
void V_NetMessages::Attach() const
|
||||
void V_NetMessages::Detour(const bool bAttach) const
|
||||
{
|
||||
if (bAttach)
|
||||
{
|
||||
auto hk_SVCPrint_Process = &SVC_Print::ProcessImpl;
|
||||
auto hk_SVCUserMessage_Process = &SVC_UserMessage::ProcessImpl;
|
||||
@ -172,8 +175,7 @@ void V_NetMessages::Attach() const
|
||||
CMemory::HookVirtualMethod((uintptr_t)g_pCLC_SetPlaylistVarOverride_VFTable, (LPVOID*)&CLC_SetPlaylistVarOverride::ReadFromBufferImpl, NetMessageVtbl::ReadFromBuffer, (LPVOID*)&CLC_SetPlaylistVarOverride_ReadFromBuffer);
|
||||
CMemory::HookVirtualMethod((uintptr_t)g_pCLC_SetPlaylistVarOverride_VFTable, (LPVOID*)&CLC_SetPlaylistVarOverride::WriteToBufferImpl, NetMessageVtbl::WriteToBuffer, (LPVOID*)&CLC_SetPlaylistVarOverride_WriteToBuffer);
|
||||
}
|
||||
|
||||
void V_NetMessages::Detach() const
|
||||
else
|
||||
{
|
||||
void* hkRestore = nullptr;
|
||||
CMemory::HookVirtualMethod((uintptr_t)g_pSVC_Print_VFTable, (LPVOID)SVC_Print_Process, NetMessageVtbl::Process, (LPVOID*)&hkRestore);
|
||||
@ -183,3 +185,4 @@ void V_NetMessages::Detach() const
|
||||
CMemory::HookVirtualMethod((uintptr_t)g_pCLC_SetPlaylistVarOverride_VFTable, (LPVOID)CLC_SetPlaylistVarOverride_ReadFromBuffer, NetMessageVtbl::ReadFromBuffer, (LPVOID*)&hkRestore);
|
||||
CMemory::HookVirtualMethod((uintptr_t)g_pCLC_SetPlaylistVarOverride_VFTable, (LPVOID)CLC_SetPlaylistVarOverride_WriteToBuffer, NetMessageVtbl::WriteToBuffer, (LPVOID*)&hkRestore);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "tier1/bitbuf.h"
|
||||
#include "common/qlimits.h"
|
||||
#include "public/inetchannel.h"
|
||||
#include "public/inetmessage.h"
|
||||
#include "public/inetmsghandler.h"
|
||||
@ -184,6 +185,24 @@ public:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// server messages:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
class SVC_CreateStringTable : public CNetMessage
|
||||
{
|
||||
public:
|
||||
const char* m_szTableName;
|
||||
int m_nMaxEntries;
|
||||
int m_nNumEntries;
|
||||
char m_bUserDataFixedSize;
|
||||
char _padding0[3];
|
||||
int m_nUserDataSize;
|
||||
int m_nUserDataSizeBits;
|
||||
int m_nDictFlags;
|
||||
int m_nLength;
|
||||
bf_read m_DataIn;
|
||||
bf_write m_DataOut;
|
||||
char m_bDataCompressed;
|
||||
char m_szTableNameBuffer[260];
|
||||
};
|
||||
|
||||
class SVC_Print : public CNetMessage
|
||||
{
|
||||
public:
|
||||
@ -362,6 +381,10 @@ private:
|
||||
bf_write m_DataOut;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Client messages:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CLC_ClientTick : public CNetMessage
|
||||
{
|
||||
public:
|
||||
@ -427,7 +450,7 @@ private:
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Client messages:
|
||||
// Shared messages:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct NET_StringCmd : CNetMessage
|
||||
@ -436,6 +459,19 @@ struct NET_StringCmd : CNetMessage
|
||||
char buffer[1024];
|
||||
};
|
||||
|
||||
class NET_SetConVar : public CNetMessage
|
||||
{
|
||||
public:
|
||||
|
||||
typedef struct cvar_s
|
||||
{
|
||||
char name[MAX_OSPATH];
|
||||
char value[MAX_OSPATH];
|
||||
} cvar_t;
|
||||
|
||||
CUtlVector<cvar_t> m_ConVars;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// This message is subclassed by 'SVC_CmdKeyValues' and 'CLC_CmdKeyValues'
|
||||
class Base_CmdKeyValues : public CNetMessage
|
||||
@ -476,15 +512,15 @@ class V_NetMessages : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogConAdr("SVC_Print::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_Print_VFTable));
|
||||
LogConAdr("SVC_UserMessage::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_UserMessage_VFTable));
|
||||
LogConAdr("SVC_ServerTick::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_ServerTick_VFTable));
|
||||
LogConAdr("SVC_VoiceData::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_VoiceData_VFTable));
|
||||
LogConAdr("SVC_PlaylistOverrides::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_PlaylistOverrides_VFTable));
|
||||
LogConAdr("CLC_ClientTick::`vftable'", reinterpret_cast<uintptr_t>(g_pCLC_ClientTick_VFTable));
|
||||
LogConAdr("CLC_SetPlaylistVarOverride::`vftable'", reinterpret_cast<uintptr_t>(g_pCLC_SetPlaylistVarOverride_VFTable));
|
||||
LogConAdr("Base_CmdKeyValues::`vftable'", reinterpret_cast<uintptr_t>(g_pBase_CmdKeyValues_VFTable));
|
||||
//LogFunAdr("MM_Heartbeat::ToString", MM_Heartbeat__ToString.GetPtr());
|
||||
LogConAdr("SVC_Print::`vftable'", g_pSVC_Print_VFTable);
|
||||
LogConAdr("SVC_UserMessage::`vftable'", g_pSVC_UserMessage_VFTable);
|
||||
LogConAdr("SVC_ServerTick::`vftable'", g_pSVC_ServerTick_VFTable);
|
||||
LogConAdr("SVC_VoiceData::`vftable'", g_pSVC_VoiceData_VFTable);
|
||||
LogConAdr("SVC_PlaylistOverrides::`vftable'", g_pSVC_PlaylistOverrides_VFTable);
|
||||
LogConAdr("CLC_ClientTick::`vftable'", g_pCLC_ClientTick_VFTable);
|
||||
LogConAdr("CLC_SetPlaylistVarOverride::`vftable'", g_pCLC_SetPlaylistVarOverride_VFTable);
|
||||
LogConAdr("Base_CmdKeyValues::`vftable'", g_pBase_CmdKeyValues_VFTable);
|
||||
//LogFunAdr("MM_Heartbeat::ToString", MM_Heartbeat__ToString);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
@ -504,8 +540,7 @@ class V_NetMessages : public IDetour
|
||||
g_pCLC_SetPlaylistVarOverride_VFTable = g_GameDll.GetVirtualMethodTable(".?AVCLC_SetPlaylistVarOverride@@");
|
||||
g_pBase_CmdKeyValues_VFTable = g_GameDll.GetVirtualMethodTable(".?AVBase_CmdKeyValues@@");
|
||||
}
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "game/server/ai_networkmanager.h"
|
||||
#include "game/server/detour_impl.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "rtech/rtech_game.h"
|
||||
//#include "rtech/rui/rui.h"
|
||||
//#include "materialsystem/cmaterialsystem.h"
|
||||
//#include "studiorender/studiorendercontext.h"
|
||||
@ -345,47 +344,9 @@ void RuntimePtc_Init() /* .TEXT */
|
||||
#ifndef DEDICATED
|
||||
p_WASAPI_GetAudioDevice.Offset(0x410).FindPatternSelf("FF 15 ?? ?? 01 00", CMemory::Direction::DOWN, 100).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xEB }); // CAL --> NOP | Disable debugger check when miles searches for audio device to allow attaching the debugger to the game upon launch.
|
||||
|
||||
p_SQVM_CompileError.Offset(0x0).FindPatternSelf("41 B0 01", CMemory::Direction::DOWN, 400).Patch({ 0x41, 0xB0, 0x00 }); // MOV --> MOV | Set script error level to 0 (not severe): 'mov r8b, 0'.
|
||||
p_SQVM_CompileError.Offset(0xE0).FindPatternSelf("E8", CMemory::Direction::DOWN, 200).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 }); // CAL --> NOP | TODO: causes errors on client script error. Research required (same function as soft error but that one doesn't crash).
|
||||
CMemory(v_SQVM_CompileError).Offset(0x0).FindPatternSelf("41 B0 01", CMemory::Direction::DOWN, 400).Patch({ 0x41, 0xB0, 0x00 }); // MOV --> MOV | Set script error level to 0 (not severe): 'mov r8b, 0'.
|
||||
CMemory(v_SQVM_CompileError).Offset(0xE0).FindPatternSelf("E8", CMemory::Direction::DOWN, 200).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 }); // CAL --> NOP | TODO: causes errors on client script error. Research required (same function as soft error but that one doesn't crash).
|
||||
#else
|
||||
p_SQVM_CompileError.Offset(0xE0).FindPatternSelf("E8", CMemory::Direction::DOWN, 200).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 }); // CAL --> NOP | For dedicated we should not perform post-error events such as telemetry / showing 'COM_ExplainDisconnection' UI etc.
|
||||
CMemory(v_SQVM_CompileError).Offset(0xE0).FindPatternSelf("E8", CMemory::Direction::DOWN, 200).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 }); // CAL --> NOP | For dedicated we should not perform post-error events such as telemetry / showing 'COM_ExplainDisconnection' UI etc.
|
||||
#endif // !DEDICATED
|
||||
|
||||
#if defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
#ifndef CLIENT_DLL
|
||||
//p_CAI_NetworkManager__ShouldRebuild.Offset(0xA0).FindPatternSelf("FF ?? ?? ?? 00 00", CMemory::Direction::DOWN, 200).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); // CAL --> NOP | Virtual call to restart when building AIN (which clears the AIN memory). Remove this once writing to file works.
|
||||
//p_Detour_LevelInit.Offset(0x100).FindPatternSelf("74", CMemory::Direction::DOWN, 600).Patch({ 0xEB }); // JE --> JMP | Do while loop setting fields to -1 in navmesh is writing out of bounds (!TODO).
|
||||
#endif // !CLIENT_DLL
|
||||
#endif
|
||||
#ifndef CLIENT_DLL
|
||||
// !!!TODO!!! HACK: this needs to be removed asap! fix the entitlements file formatting on git itself.
|
||||
Server_S2C_CONNECT_1.Offset(0x7).Patch({ 0xEB }); // JZ --> JMP | Prevent entitlement check to kick player from server on S2C_CONNECT Packet if it does not match the servers one.
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
vector<uint8_t> starPakOpenFile = {
|
||||
0x4D, 0x31, 0xC0, // xor, r8, r8
|
||||
0x48, 0x8D, 0x8C, 0x24, 0x90, 0x00, 0x00, 0x00, // lea rcx, [rsp+378h+90h] FileName
|
||||
|
||||
// call RTech::OpenFile [RIP+RVA]
|
||||
#if defined (GAMEDLL_S0)
|
||||
0xE8, 0x87, 0x96, 0xFF, 0xFF,
|
||||
#elif defined (GAMEDLL_S1)
|
||||
0xE8, 0x27, 0x95, 0xFF, 0xFF,
|
||||
#elif defined (GAMEDLL_S2)
|
||||
0xE8, 0x87, 0x95, 0xFF, 0xFF,
|
||||
#elif defined (GAMEDLL_S3)
|
||||
0xE8, 0x77, 0x8F, 0xFF, 0xFF,
|
||||
#endif
|
||||
|
||||
0x8B, 0xF8, // mov edi, eax
|
||||
|
||||
// jmp [RIP+RVA]
|
||||
#if defined (GAMEDLL_S0) || defined(GAMEDLL_S1)
|
||||
0xE9, 0xDC, 0x00, 0x00, 0x00
|
||||
#elif defined (GAMEDLL_S2) || defined(GAMEDLL_S3)
|
||||
0xE9, 0xDA, 0x00, 0x00, 0x00
|
||||
#endif
|
||||
};
|
||||
|
||||
p_CPakFile_OpenFileOffset.Patch(starPakOpenFile);
|
||||
}
|
||||
|
@ -58,13 +58,6 @@ inline CMemory Host_Shutdown;
|
||||
//-------------------------------------------------------------------------
|
||||
inline CMemory Host_Disconnect;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: S2C_CHALLENGE
|
||||
//-------------------------------------------------------------------------
|
||||
#ifndef CLIENT_DLL
|
||||
inline CMemory Server_S2C_CONNECT_1;
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME:
|
||||
//-------------------------------------------------------------------------
|
||||
@ -88,9 +81,6 @@ class VOpcodes : public IDetour
|
||||
// LogFunAdr("Sys_InitGame", Sys_InitGame.GetPtr());
|
||||
// LogFunAdr("Host_Init_1", gHost_Init_1.GetPtr());
|
||||
// LogFunAdr("Host_Init_2", gHost_Init_2.GetPtr());
|
||||
#ifndef CLIENT_DLL
|
||||
LogFunAdr("Server_S2C_CONNECT", Server_S2C_CONNECT_1.GetPtr());
|
||||
#endif // !CLIENT_DLL
|
||||
// LogFunAdr("GetEngineClientThread", GetEngineClientThread.GetPtr());
|
||||
// LogFunAdr("MatchMaking_Frame", MatchMaking_Frame.GetPtr());
|
||||
//#if !defined (GAMEDLL_S0) || !defined (GAMEDLL_S1)
|
||||
@ -148,9 +138,6 @@ class VOpcodes : public IDetour
|
||||
// // 0x140236640 // 88 4C 24 08 53 55 56 57 48 83 EC 68 //
|
||||
//
|
||||
// //-------------------------------------------------------------------------
|
||||
#ifndef CLIENT_DLL
|
||||
Server_S2C_CONNECT_1 = g_GameDll.FindPatternSIMD("48 3B 05 ?? ?? ?? ?? 74 0C");
|
||||
#endif // !CLIENT_DLL
|
||||
//
|
||||
// //-------------------------------------------------------------------------
|
||||
//#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
@ -174,7 +161,6 @@ class VOpcodes : public IDetour
|
||||
//#endif //48 83 EC 28 33 C9 FF 15 ? ? ? ? 48 8D 0D ? ? ? ?
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
45
r5dev/common/proto_oob.h
Normal file
45
r5dev/common/proto_oob.h
Normal file
@ -0,0 +1,45 @@
|
||||
//============ Copyright Valve Corporation, All rights reserved. ==============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#if !defined( PROTO_OOB_H )
|
||||
#define PROTO_OOB_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "proto_version.h"
|
||||
|
||||
#define PORT_RCON 37015 // default RCON port, TCP
|
||||
#define PORT_SERVER 37015 // Default server port, UDP/TCP
|
||||
#define PORT_CLIENT 37005 // Default client port, UDP/TCP
|
||||
|
||||
// Out of band message id bytes
|
||||
// Prefixes: S = server, C = client, A = any
|
||||
|
||||
#define C2S_CONNECT 'A' // client requests to connect
|
||||
#define S2C_DISCONNECT 'B' // server requests to disconnect
|
||||
|
||||
#define C2S_CHALLENGE 'H' // + challenge value
|
||||
#define S2C_CHALLENGE 'I' // + challenge value
|
||||
|
||||
#define S2C_CONNACCEPT 'J'
|
||||
#define S2C_CONNREJECT 'K' // special protocol for rejected connections
|
||||
|
||||
// Generic Ping Request
|
||||
#define A2A_PING 'L' // respond with an A2A_ACK
|
||||
#define A2A_ACK 'M' // general acknowledgment without info
|
||||
|
||||
#define S2C_UNKNOWN_UISCRIPT 'N' // TODO: figure out what this does, see [r5apex + 0x288880]
|
||||
|
||||
// Data Block Request
|
||||
#define S2C_DATABLOCK_FRAGMENT 'O' // data block fragment
|
||||
#define C2S_DATABLOCK_ACK 'P' // data block fragment acknowledgment
|
||||
|
||||
// All OOB packet start with this sequence
|
||||
#define CONNECTIONLESS_HEADER 0xFFFFFFFF
|
||||
|
||||
#endif
|
17
r5dev/common/proto_version.h
Normal file
17
r5dev/common/proto_version.h
Normal file
@ -0,0 +1,17 @@
|
||||
//============ Copyright Valve Corporation, All rights reserved. ==============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#if !defined( PROTO_VERSION_H )
|
||||
#define PROTO_VERSION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// The current network protocol version. Changing this makes clients and servers incompatible
|
||||
#define PROTOCOL_VERSION 529
|
||||
|
||||
#endif
|
@ -4,13 +4,20 @@
|
||||
* _protocol.h
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
// Largest # of commands to send in a packet
|
||||
#define NUM_NEW_COMMAND_BITS 4
|
||||
#define MAX_NEW_COMMANDS ((1 << NUM_NEW_COMMAND_BITS)-1)
|
||||
|
||||
// Max number of history commands to send ( 2 by default ) in case of dropped packets
|
||||
#define NUM_BACKUP_COMMAND_BITS 4 // Originally 3 bits.
|
||||
#define MAX_BACKUP_COMMANDS ((1 << NUM_BACKUP_COMMAND_BITS)-1) // 15 in R5; see 'CL_Move'.
|
||||
#define NUM_BACKUP_COMMAND_BITS 3
|
||||
#define MAX_BACKUP_COMMANDS ((1 << NUM_BACKUP_COMMAND_BITS)-1)
|
||||
|
||||
// Maximum amount of backup commands to process on the server.
|
||||
#define MAX_BACKUP_COMMANDS_PROCESS (MAX_BACKUP_COMMANDS+1) * NUM_BACKUP_COMMAND_BITS
|
||||
#define MAX_QUEUED_COMMANDS_PROCESS 0x1B0
|
||||
#define MAX_BACKUP_COMMANDS_PROCESS 64
|
||||
#define MAX_QUEUED_COMMANDS_PROCESS 432
|
||||
|
||||
// The size of the snapshot scratch buffer, which also applies to data block packets
|
||||
#define SNAPSHOT_SCRATCH_BUFFER_SIZE 786432
|
||||
|
||||
enum class SIGNONSTATE : int
|
||||
{
|
||||
@ -31,9 +38,17 @@ enum class PERSISTENCE : int
|
||||
PERSISTENCE_NONE = 0, // no persistence data for this client yet.
|
||||
PERSISTENCE_PENDING = 1, // pending or processing persistence data.
|
||||
PERSISTENCE_AVAILABLE = 2, // persistence is available for this client.
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
PERSISTENCE_READY = 3 // persistence is ready for this client.
|
||||
#else
|
||||
PERSISTENCE_READY = 5 // persistence is ready for this client.
|
||||
#endif
|
||||
};
|
||||
|
||||
#define net_NOP 0 // nop command used for padding.
|
||||
#define net_Disconnect 1 // disconnect, last message in connection.
|
||||
|
||||
// each channel packet has 1 byte of FLAG bits
|
||||
#define PACKET_FLAG_RELIABLE (1<<0) // packet contains subchannel stream data
|
||||
#define PACKET_FLAG_COMPRESSED (1<<1) // packet is compressed
|
||||
#define PACKET_FLAG_ENCRYPTED (1<<2) // packet is encrypted
|
||||
#define PACKET_FLAG_SPLIT (1<<3) // packet is split
|
||||
#define PACKET_FLAG_CHOKED (1<<4) // packet was choked by sender
|
||||
#define PACKET_FLAG_PRESCALED (1<<5) // packet was sent by sender with prescaled frame time
|
||||
#define PACKET_FLAG_LOOPBACK (1<<6) // packet was sent from loopback connection
|
||||
|
@ -21,6 +21,27 @@ typedef uintptr_t uintp;
|
||||
typedef intptr_t intp;
|
||||
|
||||
typedef const unsigned char* rsig_t;
|
||||
|
||||
// 32bit and 64bit wide boolean type
|
||||
typedef int32_t b32;
|
||||
typedef int64_t b64;
|
||||
|
||||
// signed size types
|
||||
typedef std::make_signed_t<std::size_t> ssize_t;
|
||||
|
||||
#ifndef SSIZE_MAX
|
||||
#ifdef _WIN64
|
||||
#define SSIZE_MAX 9223372036854775807i64
|
||||
#define SSIZE_MIN (-9223372036854775807i64 - 1)
|
||||
#else
|
||||
#define SSIZE_MAX 2147483647
|
||||
#define SSIZE_MIN (-2147483647 - 1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// unsigned size types
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
#endif // SDKDEFS_H
|
||||
|
52
r5dev/common/xbox/xboxstubs.h
Normal file
52
r5dev/common/xbox/xboxstubs.h
Normal file
@ -0,0 +1,52 @@
|
||||
//========= Copyright 1996-2004, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Win32 replacements for XBox.
|
||||
//
|
||||
//=============================================================================
|
||||
#if !defined( XBOXSTUBS_H ) && !defined( _X360 )
|
||||
#define XBOXSTUBS_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XK_BUTTON_UP,
|
||||
XK_BUTTON_DOWN,
|
||||
XK_BUTTON_LEFT,
|
||||
XK_BUTTON_RIGHT,
|
||||
|
||||
XK_BUTTON_START,
|
||||
XK_BUTTON_BACK,
|
||||
|
||||
XK_BUTTON_STICK1,
|
||||
XK_BUTTON_STICK2,
|
||||
|
||||
XK_BUTTON_A,
|
||||
XK_BUTTON_B,
|
||||
XK_BUTTON_X,
|
||||
XK_BUTTON_Y,
|
||||
|
||||
XK_BUTTON_LEFT_SHOULDER,
|
||||
XK_BUTTON_RIGHT_SHOULDER,
|
||||
|
||||
XK_XBUTTON_LTRIGGER_PARTIAL,
|
||||
XK_XBUTTON_LTRIGGER_FULL,
|
||||
|
||||
XK_XBUTTON_RTRIGGER_PARTIAL,
|
||||
XK_XBUTTON_RTRIGGER_FULL,
|
||||
|
||||
XK_STICK1_UP,
|
||||
XK_STICK1_DOWN,
|
||||
XK_STICK1_LEFT,
|
||||
XK_STICK1_RIGHT,
|
||||
|
||||
XK_STICK2_UP,
|
||||
XK_STICK2_DOWN,
|
||||
XK_STICK2_LEFT,
|
||||
XK_STICK2_RIGHT,
|
||||
|
||||
XK_UP_DOWN,
|
||||
XK_LEFT_RIGHT,
|
||||
|
||||
XK_MAX_KEYS,
|
||||
} xKey_t;
|
||||
|
||||
#endif // XBOXSTUBS_H
|
@ -41,6 +41,8 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
|
||||
"wldap32.lib"
|
||||
"ws2_32.lib"
|
||||
"Rpcrt4.lib"
|
||||
"iphlpapi.lib"
|
||||
"Winmm.lib"
|
||||
|
||||
"vpc"
|
||||
"memoverride"
|
||||
@ -56,26 +58,35 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
|
||||
"vphysics"
|
||||
|
||||
"SigCache_Pb"
|
||||
"LiveAPI_Pb"
|
||||
"SV_RCon_Pb"
|
||||
"CL_RCon_Pb"
|
||||
|
||||
"rtech_tools"
|
||||
"rson"
|
||||
"rtech_game"
|
||||
"playlists"
|
||||
"stryder"
|
||||
|
||||
"libdetours"
|
||||
"liblzham"
|
||||
"libzstd"
|
||||
"liblz4"
|
||||
|
||||
"libdetours"
|
||||
"libcurl"
|
||||
"libprotobuf"
|
||||
"libspdlog"
|
||||
"libdetour"
|
||||
"navdebugutils"
|
||||
|
||||
"EAThread"
|
||||
"DirtySDK"
|
||||
|
||||
"networksystem"
|
||||
"pluginsystem"
|
||||
"filesystem"
|
||||
"datacache"
|
||||
"EbisuSDK"
|
||||
"GFSDK"
|
||||
|
||||
"localize"
|
||||
|
||||
@ -98,6 +109,16 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
|
||||
"rui"
|
||||
|
||||
"d3d11.lib"
|
||||
"${THIRDPARTY_SOURCE_DIR}/nvapi/amd64/nvapi64.lib"
|
||||
)
|
||||
endif()
|
||||
|
||||
if( NOT ${PROJECT_NAME} STREQUAL "client" )
|
||||
target_link_libraries( ${PROJECT_NAME} PRIVATE
|
||||
"libmbedcrypto"
|
||||
"libmbedtls"
|
||||
"libmbedx509"
|
||||
"libjwt"
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -141,6 +162,11 @@ target_compile_definitions( ${PROJECT_NAME} PRIVATE
|
||||
|
||||
endif()
|
||||
|
||||
target_include_directories( ${PROJECT_NAME} PRIVATE
|
||||
"${THIRDPARTY_SOURCE_DIR}/dirtysdk/include/"
|
||||
"${THIRDPARTY_SOURCE_DIR}/ea/"
|
||||
)
|
||||
|
||||
target_link_options( ${PROJECT_NAME} PRIVATE
|
||||
"/STACK:8000000" # Match game executable stack reserve size
|
||||
|
||||
|
@ -10,4 +10,5 @@
|
||||
// } while (false)
|
||||
//#else
|
||||
# define Assert(condition, ...) assert(condition)
|
||||
# define AssertFatalMsg Assert
|
||||
//#endif
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "core/init.h"
|
||||
#include "core/logdef.h"
|
||||
#include "core/logger.h"
|
||||
#include "tier0/cpu.h"
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/crashhandler.h"
|
||||
#include "tier0/commandline.h"
|
||||
@ -15,6 +16,7 @@
|
||||
#include "windows/system.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "protobuf/stubs/common.h"
|
||||
|
||||
#ifndef DEDICATED
|
||||
#define SDK_DEFAULT_CFG "cfg/system/startup_default.cfg"
|
||||
@ -24,6 +26,12 @@
|
||||
|
||||
bool g_bSdkInitialized = false;
|
||||
|
||||
bool g_bSdkInitCallInitiated = false;
|
||||
bool g_bSdkShutdownCallInitiated = false;
|
||||
|
||||
bool g_bSdkShutdownInitiatedFromConsoleHandler = false;
|
||||
HMODULE s_hModuleHandle = NULL;
|
||||
|
||||
//#############################################################################
|
||||
// UTILITY
|
||||
//#############################################################################
|
||||
@ -41,14 +49,14 @@ void Show_Emblem()
|
||||
// Logged as 'SYSTEM_ERROR' for its red color.
|
||||
for (size_t i = 0; i < SDK_ARRAYSIZE(R5R_EMBLEM); i++)
|
||||
{
|
||||
DevMsg(eDLL_T::SYSTEM_ERROR, "%s\n", R5R_EMBLEM[i]);
|
||||
Msg(eDLL_T::SYSTEM_ERROR, "%s\n", R5R_EMBLEM[i]);
|
||||
}
|
||||
|
||||
// Log the SDK's 'build_id' under the emblem.
|
||||
DevMsg(eDLL_T::SYSTEM_ERROR,
|
||||
Msg(eDLL_T::SYSTEM_ERROR,
|
||||
"+------------------------------------------------[%s%010d%s]-+\n",
|
||||
g_svYellowF, g_SDKDll.GetNTHeaders()->FileHeader.TimeDateStamp, g_svRedF);
|
||||
DevMsg(eDLL_T::SYSTEM_ERROR, "\n");
|
||||
Msg(eDLL_T::SYSTEM_ERROR, "\n");
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
@ -62,12 +70,10 @@ void Tier0_Init()
|
||||
g_RadAudioDecoderDll.InitFromName("binkawin64.dll");
|
||||
g_RadAudioSystemDll.InitFromName("mileswin64.dll");
|
||||
#endif // !DEDICATED
|
||||
|
||||
g_pCmdLine = g_GameDll.GetExportedSymbol("g_pCmdLine").RCast<CCommandLine*>();
|
||||
g_CoreMsgVCallback = &EngineLoggerSink; // Setup logger callback sink.
|
||||
|
||||
g_pCmdLine->CreateCmdLine(GetCommandLineA());
|
||||
g_CrashHandler->SetCrashCallback(&Crash_Callback);
|
||||
g_CrashHandler.SetCrashCallback(&Crash_Callback);
|
||||
|
||||
// This prevents the game from recreating it,
|
||||
// see 'CCommandLine::StaticCreateCmdLine' for
|
||||
@ -77,6 +83,28 @@ void Tier0_Init()
|
||||
|
||||
void SDK_Init()
|
||||
{
|
||||
assert(!g_bSdkInitialized);
|
||||
|
||||
CheckSystemCPU(); // Check CPU as early as possible; error out if CPU isn't supported.
|
||||
|
||||
if (g_bSdkInitCallInitiated)
|
||||
{
|
||||
spdlog::error("Recursive initialization!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set after checking cpu and initializing MathLib since we check CPU
|
||||
// features there. Else we crash on the recursive initialization error as
|
||||
// SpdLog uses SSE features.
|
||||
g_bSdkInitCallInitiated = true;
|
||||
|
||||
MathLib_Init(); // Initialize Mathlib.
|
||||
|
||||
PEB64* pEnv = CModule::GetProcessEnvironmentBlock();
|
||||
|
||||
g_GameDll.InitFromBase(pEnv->ImageBaseAddress);
|
||||
g_SDKDll.InitFromBase((QWORD)s_hModuleHandle);
|
||||
|
||||
Tier0_Init();
|
||||
|
||||
if (!CommandLine()->CheckParm("-launcher"))
|
||||
@ -96,7 +124,9 @@ void SDK_Init()
|
||||
SpdLog_Init(bAnsiColor);
|
||||
Show_Emblem();
|
||||
|
||||
Winsock_Init(); // Initialize Winsock.
|
||||
Winsock_Startup(); // Initialize Winsock.
|
||||
DirtySDK_Startup();
|
||||
|
||||
Systems_Init();
|
||||
|
||||
WinSys_Init();
|
||||
@ -104,6 +134,7 @@ void SDK_Init()
|
||||
Input_Init();
|
||||
#endif // !DEDICATED
|
||||
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
lzham_enable_fail_exceptions(true);
|
||||
|
||||
@ -118,14 +149,26 @@ void SDK_Shutdown()
|
||||
{
|
||||
assert(g_bSdkInitialized);
|
||||
|
||||
if (!g_bSdkInitialized)
|
||||
// Also check CPU in shutdown, since this function is exported, if they
|
||||
// call this with an unsupported CPU we should let them know rather than
|
||||
// crashing the process.
|
||||
CheckSystemCPU();
|
||||
|
||||
if (g_bSdkShutdownCallInitiated)
|
||||
{
|
||||
spdlog::error("Recursive shutdown!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
g_bSdkInitialized = false;
|
||||
DevMsg(eDLL_T::NONE, "GameSDK shutdown initiated\n");
|
||||
g_bSdkShutdownCallInitiated = true;
|
||||
|
||||
if (!g_bSdkInitialized)
|
||||
{
|
||||
spdlog::error("Not initialized!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Msg(eDLL_T::NONE, "GameSDK shutdown initiated\n");
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
@ -135,10 +178,18 @@ void SDK_Shutdown()
|
||||
|
||||
WinSys_Shutdown();
|
||||
Systems_Shutdown();
|
||||
|
||||
DirtySDK_Shutdown();
|
||||
Winsock_Shutdown();
|
||||
|
||||
SpdLog_Shutdown();
|
||||
|
||||
// If the shutdown was initiated from the console window itself, don't
|
||||
// shutdown the console as it would otherwise deadlock in FreeConsole!
|
||||
if (!g_bSdkShutdownInitiatedFromConsoleHandler)
|
||||
Console_Shutdown();
|
||||
|
||||
g_bSdkInitialized = false;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
@ -147,27 +198,18 @@ void SDK_Shutdown()
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
CheckCPU(); // Check CPU as early as possible; error out if CPU isn't supported.
|
||||
MathLib_Init(); // Initialize Mathlib.
|
||||
|
||||
NOTE_UNUSED(lpReserved);
|
||||
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
PEB64* pEnv = CModule::GetProcessEnvironmentBlock();
|
||||
|
||||
g_GameDll.InitFromBase(pEnv->ImageBaseAddress);
|
||||
g_SDKDll.InitFromBase((QWORD)hModule);
|
||||
|
||||
SDK_Init();
|
||||
s_hModuleHandle = hModule;
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
SDK_Shutdown();
|
||||
s_hModuleHandle = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,8 @@
|
||||
#include "tier0/sigcache.h"
|
||||
#include "tier1/cmd.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "tier1/keyvalues_iface.h"
|
||||
#include "vpc/IAppSystem.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "vpc/rson.h"
|
||||
#include "vpc/interfaces.h"
|
||||
#include "common/callback.h"
|
||||
#include "common/completion.h"
|
||||
@ -38,6 +37,7 @@
|
||||
#include "codecs/miles/miles_impl.h"
|
||||
#include "codecs/miles/radshal_wasapi.h"
|
||||
#endif // !DEDICATED
|
||||
#include "vphysics/physics_collide.h"
|
||||
#include "vphysics/QHull.h"
|
||||
#include "engine/staticpropmgr.h"
|
||||
#include "materialsystem/cmaterialsystem.h"
|
||||
@ -46,6 +46,7 @@
|
||||
#include "vgui/vgui_baseui_interface.h"
|
||||
#include "vgui/vgui_debugpanel.h"
|
||||
#include "vgui/vgui_fpspanel.h"
|
||||
#include "vgui/vgui_controls/RichText.h"
|
||||
#include "vguimatsurface/MatSystemSurface.h"
|
||||
#include "engine/client/vengineclient_impl.h"
|
||||
#include "engine/client/cdll_engine_int.h"
|
||||
@ -58,13 +59,23 @@
|
||||
#include "engine/server/datablock_sender.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "studiorender/studiorendercontext.h"
|
||||
#include "rtech/rtech_game.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "rtech/liveapi/liveapi.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "rtech/rstdlib.h"
|
||||
#include "rtech/rson.h"
|
||||
#include "rtech/async/asyncio.h"
|
||||
#include "rtech/pak/pakalloc.h"
|
||||
#include "rtech/pak/pakparse.h"
|
||||
#include "rtech/pak/pakstate.h"
|
||||
#include "rtech/pak/pakstream.h"
|
||||
#include "rtech/stryder/stryder.h"
|
||||
#include "rtech/playlists/playlists.h"
|
||||
#ifndef DEDICATED
|
||||
#include "rtech/rui/rui.h"
|
||||
#include "engine/client/cl_ents_parse.h"
|
||||
#include "engine/client/cl_main.h"
|
||||
#include "engine/client/cl_rcon.h"
|
||||
#include "engine/client/cl_splitscreen.h"
|
||||
#endif // !DEDICATED
|
||||
#include "engine/client/client.h"
|
||||
@ -87,6 +98,7 @@
|
||||
#include "engine/networkstringtable.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/sv_main.h"
|
||||
#include "engine/server/sv_rcon.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "engine/sdk_dll.h"
|
||||
#include "engine/sys_dll.h"
|
||||
@ -95,13 +107,15 @@
|
||||
#include "engine/sys_utils.h"
|
||||
#ifndef DEDICATED
|
||||
#include "engine/sys_getmodes.h"
|
||||
#include "engine/gl_rmain.h"
|
||||
#include "engine/sys_mainwind.h"
|
||||
#include "engine/matsys_interface.h"
|
||||
#include "engine/gl_rmain.h"
|
||||
#include "engine/gl_matsysiface.h"
|
||||
#include "engine/gl_drawlights.h"
|
||||
#include "engine/gl_screen.h"
|
||||
#include "engine/gl_rsurf.h"
|
||||
#include "engine/debugoverlay.h"
|
||||
#include "engine/keys.h"
|
||||
#endif // !DEDICATED
|
||||
#include "vscript/languages/squirrel_re/include/squirrel.h"
|
||||
#include "vscript/languages/squirrel_re/include/sqvm.h"
|
||||
@ -137,6 +151,11 @@
|
||||
#include "windows/id3dx.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
#include "DirtySDK/dirtysock.h"
|
||||
#include "DirtySDK/dirtysock/netconn.h"
|
||||
#include "DirtySDK/proto/protossl.h"
|
||||
#include "DirtySDK/proto/protowebsocket.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -176,7 +195,7 @@ void ScriptConstantRegistrationCallback(CSquirrelVM* s)
|
||||
|
||||
void Systems_Init()
|
||||
{
|
||||
DevMsg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
Msg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
QuerySystemInfo();
|
||||
|
||||
DetourRegister();
|
||||
@ -186,8 +205,8 @@ void Systems_Init()
|
||||
DetourInit();
|
||||
initTimer.End();
|
||||
|
||||
DevMsg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
DevMsg(eDLL_T::NONE, "%-16s '%10.6f' seconds ('%12lu' clocks)\n", "Detour->InitDB()",
|
||||
Msg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
Msg(eDLL_T::NONE, "%-16s '%10.6f' seconds ('%12lu' clocks)\n", "Detour->InitDB()",
|
||||
initTimer.GetDuration().GetSeconds(), initTimer.GetDuration().GetCycles());
|
||||
|
||||
initTimer.Start();
|
||||
@ -197,9 +216,9 @@ void Systems_Init()
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
// Hook functions
|
||||
for (const IDetour* Detour : g_DetourVec)
|
||||
for (const IDetour* pd : g_DetourVec)
|
||||
{
|
||||
Detour->Attach();
|
||||
pd->Detour(true);
|
||||
}
|
||||
|
||||
// Patch instructions
|
||||
@ -210,16 +229,15 @@ void Systems_Init()
|
||||
if (hr != NO_ERROR)
|
||||
{
|
||||
// Failed to hook into the process, terminate
|
||||
Assert(0);
|
||||
Error(eDLL_T::COMMON, 0xBAD0C0DE, "Failed to detour process: error code = %08x\n", hr);
|
||||
}
|
||||
|
||||
initTimer.End();
|
||||
DevMsg(eDLL_T::NONE, "%-16s '%10.6f' seconds ('%12lu' clocks)\n", "Detour->Attach()",
|
||||
Msg(eDLL_T::NONE, "%-16s '%10.6f' seconds ('%12lu' clocks)\n", "Detour->Attach()",
|
||||
initTimer.GetDuration().GetSeconds(), initTimer.GetDuration().GetCycles());
|
||||
DevMsg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
DevMsg(eDLL_T::NONE, "\n");
|
||||
|
||||
ConVar_StaticInit();
|
||||
Msg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
Msg(eDLL_T::NONE, "\n");
|
||||
|
||||
#ifdef DEDICATED
|
||||
InitCommandLineParameters();
|
||||
@ -232,6 +250,8 @@ void Systems_Init()
|
||||
ServerScriptRegister_Callback = Script_RegisterServerFunctions;
|
||||
CoreServerScriptRegister_Callback = Script_RegisterCoreServerFunctions;
|
||||
AdminPanelScriptRegister_Callback = Script_RegisterAdminPanelFunctions;
|
||||
|
||||
ServerScriptRegisterEnum_Callback = Script_RegisterServerEnums;
|
||||
#endif// !CLIENT_DLL
|
||||
|
||||
#ifndef SERVER_DLL
|
||||
@ -257,6 +277,18 @@ void Systems_Init()
|
||||
|
||||
void Systems_Shutdown()
|
||||
{
|
||||
// Shutdown RCON (closes all open sockets)
|
||||
#ifndef CLIENT_DLL
|
||||
RCONServer()->Shutdown();
|
||||
#endif// !CLIENT_DLL
|
||||
#ifndef SERVER_DLL
|
||||
RCONClient()->Shutdown();
|
||||
#endif // !SERVER_DLL
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
LiveAPISystem()->Shutdown();
|
||||
#endif// !CLIENT_DLL
|
||||
|
||||
CFastTimer shutdownTimer;
|
||||
shutdownTimer.Start();
|
||||
|
||||
@ -265,19 +297,19 @@ void Systems_Shutdown()
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
// Unhook functions
|
||||
for (const IDetour* Detour : g_DetourVec)
|
||||
for (const IDetour* pd : g_DetourVec)
|
||||
{
|
||||
Detour->Detach();
|
||||
pd->Detour(false);
|
||||
}
|
||||
|
||||
// Commit the transaction
|
||||
DetourTransactionCommit();
|
||||
|
||||
shutdownTimer.End();
|
||||
DevMsg(eDLL_T::NONE, "%-16s '%10.6f' seconds ('%12lu' clocks)\n", "Detour->Detach()",
|
||||
Msg(eDLL_T::NONE, "%-16s '%10.6f' seconds ('%12lu' clocks)\n", "Detour->Detach()",
|
||||
shutdownTimer.GetDuration().GetSeconds(), shutdownTimer.GetDuration().GetCycles());
|
||||
DevMsg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
DevMsg(eDLL_T::NONE, "\n");
|
||||
Msg(eDLL_T::NONE, "+-------------------------------------------------------------+\n");
|
||||
Msg(eDLL_T::NONE, "\n");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
@ -291,25 +323,51 @@ void Systems_Shutdown()
|
||||
//
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
void Winsock_Init()
|
||||
void Winsock_Startup()
|
||||
{
|
||||
WSAData wsaData{};
|
||||
int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
const int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
|
||||
if (nError != 0)
|
||||
{
|
||||
Error(eDLL_T::COMMON, NO_ERROR, "%s: Failed to start Winsock: (%s)\n",
|
||||
Error(eDLL_T::COMMON, 0, "%s: Windows Sockets API startup failure: (%s)\n",
|
||||
__FUNCTION__, NET_ErrorString(WSAGetLastError()));
|
||||
}
|
||||
}
|
||||
|
||||
void Winsock_Shutdown()
|
||||
{
|
||||
int nError = ::WSACleanup();
|
||||
const int nError = ::WSACleanup();
|
||||
|
||||
if (nError != 0)
|
||||
{
|
||||
Error(eDLL_T::COMMON, NO_ERROR, "%s: Failed to stop Winsock: (%s)\n",
|
||||
Error(eDLL_T::COMMON, 0, "%s: Windows Sockets API shutdown failure: (%s)\n",
|
||||
__FUNCTION__, NET_ErrorString(WSAGetLastError()));
|
||||
}
|
||||
}
|
||||
|
||||
void DirtySDK_Startup()
|
||||
{
|
||||
const int32_t netConStartupRet = NetConnStartup("-servicename=sourcesdk");
|
||||
|
||||
if (netConStartupRet < 0)
|
||||
{
|
||||
Error(eDLL_T::COMMON, 0, "%s: Network connection module startup failure: (%i)\n",
|
||||
__FUNCTION__, netConStartupRet);
|
||||
}
|
||||
}
|
||||
|
||||
void DirtySDK_Shutdown()
|
||||
{
|
||||
const int32_t netConShutdownRet = NetConnShutdown(0);
|
||||
|
||||
if (netConShutdownRet < 0)
|
||||
{
|
||||
Error(eDLL_T::COMMON, 0, "%s: Network connection module shutdown failure: (%i)\n",
|
||||
__FUNCTION__, netConShutdownRet);
|
||||
}
|
||||
}
|
||||
|
||||
void QuerySystemInfo()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
@ -324,20 +382,20 @@ void QuerySystemInfo()
|
||||
|
||||
if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) // Only log the primary device.
|
||||
{
|
||||
DevMsg(eDLL_T::NONE, "%-25s: '%s'\n", "GPU model identifier", dd.DeviceString);
|
||||
Msg(eDLL_T::NONE, "%-25s: '%s'\n", "GPU model identifier", dd.DeviceString);
|
||||
}
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
|
||||
const CPUInformation& pi = GetCPUInformation();
|
||||
|
||||
DevMsg(eDLL_T::NONE, "%-25s: '%s'\n","CPU model identifier", pi.m_szProcessorBrand);
|
||||
DevMsg(eDLL_T::NONE, "%-25s: '%s'\n","CPU vendor tag", pi.m_szProcessorID);
|
||||
DevMsg(eDLL_T::NONE, "%-25s: '%12hhu' ('%2hhu' %s)\n", "CPU core count", pi.m_nPhysicalProcessors, pi.m_nLogicalProcessors, "logical");
|
||||
DevMsg(eDLL_T::NONE, "%-25s: '%12lld' ('%6.1f' %s)\n", "CPU core speed", pi.m_Speed, float(pi.m_Speed / 1000000), "MHz");
|
||||
DevMsg(eDLL_T::NONE, "%-20s%s: '%12lu' ('0x%-8X')\n", "L1 cache", "(KiB)", pi.m_nL1CacheSizeKb, pi.m_nL1CacheDesc);
|
||||
DevMsg(eDLL_T::NONE, "%-20s%s: '%12lu' ('0x%-8X')\n", "L2 cache", "(KiB)", pi.m_nL2CacheSizeKb, pi.m_nL2CacheDesc);
|
||||
DevMsg(eDLL_T::NONE, "%-20s%s: '%12lu' ('0x%-8X')\n", "L3 cache", "(KiB)", pi.m_nL3CacheSizeKb, pi.m_nL3CacheDesc);
|
||||
Msg(eDLL_T::NONE, "%-25s: '%s'\n","CPU model identifier", pi.m_szProcessorBrand);
|
||||
Msg(eDLL_T::NONE, "%-25s: '%s'\n","CPU vendor tag", pi.m_szProcessorID);
|
||||
Msg(eDLL_T::NONE, "%-25s: '%12hhu' ('%2hhu' %s)\n", "CPU core count", pi.m_nPhysicalProcessors, pi.m_nLogicalProcessors, "logical");
|
||||
Msg(eDLL_T::NONE, "%-25s: '%12lld' ('%6.1f' %s)\n", "CPU core speed", pi.m_Speed, float(pi.m_Speed / 1000000), "MHz");
|
||||
Msg(eDLL_T::NONE, "%-20s%s: '%12lu' ('0x%-8X')\n", "L1 cache", "(KiB)", pi.m_nL1CacheSizeKb, pi.m_nL1CacheDesc);
|
||||
Msg(eDLL_T::NONE, "%-20s%s: '%12lu' ('0x%-8X')\n", "L2 cache", "(KiB)", pi.m_nL2CacheSizeKb, pi.m_nL2CacheDesc);
|
||||
Msg(eDLL_T::NONE, "%-20s%s: '%12lu' ('0x%-8X')\n", "L3 cache", "(KiB)", pi.m_nL3CacheSizeKb, pi.m_nL3CacheDesc);
|
||||
|
||||
MEMORYSTATUSEX statex{};
|
||||
statex.dwLength = sizeof(statex);
|
||||
@ -350,8 +408,8 @@ void QuerySystemInfo()
|
||||
DWORDLONG availPhysical = (statex.ullAvailPhys / 1024) / 1024;
|
||||
DWORDLONG availVirtual = (statex.ullAvailVirtual / 1024) / 1024;
|
||||
|
||||
DevMsg(eDLL_T::NONE, "%-20s%s: '%12llu' ('%9llu' %s)\n", "Total system memory", "(MiB)", totalPhysical, totalVirtual, "virtual");
|
||||
DevMsg(eDLL_T::NONE, "%-20s%s: '%12llu' ('%9llu' %s)\n", "Avail system memory", "(MiB)", availPhysical, availVirtual, "virtual");
|
||||
Msg(eDLL_T::NONE, "%-20s%s: '%12llu' ('%9llu' %s)\n", "Total system memory", "(MiB)", totalPhysical, totalVirtual, "virtual");
|
||||
Msg(eDLL_T::NONE, "%-20s%s: '%12llu' ('%9llu' %s)\n", "Avail system memory", "(MiB)", availPhysical, availVirtual, "virtual");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -360,30 +418,6 @@ void QuerySystemInfo()
|
||||
}
|
||||
}
|
||||
|
||||
void CheckCPU() // Respawn's engine and our SDK utilize POPCNT, SSE3 and SSSE3 (Supplemental SSE 3 Instructions).
|
||||
{
|
||||
const CPUInformation& pi = GetCPUInformation();
|
||||
static char szBuf[1024];
|
||||
if (!pi.m_bSSE3)
|
||||
{
|
||||
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "SSE 3");
|
||||
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
|
||||
ExitProcess(0xFFFFFFFF);
|
||||
}
|
||||
if (!pi.m_bSSSE3)
|
||||
{
|
||||
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "SSSE 3 (Supplemental SSE 3 Instructions)");
|
||||
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
|
||||
ExitProcess(0xFFFFFFFF);
|
||||
}
|
||||
if (!pi.m_bPOPCNT)
|
||||
{
|
||||
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "POPCNT");
|
||||
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
|
||||
ExitProcess(0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (DEDICATED)
|
||||
#define SIGDB_FILE "cfg/server/startup.bin"
|
||||
#elif defined (CLIENT_DLL)
|
||||
@ -394,27 +428,30 @@ void CheckCPU() // Respawn's engine and our SDK utilize POPCNT, SSE3 and SSSE3 (
|
||||
|
||||
void DetourInit() // Run the sigscan
|
||||
{
|
||||
const bool bLogAdr = CommandLine()->CheckParm("-sig_toconsole") ? true : false;
|
||||
const bool bNoSmap = CommandLine()->CheckParm("-nosmap") ? true : false;
|
||||
const bool bLogAdr = CommandLine()->CheckParm("-sig_toconsole") ? true : false;
|
||||
bool bInitDivider = false;
|
||||
|
||||
g_SigCache.SetDisabled(bNoSmap);
|
||||
g_SigCache.LoadCache(SIGDB_FILE);
|
||||
g_SigCache.ReadCache(SIGDB_FILE);
|
||||
|
||||
for (const IDetour* Detour : g_DetourVec)
|
||||
// No debug logging in non dev builds.
|
||||
const bool bDevMode = !IsCert() && !IsRetail();
|
||||
|
||||
for (const IDetour* pd : g_DetourVec)
|
||||
{
|
||||
Detour->GetCon(); // Constants.
|
||||
Detour->GetFun(); // Functions.
|
||||
Detour->GetVar(); // Variables.
|
||||
pd->GetCon(); // Constants.
|
||||
pd->GetFun(); // Functions.
|
||||
pd->GetVar(); // Variables.
|
||||
|
||||
if (bLogAdr)
|
||||
if (bDevMode && bLogAdr)
|
||||
{
|
||||
if (!bInitDivider)
|
||||
{
|
||||
bInitDivider = true;
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
}
|
||||
Detour->GetAdr();
|
||||
pd->GetAdr();
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
}
|
||||
}
|
||||
@ -431,9 +468,9 @@ void DetourInit() // Run the sigscan
|
||||
void DetourAddress() // Test the sigscan results
|
||||
{
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
for (const IDetour* Detour : g_DetourVec)
|
||||
for (const IDetour* pd : g_DetourVec)
|
||||
{
|
||||
Detour->GetAdr();
|
||||
pd->GetAdr();
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
}
|
||||
}
|
||||
@ -448,7 +485,6 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
|
||||
// Tier1
|
||||
REGISTER(VCommandLine);
|
||||
REGISTER(VConVar);
|
||||
REGISTER(VCVar);
|
||||
|
||||
// VPC
|
||||
@ -492,6 +528,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
#endif // !DEDICATED
|
||||
|
||||
// VPhysics
|
||||
REGISTER(VPhysicsCollide);
|
||||
REGISTER(VQHull);
|
||||
|
||||
// StaticPropMgr
|
||||
@ -509,6 +546,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
// VGui
|
||||
REGISTER(VEngineVGui); // REGISTER CLIENT ONLY!
|
||||
REGISTER(VFPSPanel); // REGISTER CLIENT ONLY!
|
||||
REGISTER(VVGUIRichText); // REGISTER CLIENT ONLY!
|
||||
REGISTER(VMatSystemSurface);
|
||||
|
||||
// Client
|
||||
@ -536,9 +574,17 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
#endif // !DEDICATED
|
||||
|
||||
// RTech
|
||||
REGISTER(V_RTechGame);
|
||||
REGISTER(V_RTechUtils);
|
||||
REGISTER(V_ReSTD);
|
||||
|
||||
REGISTER(V_AsyncIO);
|
||||
|
||||
REGISTER(V_PakAlloc);
|
||||
REGISTER(V_PakParse);
|
||||
REGISTER(V_PakState);
|
||||
REGISTER(V_PakStream);
|
||||
|
||||
REGISTER(VStryder);
|
||||
REGISTER(VPlaylists);
|
||||
|
||||
#ifndef DEDICATED
|
||||
REGISTER(V_Rui);
|
||||
@ -573,6 +619,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
REGISTER(VGL_RMain);
|
||||
REGISTER(VMatSys_Interface);
|
||||
REGISTER(VGL_MatSysIFace);
|
||||
REGISTER(VGL_DrawLights);
|
||||
REGISTER(VGL_Screen);
|
||||
#endif // !DEDICATED
|
||||
|
||||
@ -583,6 +630,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
REGISTER(VGL_RSurf);
|
||||
|
||||
REGISTER(VDebugOverlay); // !TODO: This also needs to be exposed to server dll!!!
|
||||
REGISTER(VKeys);
|
||||
#endif // !DEDICATED
|
||||
|
||||
// VScript
|
||||
@ -632,3 +680,11 @@ void DetourRegister() // Register detour classes to be searched and hooked.
|
||||
REGISTER(VDXGI);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton accessors:
|
||||
//-----------------------------------------------------------------------------
|
||||
IKeyValuesSystem* KeyValuesSystem()
|
||||
{
|
||||
return g_pKeyValuesSystem;
|
||||
}
|
||||
|
@ -1,18 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
void SDK_Init();
|
||||
void SDK_Shutdown();
|
||||
PLATFORM_INTERFACE void SDK_Init();
|
||||
PLATFORM_INTERFACE void SDK_Shutdown();
|
||||
|
||||
void Systems_Init();
|
||||
void Systems_Shutdown();
|
||||
|
||||
void Winsock_Init();
|
||||
void Winsock_Startup();
|
||||
void Winsock_Shutdown();
|
||||
void DirtySDK_Startup();
|
||||
void DirtySDK_Shutdown();
|
||||
void QuerySystemInfo();
|
||||
void CheckCPU();
|
||||
|
||||
void DetourInit();
|
||||
void DetourAddress();
|
||||
void DetourRegister();
|
||||
|
||||
extern bool g_bSdkInitialized;
|
||||
extern bool g_bSdkShutdownInitiatedFromConsoleHandler;
|
||||
|
@ -4,9 +4,47 @@
|
||||
std::shared_ptr<spdlog::logger> g_TermLogger;
|
||||
std::shared_ptr<spdlog::logger> g_ImGuiLogger;
|
||||
|
||||
std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger;
|
||||
|
||||
std::ostringstream g_LogStream;
|
||||
std::shared_ptr<spdlog::sinks::ostream_sink_st> g_LogSink;
|
||||
|
||||
#ifndef _TOOLS
|
||||
static void SpdLog_CreateRotatingLoggers()
|
||||
{
|
||||
/************************
|
||||
* ROTATE LOGGER SETUP *
|
||||
************************/
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("squirrel_re(warning)"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "script_warning.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("squirrel_re"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "script.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "message.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(warning)"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "warning.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(error)"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "error.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("net_trace"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "net_trace.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
#ifndef DEDICATED
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("netconsole"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "netconsole.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
#endif // !DEDICATED
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("filesystem"
|
||||
, fmt::format("{:s}/{:s}", g_LogSessionDirectory, "filesystem.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
}
|
||||
#endif // !_TOOLS
|
||||
|
||||
#ifdef _TOOLS
|
||||
// NOTE: used for tools as additional file logger on top of the existing terminal logger.
|
||||
void SpdLog_InstallSupplementalLogger(const char* pszLoggerName, const char* pszLogFileName, const char* pszPattern, const bool bTruncate)
|
||||
{
|
||||
g_SuppementalToolsLogger = spdlog::basic_logger_mt(pszLoggerName, pszLogFileName, bTruncate);
|
||||
g_SuppementalToolsLogger->set_pattern(pszPattern);
|
||||
}
|
||||
#endif // _TOOLS
|
||||
|
||||
//#############################################################################
|
||||
// SPDLOG INIT
|
||||
//#############################################################################
|
||||
@ -20,9 +58,9 @@ void SpdLog_Init(const bool bAnsiColor)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
g_LogSessionUUID = CreateUUID();
|
||||
g_LogSessionDirectory = fmt::format("platform\\logs\\{:s}", g_LogSessionUUID);
|
||||
g_LogSessionDirectory = fmt::format("platform/logs/{:s}", g_LogSessionUUID);
|
||||
/************************
|
||||
* IMGUI LOGGER SETUP *
|
||||
************************/
|
||||
@ -33,16 +71,16 @@ void SpdLog_Init(const bool bAnsiColor)
|
||||
g_ImGuiLogger->set_pattern("%v");
|
||||
g_ImGuiLogger->set_level(spdlog::level::trace);
|
||||
}
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
/************************
|
||||
* WINDOWS LOGGER SETUP *
|
||||
************************/
|
||||
{
|
||||
#ifdef NETCONSOLE
|
||||
#ifdef _TOOLS
|
||||
g_TermLogger = spdlog::default_logger();
|
||||
#else
|
||||
g_TermLogger = spdlog::stdout_logger_mt("win_console");
|
||||
#endif // NETCONSOLE
|
||||
#endif // _TOOLS
|
||||
|
||||
// Determine if user wants ansi-color logging in the terminal.
|
||||
if (bAnsiColor)
|
||||
@ -57,38 +95,15 @@ void SpdLog_Init(const bool bAnsiColor)
|
||||
//g_TermLogger->set_level(spdlog::level::trace);
|
||||
}
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
spdlog::set_default_logger(g_TermLogger); // Set as default.
|
||||
SpdLog_Create();
|
||||
#endif // !NETCONSOLE
|
||||
SpdLog_CreateRotatingLoggers();
|
||||
#endif // !_TOOLS
|
||||
|
||||
spdlog::set_level(spdlog::level::trace);
|
||||
bInitialized = true;
|
||||
}
|
||||
spdlog::flush_every(std::chrono::seconds(5));
|
||||
|
||||
void SpdLog_Create()
|
||||
{
|
||||
/************************
|
||||
* ROTATE LOGGER SETUP *
|
||||
************************/
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("squirrel_re(warning)"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "script_warning.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("squirrel_re"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "script.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "message.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(warning)"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "warning.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(error)"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "error.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("net_trace"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "net_trace.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
#ifndef DEDICATED
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("netconsole"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "netconsole.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
#endif // !DEDICATED
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("filesystem"
|
||||
, fmt::format("{:s}\\{:s}", g_LogSessionDirectory, "filesystem.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
bInitialized = true;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
@ -97,4 +112,8 @@ void SpdLog_Create()
|
||||
void SpdLog_Shutdown()
|
||||
{
|
||||
spdlog::shutdown();
|
||||
#ifdef _TOOLS
|
||||
// Destroy the tools logger to flush it.
|
||||
g_SuppementalToolsLogger.reset();
|
||||
#endif // !_TOOLS
|
||||
}
|
||||
|
@ -18,11 +18,19 @@ inline bool g_bSpdLog_UseAnsiClr = false;
|
||||
extern std::shared_ptr<spdlog::logger> g_TermLogger;
|
||||
extern std::shared_ptr<spdlog::logger> g_ImGuiLogger;
|
||||
|
||||
#ifdef _TOOLS
|
||||
extern std::shared_ptr<spdlog::logger> g_SuppementalToolsLogger;
|
||||
#endif // _TOOLS
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// IMGUI CONSOLE SINK |
|
||||
extern std::ostringstream g_LogStream;
|
||||
extern std::shared_ptr<spdlog::sinks::ostream_sink_st> g_LogSink;
|
||||
|
||||
void SpdLog_Init(const bool bAnsiColor);
|
||||
void SpdLog_Create(void);
|
||||
void SpdLog_Shutdown(void);
|
||||
|
||||
#ifdef _TOOLS
|
||||
void SpdLog_InstallSupplementalLogger(const char* pszLoggerName, const char* pszLogFileName,
|
||||
const char* pszPattern = "[%Y-%m-%d %H:%M:%S.%e] %v", const bool bTruncate = true);
|
||||
#endif // _TOOLS
|
||||
|
@ -9,13 +9,13 @@
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/sv_rcon.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
#include "vscript/languages/squirrel_re/include/sqstdaux.h"
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
static const std::regex s_AnsiRowRegex("\\\033\\[.*?m");
|
||||
std::mutex g_LogMutex;
|
||||
|
||||
#if !defined (DEDICATED) && !defined (NETCONSOLE)
|
||||
#if !defined (DEDICATED) && !defined (_TOOLS)
|
||||
ImVec4 CheckForWarnings(LogType_t type, eDLL_T context, const ImVec4& defaultCol)
|
||||
{
|
||||
ImVec4 color = defaultCol;
|
||||
@ -67,7 +67,7 @@ ImVec4 GetColorForContext(LogType_t type, eDLL_T context)
|
||||
return CheckForWarnings(type, context, ImVec4(0.81f, 0.81f, 0.81f, 1.00f));
|
||||
}
|
||||
}
|
||||
#endif // !DEDICATED && !NETCONSOLE
|
||||
#endif // !DEDICATED && !_TOOLS
|
||||
|
||||
const char* GetContextNameByIndex(eDLL_T context, const bool ansiColor = false)
|
||||
{
|
||||
@ -150,18 +150,18 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
const char* pszContext = GetContextNameByIndex(context, bUseColor);
|
||||
message.append(pszContext);
|
||||
|
||||
#if !defined (DEDICATED) && !defined (NETCONSOLE)
|
||||
#if !defined (DEDICATED) && !defined (_TOOLS)
|
||||
ImVec4 overlayColor = GetColorForContext(logType, context);
|
||||
eDLL_T overlayContext = context;
|
||||
#endif // !DEDICATED && !NETCONSOLE
|
||||
#endif // !DEDICATED && !_TOOLS
|
||||
|
||||
#if !defined (NETCONSOLE)
|
||||
#if !defined (_TOOLS)
|
||||
bool bSquirrel = false;
|
||||
bool bWarning = false;
|
||||
bool bError = false;
|
||||
#else
|
||||
NOTE_UNUSED(pszLogger);
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Setup logger and context
|
||||
@ -169,24 +169,24 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
switch (logType)
|
||||
{
|
||||
case LogType_t::LOG_WARNING:
|
||||
#if !defined (DEDICATED) && !defined (NETCONSOLE)
|
||||
#if !defined (DEDICATED) && !defined (_TOOLS)
|
||||
overlayContext = eDLL_T::SYSTEM_WARNING;
|
||||
#endif // !DEDICATED && !NETCONSOLE
|
||||
#endif // !DEDICATED && !_TOOLS
|
||||
if (bUseColor)
|
||||
{
|
||||
message.append(g_svYellowF);
|
||||
}
|
||||
break;
|
||||
case LogType_t::LOG_ERROR:
|
||||
#if !defined (DEDICATED) && !defined (NETCONSOLE)
|
||||
#if !defined (DEDICATED) && !defined (_TOOLS)
|
||||
overlayContext = eDLL_T::SYSTEM_ERROR;
|
||||
#endif // !DEDICATED && !NETCONSOLE
|
||||
#endif // !DEDICATED && !_TOOLS
|
||||
if (bUseColor)
|
||||
{
|
||||
message.append(g_svRedF);
|
||||
}
|
||||
break;
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
case LogType_t::SQ_INFO:
|
||||
bSquirrel = true;
|
||||
break;
|
||||
@ -198,7 +198,7 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
bSquirrel = true;
|
||||
bWarning = true;
|
||||
break;
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -211,7 +211,7 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
const string formatted = FormatV(pszFormat, argsCopy);
|
||||
va_end(argsCopy);
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
//-------------------------------------------------------------------------
|
||||
// Colorize script warnings and errors
|
||||
//-------------------------------------------------------------------------
|
||||
@ -253,7 +253,7 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
message.append(g_svYellowF);
|
||||
}
|
||||
}
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
message.append(formatted);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -271,7 +271,11 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
// If a debugger is attached, emit the text there too
|
||||
if (Plat_IsInDebugSession())
|
||||
Plat_DebugString(message.c_str());
|
||||
|
||||
#ifndef _TOOLS
|
||||
// Output is always logged to the file.
|
||||
std::shared_ptr<spdlog::logger> ntlogger = spdlog::get(pszLogger); // <-- Obtain by 'pszLogger'.
|
||||
assert(ntlogger.get() != nullptr);
|
||||
@ -290,14 +294,14 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
g_ImGuiLogger->debug(message);
|
||||
|
||||
const string logStreamBuf = g_LogStream.str();
|
||||
g_pConsole->AddLog(ConLog_t(logStreamBuf, overlayColor));
|
||||
g_Console.AddLog(logStreamBuf.c_str(), ImGui::ColorConvertFloat4ToU32(overlayColor));
|
||||
|
||||
// We can only log to the in-game overlay console when the SDK has
|
||||
// been fully initialized, due to the use of ConVar's.
|
||||
if (g_bSdkInitialized && logLevel >= LogLevel_t::LEVEL_NOTIFY)
|
||||
{
|
||||
// Draw to mini console.
|
||||
g_pOverlay->AddLog(overlayContext, logStreamBuf.c_str());
|
||||
g_TextOverlay.AddLog(overlayContext, logStreamBuf.c_str());
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
@ -307,7 +311,12 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
|
||||
g_LogStream.clear();
|
||||
#endif // !DEDICATED
|
||||
|
||||
#endif // !NETCONSOLE
|
||||
#else
|
||||
if (g_SuppementalToolsLogger)
|
||||
{
|
||||
g_SuppementalToolsLogger->debug(message);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (exitCode) // Terminate the process if an exit code was passed.
|
||||
{
|
||||
|
@ -8,10 +8,10 @@ __declspec(dllexport) void DummyExport()
|
||||
static const char* const R5R_EMBLEM[] =
|
||||
{
|
||||
R"(+-------------------------------------------------------------+)",
|
||||
R"(| ___ ___ ___ _ _ _ ___ ___ |)",
|
||||
R"(| | _ \ __| _ \___| |___ __ _ __| |___ __| | __ _|_ ) |_ ) |)",
|
||||
R"(| | /__ \ / -_) / _ \/ _` / _` / -_) _` | \ V // / _ / / |)",
|
||||
R"(| |_|_\___/_|_\___|_\___/\__,_\__,_\___\__,_| \_//___(_)___| |)",
|
||||
R"(| ___ ___ ___ _ _ _ ___ _ _ |)",
|
||||
R"(| | _ \ __| _ \___| |___ __ _ __| |___ __| | __ _|_ )| | | |)",
|
||||
R"(| | /__ \ / -_) / _ \/ _` / _` / -_) _` | \ V // / |_ _| |)",
|
||||
R"(| |_|_\___/_|_\___|_\___/\__,_\__,_\___\__,_| \_//___(_)|_| |)",
|
||||
R"(| |)"/*,
|
||||
R"(+-------------------------------------------------------------+)"*/
|
||||
};
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <shellapi.h>
|
||||
#include <Psapi.h>
|
||||
#include <setjmp.h>
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
#include <shlobj.h>
|
||||
#include <objbase.h>
|
||||
|
@ -18,8 +18,18 @@
|
||||
#include "thirdparty/lzham/include/lzham_types.h"
|
||||
#include "thirdparty/lzham/include/lzham.h"
|
||||
|
||||
#include "thirdparty/zstd/zstd.h"
|
||||
#include "thirdparty/zstd/decompress/zstd_decompress_internal.h"
|
||||
|
||||
#include "thirdparty/lz4/lz4.h"
|
||||
|
||||
#include "thirdparty/curl/include/curl/curl.h"
|
||||
#include "thirdparty/nlohmann/json.hpp"
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
|
||||
#if !defined(DEDICATED) && !defined(PLUGINSDK)
|
||||
#include "thirdparty/imgui/imgui.h"
|
||||
@ -30,6 +40,10 @@
|
||||
#include "thirdparty/imgui/misc/cpp/imgui_stdlib.h"
|
||||
#include "thirdparty/imgui/backends/imgui_impl_dx11.h"
|
||||
#include "thirdparty/imgui/backends/imgui_impl_win32.h"
|
||||
|
||||
#include "thirdparty/nvapi/pclstats.h"
|
||||
#include "thirdparty/nvapi/nvapi.h"
|
||||
#include "thirdparty/nvapi/nvapi_lite_common.h"
|
||||
#endif // !DEDICATED && !PLUGINSDK
|
||||
|
||||
|
||||
@ -46,11 +60,13 @@
|
||||
#pragma warning(pop)
|
||||
|
||||
// Tier0 includes.
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/wchartypes.h"
|
||||
#include "tier0/memaddr.h"
|
||||
#include "tier0/utility.h"
|
||||
#include "tier0/module.h"
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/platwindow.h"
|
||||
#include "tier0/annotations.h"
|
||||
#include "tier0/commonmacros.h"
|
||||
#include "tier0/memalloc.h"
|
||||
@ -58,6 +74,7 @@
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
// Tier1 includes.
|
||||
#include "tier1/tier1.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "tier1/cmd.h"
|
||||
#include "common/global.h"
|
||||
|
@ -12,12 +12,11 @@
|
||||
#include "datacache/mdlcache.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "rtech/pak/paktools.h"
|
||||
#include "public/studio.h"
|
||||
|
||||
RMDLFallBack_t* g_pMDLFallback = new RMDLFallBack_t();
|
||||
std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
|
||||
CStudioFallbackHandler g_StudioMdlFallbackHandler;
|
||||
#define IS_VALID_DATACACHE_HANDLE(cacheHandle) (cacheHandle && cacheHandle != DC_INVALID_HANDLE)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: finds an MDL
|
||||
@ -26,33 +25,13 @@ std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
// *a3 -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
studiohdr_t* CMDLCache::FindMDL(CMDLCache* const cache, const MDLHandle_t handle, void* a3)
|
||||
{
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
studiohdr_t* pStudioHdr;
|
||||
studiodata_t* const studioData = cache->GetStudioData(handle);
|
||||
|
||||
if (pStudioData)
|
||||
if (!studioData)
|
||||
{
|
||||
if (pStudioData->m_MDLCache &&
|
||||
pStudioData->m_MDLCache != DC_INVALID_HANDLE)
|
||||
{
|
||||
studiohdr_t* pStudioHDR = **reinterpret_cast<studiohdr_t***>(pStudioData);
|
||||
|
||||
if (!g_pMDLFallback->m_hErrorMDL && V_ComparePath(pStudioHDR->name, ERROR_MODEL))
|
||||
{
|
||||
g_pMDLFallback->m_pErrorHDR = pStudioHDR;
|
||||
g_pMDLFallback->m_hErrorMDL = handle;
|
||||
}
|
||||
else if (!g_pMDLFallback->m_hEmptyMDL && V_ComparePath(pStudioHDR->name, EMPTY_MODEL))
|
||||
{
|
||||
g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
|
||||
g_pMDLFallback->m_hEmptyMDL = handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
studiohdr_t* const pStudioHdr = GetErrorModel();
|
||||
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
@ -65,33 +44,56 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
return pStudioHdr;
|
||||
}
|
||||
|
||||
int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
|
||||
if ((pStudioData->m_nFlags & nFlags))
|
||||
studiomodelcache_t* modelCache = studioData->GetModelCache();
|
||||
|
||||
// Store error and empty fallback models.
|
||||
if (IS_VALID_DATACACHE_HANDLE(modelCache))
|
||||
{
|
||||
void* pMDLCache = *reinterpret_cast<void**>(pStudioData);
|
||||
if (pStudioData->m_MDLCache)
|
||||
studiohdr_t* const studioHdr = studioData->GetModelCache()->GetStudioHdr();
|
||||
|
||||
if (studioHdr)
|
||||
{
|
||||
// Typically, you would only check for '(m_nFlags & STUDIODATA_ERROR_MODEL)',
|
||||
// but for some reason this game doesn't have this flag set on that model.
|
||||
if (!HasErrorModel() && ((studioData->flags & STUDIODATA_ERROR_MODEL)
|
||||
|| V_ComparePath(studioHdr->name, ERROR_MODEL)))
|
||||
{
|
||||
g_StudioMdlFallbackHandler.SetFallbackModel(studioHdr, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
|
||||
|
||||
if ((studioData->flags & nFlags))
|
||||
{
|
||||
if (IS_VALID_DATACACHE_HANDLE(modelCache))
|
||||
{
|
||||
if (a3)
|
||||
{
|
||||
FindCachedMDL(cache, pStudioData, a3);
|
||||
pMDLCache = *reinterpret_cast<void**>(pStudioData);
|
||||
FindCachedMDL(cache, studioData, a3);
|
||||
modelCache = studioData->GetModelCache();
|
||||
}
|
||||
|
||||
pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
|
||||
studiohdr_t* const pStudioHdr = modelCache->GetStudioHdr();
|
||||
|
||||
if (pStudioHdr)
|
||||
return pStudioHdr;
|
||||
|
||||
return FindUncachedMDL(cache, handle, pStudioData, a3);
|
||||
return FindUncachedMDL(cache, handle, studioData, a3);
|
||||
}
|
||||
pMDLCache = pStudioData->m_pAnimData;
|
||||
if (pMDLCache)
|
||||
|
||||
studioanimcache_t* const animCache = studioData->GetAnimCache();
|
||||
|
||||
if (IS_VALID_DATACACHE_HANDLE(animCache))
|
||||
{
|
||||
pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
|
||||
studiohdr_t* const pStudioHdr = animCache->GetStudioHdr();
|
||||
|
||||
if (pStudioHdr)
|
||||
return pStudioHdr;
|
||||
}
|
||||
}
|
||||
return FindUncachedMDL(cache, handle, pStudioData, a3);
|
||||
return FindUncachedMDL(cache, handle, studioData, a3);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -100,11 +102,11 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
// *pStudioData -
|
||||
// *a3 -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3)
|
||||
void CMDLCache::FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudioData, void* a3)
|
||||
{
|
||||
if (a3)
|
||||
{
|
||||
AUTO_LOCK(pStudioData->m_Mutex);
|
||||
AUTO_LOCK(pStudioData->mutex);
|
||||
|
||||
*(_QWORD*)((int64_t)a3 + 0x880) = *(_QWORD*)&pStudioData->pad[0x24];
|
||||
int64_t v6 = *(_QWORD*)&pStudioData->pad[0x24];
|
||||
@ -112,7 +114,7 @@ void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void*
|
||||
*(_QWORD*)(v6 + 0x878) = (int64_t)a3;
|
||||
*(_QWORD*)&pStudioData->pad[0x24] = (int64_t)a3;
|
||||
*(_QWORD*)((int64_t)a3 + 0x870) = (int64_t)cache;
|
||||
*(_WORD*)((int64_t)a3 + 0x888) = pStudioData->m_Handle;
|
||||
*(_WORD*)((int64_t)a3 + 0x888) = pStudioData->modelHandle;
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,124 +126,145 @@ void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void*
|
||||
// *a4 -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
|
||||
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
|
||||
{
|
||||
AUTO_LOCK(pStudioData->m_Mutex);
|
||||
AUTO_LOCK(pStudioData->mutex);
|
||||
|
||||
const char* szModelName = cache->GetModelName(handle);
|
||||
size_t nFileNameLen = strlen(szModelName);
|
||||
const char* modelName = cache->GetModelName(handle);
|
||||
const size_t fileNameLen = strlen(modelName);
|
||||
|
||||
studiohdr_t* pStudioHdr;
|
||||
studiohdr_t* studioHdr = nullptr;
|
||||
|
||||
if (nFileNameLen < 5 ||
|
||||
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rmdl") != 0) &&
|
||||
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rrig") != 0) &&
|
||||
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rpak") != 0))
|
||||
if (fileNameLen < 5 ||
|
||||
(Q_stricmp(&modelName[fileNameLen - 5], ".rmdl") != 0) &&
|
||||
(Q_stricmp(&modelName[fileNameLen - 5], ".rrig") != 0) &&
|
||||
(Q_stricmp(&modelName[fileNameLen - 5], ".rpak") != 0))
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
studioHdr = GetErrorModel();
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load old model \"%s\" and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
|
||||
if (!studioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load old model \"%s\" and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
|
||||
else
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to load old model \"%s\"; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to load old model \"%s\"; replacing with \"%s\".\n", modelName, ERROR_MODEL);
|
||||
}
|
||||
|
||||
return pStudioHdr;
|
||||
return studioHdr;
|
||||
}
|
||||
|
||||
LOBYTE(pStudioData->m_nGuidLock) = 1;
|
||||
g_pRTech->StringToGuid(szModelName);
|
||||
LOBYTE(pStudioData->m_nGuidLock) = 0;
|
||||
pStudioData->processing = true;
|
||||
Pak_StringToGuid(modelName);
|
||||
pStudioData->processing = false;
|
||||
|
||||
if (!pStudioData->m_MDLCache)
|
||||
{
|
||||
studiohdr_t** pAnimData = (studiohdr_t**)pStudioData->m_pAnimData;
|
||||
if (pAnimData)
|
||||
{
|
||||
pStudioHdr = *pAnimData;
|
||||
}
|
||||
else
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
|
||||
else
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" not found; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
|
||||
}
|
||||
studiomodelcache_t* const modelCache = pStudioData->GetModelCache();
|
||||
|
||||
return pStudioHdr;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (IS_VALID_DATACACHE_HANDLE(modelCache))
|
||||
{
|
||||
FindCachedMDL(cache, pStudioData, a4);
|
||||
DataCacheHandle_t dataHandle = pStudioData->m_MDLCache;
|
||||
studioHdr = modelCache->GetStudioHdr();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attempt to get studio header from anim cache.
|
||||
studioanimcache_t* const animCache = pStudioData->GetAnimCache();
|
||||
|
||||
if (dataHandle)
|
||||
if (IS_VALID_DATACACHE_HANDLE(animCache))
|
||||
{
|
||||
if (dataHandle == DC_INVALID_HANDLE)
|
||||
studioHdr = animCache->GetStudioHdr();
|
||||
}
|
||||
else
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
studioHdr = GetErrorModel();
|
||||
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has bad studio data and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
|
||||
if (!studioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
|
||||
else
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has bad studio data; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
|
||||
}
|
||||
}
|
||||
else
|
||||
pStudioHdr = *(studiohdr_t**)dataHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has no studio data and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
|
||||
else
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has no studio data; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" not found; replacing with \"%s\".\n", modelName, ERROR_MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pStudioHdr;
|
||||
assert(studioHdr);
|
||||
return studioHdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the studiohdr from cache pool by handle
|
||||
// Purpose: gets the model cache by handle
|
||||
// Input : handle -
|
||||
// Output : a pointer to the studiomodelcache_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiomodelcache_t* CMDLCache::GetModelCache(const MDLHandle_t handle)
|
||||
{
|
||||
if (handle == MDLHANDLE_INVALID)
|
||||
return nullptr;
|
||||
|
||||
const studiodata_t* const studioData = GetStudioData(handle);
|
||||
|
||||
if (!studioData)
|
||||
return nullptr;
|
||||
|
||||
studiomodelcache_t* const modelCache = studioData->GetModelCache();
|
||||
return modelCache;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the vcollide data from cache pool by handle
|
||||
// Input : *this -
|
||||
// handle -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
// Output : a pointer to the vcollide_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
|
||||
vcollide_t* CMDLCache::GetVCollide(CMDLCache* const cache, const MDLHandle_t handle)
|
||||
{
|
||||
studiohdr_t* pStudioHdr = nullptr; // rax
|
||||
studiomodelcache_t* const modelCache = cache->GetModelCache(handle);
|
||||
|
||||
if (!handle)
|
||||
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load model with no handle and \"%s\" couldn't be loaded.\n", ERROR_MODEL);
|
||||
|
||||
return pStudioHdr;
|
||||
Warning(eDLL_T::ENGINE, "Attempted to load collision data on model \"%s\" with invalid studio data!\n", cache->GetModelName(handle));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
DataCacheHandle_t dataCache = pStudioData->m_MDLCache;
|
||||
studiophysicsref_t* const physicsCache = modelCache->GetPhysicsCache();
|
||||
|
||||
if (dataCache &&
|
||||
dataCache != DC_INVALID_HANDLE)
|
||||
{
|
||||
void* v4 = *(void**)(*((_QWORD*)dataCache + 1) + 24i64);
|
||||
if (v4)
|
||||
pStudioHdr = (studiohdr_t*)((char*)v4 + 0x10);
|
||||
if (!physicsCache)
|
||||
return nullptr;
|
||||
|
||||
CStudioVCollide* const pVCollide = physicsCache->GetStudioVCollide();
|
||||
|
||||
if (!pVCollide)
|
||||
return nullptr;
|
||||
|
||||
return pVCollide->GetVCollide();
|
||||
}
|
||||
return pStudioHdr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the physics geometry data from cache pool by handle
|
||||
// Input : *this -
|
||||
// handle -
|
||||
// Output : a pointer to the physics geometry descriptor
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CMDLCache::GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle)
|
||||
{
|
||||
studiomodelcache_t* const modelCache = cache->GetModelCache(handle);
|
||||
|
||||
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
|
||||
{
|
||||
Warning(eDLL_T::ENGINE, "Attempted to load physics geometry on model \"%s\" with invalid studio data!\n", cache->GetModelName(handle));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
studiophysicsref_t* const physicsRef = modelCache->GetPhysicsCache();
|
||||
|
||||
if (!physicsRef)
|
||||
return nullptr;
|
||||
|
||||
CStudioPhysicsGeoms* const physicsGeoms = physicsRef->GetPhysicsGeoms();
|
||||
|
||||
if (!physicsGeoms)
|
||||
return nullptr;
|
||||
|
||||
return physicsGeoms->GetGeometryData();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -250,52 +273,72 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
|
||||
// handle -
|
||||
// Output : a pointer to the studiohwdata_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
|
||||
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* const cache, const MDLHandle_t handle)
|
||||
{
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
const studiodata_t* studioData = nullptr; cache->GetStudioData(handle);
|
||||
const studiomodelcache_t* modelCache = cache->GetModelCache(handle);
|
||||
|
||||
if (!pStudioData)
|
||||
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
|
||||
{
|
||||
if (!g_pMDLFallback->m_hErrorMDL)
|
||||
if (!HasErrorModel())
|
||||
{
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Studio hardware with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL);
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Studio hardware for model \"%s\" not found and \"%s\" couldn't be loaded!\n",
|
||||
cache->GetModelName(handle), ERROR_MODEL);
|
||||
|
||||
assert(0); // Should never be hit!
|
||||
return nullptr;
|
||||
}
|
||||
pStudioData = cache->GetStudioData(g_pMDLFallback->m_hErrorMDL);
|
||||
else
|
||||
{
|
||||
// Only spew the message once.
|
||||
if (g_StudioMdlFallbackHandler.AddToSuppressionList(handle))
|
||||
{
|
||||
Warning(eDLL_T::ENGINE, "Studio hardware for model \"%s\" not found; replacing with \"%s\".\n",
|
||||
cache->GetModelName(handle), ERROR_MODEL);
|
||||
}
|
||||
}
|
||||
|
||||
DataCacheHandle_t dataCache = pStudioData->m_MDLCache;
|
||||
|
||||
if (dataCache)
|
||||
studioData = cache->GetStudioData(GetErrorModelHandle());
|
||||
modelCache = studioData->GetModelCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataCache == DC_INVALID_HANDLE)
|
||||
return nullptr;
|
||||
studioData = cache->GetStudioData(handle);
|
||||
}
|
||||
|
||||
void* pAnimData = (void*)*((_QWORD*)dataCache + 1);
|
||||
studiophysicsref_t* const physicsRef = modelCache->GetPhysicsCache();
|
||||
|
||||
AcquireSRWLockExclusive(g_pMDLLock);
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
v_CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(pAnimData), 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
||||
#endif
|
||||
CMDLCache__CheckData(physicsRef, 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
||||
ReleaseSRWLockExclusive(g_pMDLLock);
|
||||
}
|
||||
if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
|
||||
return &pStudioData->m_pHardwareRef->m_HardwareData;
|
||||
else
|
||||
|
||||
if ((studioData->flags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
|
||||
return studioData->GetHardwareDataRef()->GetHardwareData();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the error model
|
||||
// Output : *studiohdr_t
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::GetErrorModel(void)
|
||||
{
|
||||
// !TODO [AMOS]: mdl/error.rmdl fallback is not supported (yet) in the new GatherProps solution!
|
||||
if (!old_gather_props->GetBool())
|
||||
old_gather_props->SetValue(true);
|
||||
return g_StudioMdlFallbackHandler.GetFallbackModelHeader();
|
||||
}
|
||||
const char* CMDLCache::GetErrorModelName(void)
|
||||
{
|
||||
const studiohdr_t* const errorStudioHdr = g_StudioMdlFallbackHandler.GetFallbackModelHeader();
|
||||
assert(errorStudioHdr);
|
||||
|
||||
return g_pMDLFallback->m_pErrorHDR;
|
||||
return errorStudioHdr ? errorStudioHdr->name : "(invalid)";
|
||||
}
|
||||
MDLHandle_t CMDLCache::GetErrorModelHandle(void)
|
||||
{
|
||||
return g_StudioMdlFallbackHandler.GetFallbackModelHandle();
|
||||
}
|
||||
bool CMDLCache::HasErrorModel(void)
|
||||
{
|
||||
return g_StudioMdlFallbackHandler.HasFallbackModel();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -303,34 +346,20 @@ studiohdr_t* CMDLCache::GetErrorModel(void)
|
||||
// Input : handle -
|
||||
// Output : true if exist, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMDLCache::IsKnownBadModel(MDLHandle_t handle)
|
||||
bool CMDLCache::IsKnownBadModel(const MDLHandle_t handle)
|
||||
{
|
||||
auto p = g_vBadMDLHandles.insert(handle);
|
||||
return !p.second;
|
||||
// Only adds if it didn't exist yet, else it returns false.
|
||||
return g_StudioMdlFallbackHandler.AddBadModelHandle(handle);
|
||||
}
|
||||
|
||||
void VMDLCache::Attach() const
|
||||
void VMDLCache::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL);
|
||||
#ifdef GAMEDLL_S3 // !!! DECLARED INLINE WITH FINDMDL IN < S3 !!!
|
||||
DetourAttach((LPVOID*)&v_CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL);
|
||||
DetourAttach((LPVOID*)&v_CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL);
|
||||
#endif // GAMEDLL_S3
|
||||
#ifdef GAMEDLL_S3 // !TODO:
|
||||
DetourAttach((LPVOID*)&v_CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData);
|
||||
DetourAttach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR);
|
||||
#endif
|
||||
}
|
||||
DetourSetup(&CMDLCache__FindMDL, &CMDLCache::FindMDL, bAttach);
|
||||
DetourSetup(&CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL, bAttach);
|
||||
DetourSetup(&CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL, bAttach);
|
||||
|
||||
void VMDLCache::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL);
|
||||
#ifdef GAMEDLL_S3 // !!! DECLARED INLINE WITH FINDMDL IN < S3 !!!
|
||||
DetourDetach((LPVOID*)&v_CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL);
|
||||
DetourDetach((LPVOID*)&v_CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL);
|
||||
#endif // GAMEDLL_S3
|
||||
#ifdef GAMEDLL_S3 // !TODO:
|
||||
DetourDetach((LPVOID*)&v_CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData);
|
||||
DetourDetach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR);
|
||||
#endif
|
||||
DetourSetup(&CMDLCache__GetVCollide, &CMDLCache::GetVCollide, bAttach);
|
||||
DetourSetup(&CMDLCache__GetPhysicsGeometry, &CMDLCache::GetPhysicsGeometry, bAttach);
|
||||
|
||||
DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
|
||||
}
|
@ -2,104 +2,254 @@
|
||||
#define MDLCACHE_H
|
||||
#include "tier0/threadtools.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "tier1/refcount.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "public/studio.h"
|
||||
#include "public/vphysics/phyfile.h"
|
||||
#include "vphysics/physics_collide.h"
|
||||
#include "public/rtech/ipakfile.h"
|
||||
|
||||
struct RStaticProp_t
|
||||
class CStudioFallbackHandler
|
||||
{
|
||||
studiohdr_t* m_pStudioHDR{};
|
||||
CStudioHWDataRef* m_pHardWareData{};
|
||||
const char* m_szPropName{};
|
||||
uint8_t m_pUnknown[0x62]{};
|
||||
public:
|
||||
CStudioFallbackHandler(void)
|
||||
: m_pFallbackHDR(nullptr)
|
||||
, m_hFallbackMDL(NULL)
|
||||
{}
|
||||
|
||||
// This must be cleared if 'common.rpak' is getting unloaded, as this pak
|
||||
// contains the default fallback models!!!
|
||||
inline void Clear(void)
|
||||
{
|
||||
m_pFallbackHDR = nullptr;
|
||||
m_hFallbackMDL = NULL;
|
||||
|
||||
m_BadMdlHandles.clear();
|
||||
}
|
||||
|
||||
inline bool HasFallbackModel() const
|
||||
{
|
||||
return !!m_hFallbackMDL;
|
||||
}
|
||||
|
||||
inline void SetFallbackModel(studiohdr_t* const studioHdr, const MDLHandle_t handle)
|
||||
{
|
||||
m_pFallbackHDR = studioHdr;
|
||||
m_hFallbackMDL = handle;
|
||||
}
|
||||
|
||||
inline studiohdr_t* GetFallbackModelHeader() const
|
||||
{
|
||||
return m_pFallbackHDR;
|
||||
}
|
||||
|
||||
inline MDLHandle_t GetFallbackModelHandle() const
|
||||
{
|
||||
return m_hFallbackMDL;
|
||||
}
|
||||
|
||||
inline void EnableLegacyGatherProps()
|
||||
{
|
||||
if (!old_gather_props->GetBool())
|
||||
old_gather_props->SetValue(true);
|
||||
}
|
||||
|
||||
inline void DisableLegacyGatherProps()
|
||||
{
|
||||
if (old_gather_props->GetBool())
|
||||
old_gather_props->SetValue(false);
|
||||
}
|
||||
|
||||
inline bool AddBadModelHandle(const MDLHandle_t handle)
|
||||
{
|
||||
auto p = m_BadMdlHandles.insert(handle);
|
||||
return !p.second;
|
||||
}
|
||||
|
||||
inline void ClearBadModelHandleCache()
|
||||
{
|
||||
m_BadMdlHandles.clear();
|
||||
}
|
||||
|
||||
inline bool HasInvalidModelHandles()
|
||||
{
|
||||
return !m_BadMdlHandles.empty();
|
||||
}
|
||||
|
||||
inline bool AddToSuppressionList(const MDLHandle_t handle)
|
||||
{
|
||||
auto p = m_SuppressedHandles.insert(handle);
|
||||
return p.second;
|
||||
}
|
||||
|
||||
inline void ClearSuppresionList()
|
||||
{
|
||||
m_SuppressedHandles.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
studiohdr_t* m_pFallbackHDR;
|
||||
MDLHandle_t m_hFallbackMDL;
|
||||
|
||||
// Keep track of bad model handles so we don't log the
|
||||
// same one twice or more to the console and cause a
|
||||
// significant performance impact.
|
||||
std::unordered_set<MDLHandle_t> m_BadMdlHandles;
|
||||
|
||||
// Don't spam on these handles when trying to get
|
||||
// cache data.
|
||||
std::unordered_set<MDLHandle_t> m_SuppressedHandles;
|
||||
};
|
||||
|
||||
struct RMDLFallBack_t
|
||||
{
|
||||
studiohdr_t* m_pErrorHDR;
|
||||
studiohdr_t* m_pEmptyHDR;
|
||||
MDLHandle_t m_hErrorMDL;
|
||||
MDLHandle_t m_hEmptyMDL;
|
||||
|
||||
RMDLFallBack_t(void)
|
||||
: m_pErrorHDR(nullptr)
|
||||
, m_pEmptyHDR(nullptr)
|
||||
, m_hErrorMDL(NULL)
|
||||
, m_hEmptyMDL(NULL)
|
||||
struct CStudioVCollide : public CRefCounted<>
|
||||
{
|
||||
public:
|
||||
~CStudioVCollide()
|
||||
{
|
||||
PhysicsCollision()->VCollideUnload(&m_vcollide);
|
||||
}
|
||||
vcollide_t* GetVCollide()
|
||||
{
|
||||
return &m_vcollide;
|
||||
}
|
||||
private:
|
||||
vcollide_t m_vcollide;
|
||||
};
|
||||
|
||||
// This must be cleared if 'common.rpak' is getting unloaded!
|
||||
void Clear(void)
|
||||
class CStudioPhysicsGeoms : public CRefCounted<>
|
||||
{
|
||||
m_pErrorHDR = nullptr;
|
||||
m_pEmptyHDR = nullptr;
|
||||
m_hErrorMDL = NULL;
|
||||
m_hEmptyMDL = NULL;
|
||||
}
|
||||
public:
|
||||
void* GetGeometryData() { return m_pGeomDataDesc; }
|
||||
|
||||
private:
|
||||
// TODO: ptr to another ptr to geometry data; requires reversing.
|
||||
void* m_pGeomDataDesc;
|
||||
int unk2;
|
||||
short unk3;
|
||||
short unk4;
|
||||
};
|
||||
|
||||
struct studiophysicsref_t
|
||||
{
|
||||
inline CStudioVCollide* GetStudioVCollide() const { return vCollide; }
|
||||
inline CStudioPhysicsGeoms* GetPhysicsGeoms() const { return physicsGeoms; }
|
||||
|
||||
int unk0;
|
||||
int unk1;
|
||||
int unk2;
|
||||
int unk3;
|
||||
int unk4;
|
||||
int unk5;
|
||||
CStudioVCollide* vCollide;
|
||||
CStudioPhysicsGeoms* physicsGeoms;
|
||||
};
|
||||
|
||||
struct studiomodelcache_t
|
||||
{
|
||||
inline studiohdr_t* GetStudioHdr() const { return studioHeader; }
|
||||
inline studiophysicsref_t* GetPhysicsCache() const { return physicsCache; }
|
||||
|
||||
studiohdr_t* studioHeader;
|
||||
studiophysicsref_t* physicsCache;
|
||||
const char* modelName;
|
||||
char gap_18[8];
|
||||
phyheader_t* physicsHeader;
|
||||
void* unk_28;
|
||||
void* staticPropData;
|
||||
void* animRigs;
|
||||
int numAnimRigs;
|
||||
int unk_44;
|
||||
int streamedDataSize;
|
||||
char gap_4C[8];
|
||||
int numAnimSeqs;
|
||||
void* m_pAnimSeqs;
|
||||
char gap_60[24];
|
||||
};
|
||||
|
||||
struct studioanimcache_t
|
||||
{
|
||||
inline studiohdr_t* GetStudioHdr() const { return studioHdr; }
|
||||
|
||||
studiohdr_t* studioHdr;
|
||||
const char* rigName;
|
||||
int unk0;
|
||||
int numSequences;
|
||||
PakPage_t sequences;
|
||||
int unk1;
|
||||
int unk2;
|
||||
};
|
||||
|
||||
// only models with type "mod_studio" have this data
|
||||
struct studiodata_t
|
||||
{
|
||||
DataCacheHandle_t m_MDLCache;
|
||||
void* m_pAnimData; // !TODO: reverse struct.
|
||||
unsigned short m_nRefCount;
|
||||
unsigned short m_nFlags;
|
||||
MDLHandle_t m_Handle;
|
||||
#ifndef GAMEDLL_S3
|
||||
void* Unk1; // TODO: unverified!
|
||||
void* Unk2; // TODO: unverified!
|
||||
#endif // !GAMEDLL_S3
|
||||
void* Unk3; // ptr to flags and model string.
|
||||
CStudioHWDataRef* m_pHardwareRef;
|
||||
void* m_pMaterialTable; // contains a large table of CMaterialGlue objects.
|
||||
inline studiomodelcache_t* GetModelCache() const { return modelCache; }
|
||||
inline studioanimcache_t* GetAnimCache() const { return animCache; }
|
||||
inline CStudioHWDataRef* GetHardwareDataRef() const { return hardwareRef; }
|
||||
|
||||
studiomodelcache_t* modelCache;
|
||||
studioanimcache_t* animCache;
|
||||
unsigned short refCount;
|
||||
unsigned short flags;
|
||||
MDLHandle_t modelHandle;
|
||||
void* unkStruct; // TODO: reverse structure
|
||||
CStudioHWDataRef* hardwareRef;
|
||||
void* materialTable; // contains a large table of CMaterialGlue objects.
|
||||
int Unk5;
|
||||
char pad[72];
|
||||
CThreadFastMutex m_Mutex;
|
||||
int m_nGuidLock; // always -1, set to 1 and 0 in CMDLCache::FindUncachedMDL.
|
||||
CThreadFastMutex mutex;
|
||||
bool processing;
|
||||
PakHandle_t pakHandle;
|
||||
};
|
||||
|
||||
extern RMDLFallBack_t* g_pMDLFallback;
|
||||
extern std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
extern CStudioFallbackHandler g_StudioMdlFallbackHandler;
|
||||
|
||||
class CMDLCache : public IMDLCache
|
||||
class CMDLCache : public CTier1AppSystem<IMDLCache>
|
||||
{
|
||||
public:
|
||||
static studiohdr_t* FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3);
|
||||
static void FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3);
|
||||
static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
|
||||
static studiohdr_t* GetStudioHDR(CMDLCache* cache, MDLHandle_t handle);
|
||||
static studiohwdata_t* GetHardwareData(CMDLCache* cache, MDLHandle_t handle);
|
||||
static studiohdr_t* FindMDL(CMDLCache* const cache, const MDLHandle_t handle, void* a3);
|
||||
static void FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudioData, void* a3);
|
||||
static studiohdr_t* FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* const pStudioData, void* a4);
|
||||
|
||||
studiomodelcache_t* GetModelCache(const MDLHandle_t handle);
|
||||
static vcollide_t* GetVCollide(CMDLCache* const cache, const MDLHandle_t handle);
|
||||
static void* GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle);
|
||||
|
||||
static studiohwdata_t* GetHardwareData(CMDLCache* const cache, const MDLHandle_t handle);
|
||||
|
||||
static studiohdr_t* GetErrorModel(void);
|
||||
static bool IsKnownBadModel(MDLHandle_t handle);
|
||||
static const char* GetErrorModelName(void);
|
||||
static MDLHandle_t GetErrorModelHandle(void);
|
||||
static bool HasErrorModel(void);
|
||||
static bool IsKnownBadModel(const MDLHandle_t handle);
|
||||
|
||||
|
||||
studiodata_t* GetStudioData(MDLHandle_t handle)
|
||||
inline studiodata_t* GetStudioData(const MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(&m_MDLMutex);
|
||||
studiodata_t* pStudioData = m_MDLDict.Element(handle);
|
||||
studiodata_t* const studioData = m_MDLDict.Element(handle);
|
||||
LeaveCriticalSection(&m_MDLMutex);
|
||||
|
||||
return pStudioData;
|
||||
return studioData;
|
||||
}
|
||||
|
||||
const char* GetModelName(MDLHandle_t handle)
|
||||
inline const char* GetModelName(const MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(&m_MDLMutex);
|
||||
const char* szModelName = m_MDLDict.GetElementName(handle);
|
||||
const char* const modelName = m_MDLDict.GetElementName(handle);
|
||||
LeaveCriticalSection(&m_MDLMutex);
|
||||
|
||||
return szModelName;
|
||||
return modelName;
|
||||
}
|
||||
|
||||
void* GetMaterialTable(MDLHandle_t handle)
|
||||
inline void* GetMaterialTable(const MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(&m_MDLMutex);
|
||||
studiodata_t* pStudioData = m_MDLDict.Element(handle);
|
||||
studiodata_t* const studioData = m_MDLDict.Element(handle);
|
||||
LeaveCriticalSection(&m_MDLMutex);
|
||||
|
||||
return &pStudioData->m_pMaterialTable;
|
||||
return &studioData->materialTable;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -108,24 +258,16 @@ private:
|
||||
// !TODO: reverse the rest
|
||||
};
|
||||
|
||||
inline CMemory p_CMDLCache__FindMDL;
|
||||
inline studiohdr_t*(*v_CMDLCache__FindMDL)(CMDLCache* pCache, void* a2, void* a3);
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
inline CMemory p_CMDLCache__FindCachedMDL;
|
||||
inline void(*v_CMDLCache__FindCachedMDL)(CMDLCache* pCache, void* a2, void* a3);
|
||||
inline studiohdr_t*(*CMDLCache__FindMDL)(CMDLCache* const pCache, const MDLHandle_t handle, void* a3);
|
||||
inline void(*CMDLCache__FindCachedMDL)(CMDLCache* const pCache, studiodata_t* const pStudioData, void* a3);
|
||||
inline studiohdr_t*(*CMDLCache__FindUncachedMDL)(CMDLCache* const pCache, MDLHandle_t handle, studiodata_t* const pStudioData, void* a4);
|
||||
|
||||
inline CMemory p_CMDLCache__FindUncachedMDL;
|
||||
inline studiohdr_t*(*v_CMDLCache__FindUncachedMDL)(CMDLCache* pCache, MDLHandle_t handle, void* a3, void* a4);
|
||||
#endif
|
||||
inline CMemory p_CMDLCache__GetStudioHDR;
|
||||
inline studiohdr_t*(*v_CMDLCache__GetStudioHDR)(CMDLCache* pCache, MDLHandle_t handle);
|
||||
inline vcollide_t*(*CMDLCache__GetVCollide)(CMDLCache* const pCache, const MDLHandle_t handle);
|
||||
inline void* (*CMDLCache__GetPhysicsGeometry)(CMDLCache* const pCache, const MDLHandle_t handle);
|
||||
|
||||
inline studiohwdata_t* (*CMDLCache__GetHardwareData)(CMDLCache* const pCache, const MDLHandle_t handle);
|
||||
inline bool(*CMDLCache__CheckData)(void* const ref, const int64_t type); // Probably incorrect name.
|
||||
|
||||
inline CMemory p_CMDLCache__GetHardwareData;
|
||||
inline studiohwdata_t*(*v_CMDLCache__GetHardwareData)(CMDLCache* pCache, MDLHandle_t handle);
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
inline CMemory p_CStudioHWDataRef__SetFlags; // Probably incorrect.
|
||||
inline bool(*v_CStudioHWDataRef__SetFlags)(CStudioHWDataRef* ref, int64_t flags);
|
||||
#endif
|
||||
inline CMDLCache* g_pMDLCache = nullptr;
|
||||
inline PSRWLOCK g_pMDLLock = nullptr; // Possibly a member? research required.
|
||||
|
||||
@ -134,54 +276,26 @@ class VMDLCache : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CMDLCache::FindMDL", p_CMDLCache__FindMDL.GetPtr());
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
LogFunAdr("CMDLCache::FindCachedMDL", p_CMDLCache__FindCachedMDL.GetPtr());
|
||||
LogFunAdr("CMDLCache::FindUncachedMDL", p_CMDLCache__FindUncachedMDL.GetPtr());
|
||||
#endif
|
||||
LogFunAdr("CMDLCache::GetStudioHDR", p_CMDLCache__GetStudioHDR.GetPtr());
|
||||
LogFunAdr("CMDLCache::GetHardwareData", p_CMDLCache__GetHardwareData.GetPtr());
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
LogFunAdr("CStudioHWDataRef::SetFlags", p_CStudioHWDataRef__SetFlags.GetPtr());
|
||||
#endif
|
||||
LogVarAdr("g_MDLCache", reinterpret_cast<uintptr_t>(g_pMDLCache));
|
||||
LogVarAdr("g_MDLLock", reinterpret_cast<uintptr_t>(g_pMDLLock));
|
||||
LogFunAdr("CMDLCache::FindMDL", CMDLCache__FindMDL);
|
||||
LogFunAdr("CMDLCache::FindCachedMDL", CMDLCache__FindCachedMDL);
|
||||
LogFunAdr("CMDLCache::FindUncachedMDL", CMDLCache__FindUncachedMDL);
|
||||
LogFunAdr("CMDLCache::GetVCollide", CMDLCache__GetVCollide);
|
||||
LogFunAdr("CMDLCache::GetPhysicsGeometry", CMDLCache__GetPhysicsGeometry);
|
||||
LogFunAdr("CMDLCache::GetHardwareData", CMDLCache__GetHardwareData);
|
||||
LogFunAdr("CMDLCache::CheckData", CMDLCache__CheckData);
|
||||
|
||||
LogVarAdr("g_MDLCache", g_pMDLCache);
|
||||
LogVarAdr("g_MDLLock", g_pMDLLock);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
p_CMDLCache__FindMDL = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 4C 8B F1 0F B7 DA");
|
||||
v_CMDLCache__FindMDL = p_CMDLCache__FindMDL.RCast<studiohdr_t* (*)(CMDLCache*, void*, void*)>(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC 20 4C 8B F1 0F B7 DA*/
|
||||
|
||||
p_CMDLCache__GetStudioHDR = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 0F B7 FA 48 8D 0D ?? ?? ?? ??");
|
||||
v_CMDLCache__GetStudioHDR = p_CMDLCache__GetStudioHDR.RCast<studiohdr_t* (*)(CMDLCache*, MDLHandle_t)>(); /*48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B F1 0F B7 FA 48 8D 0D ? ? ? ?*/
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CMDLCache__GetHardwareData = g_GameDll.FindPatternSIMD("40 56 48 83 EC 20 48 89 5C 24 ?? 48 8D 0D ?? ?? ?? ??");
|
||||
v_CMDLCache__GetHardwareData = p_CMDLCache__GetHardwareData.RCast<studiohwdata_t* (*)(CMDLCache*, MDLHandle_t)>(); /*40 56 48 83 EC 20 48 89 5C 24 ? 48 8D 0D ? ? ? ?*/
|
||||
#else
|
||||
p_CMDLCache__GetHardwareData = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 7C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 1F");
|
||||
v_CMDLCache__GetHardwareData = p_CMDLCache__GetHardwareData.RCast<studiohwdata_t* (*)(CMDLCache*, MDLHandle_t)>(); /*48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 0F B7 DA FF 15 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 14 5B 48 8D 0D ? ? ? ? 48 8B 7C D0 ? FF 15 ? ? ? ? 48 8B 1F*/
|
||||
#endif
|
||||
#else
|
||||
p_CMDLCache__FindMDL = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 0F B7 EA");
|
||||
v_CMDLCache__FindMDL = p_CMDLCache__FindMDL.RCast<studiohdr_t* (*)(CMDLCache*, void*, void*)>(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B F1 0F B7 EA*/
|
||||
|
||||
p_CMDLCache__FindCachedMDL = g_GameDll.FindPatternSIMD("4D 85 C0 74 7A 48 89 6C 24 ??");
|
||||
v_CMDLCache__FindCachedMDL = p_CMDLCache__FindCachedMDL.RCast<void(*)(CMDLCache*, void*, void*)>(); /*4D 85 C0 74 7A 48 89 6C 24 ?*/
|
||||
|
||||
p_CMDLCache__FindUncachedMDL = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B E9 0F B7 FA");
|
||||
v_CMDLCache__FindUncachedMDL = p_CMDLCache__FindUncachedMDL.RCast<studiohdr_t* (*)(CMDLCache*, MDLHandle_t, void*, void*)>(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC 20 48 8B E9 0F B7 FA*/
|
||||
|
||||
p_CMDLCache__GetStudioHDR = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08");
|
||||
v_CMDLCache__GetStudioHDR = p_CMDLCache__GetStudioHDR.RCast<studiohdr_t* (*)(CMDLCache*, MDLHandle_t)>(); /*40 53 48 83 EC 20 48 8D 0D ? ? ? ? 0F B7 DA FF 15 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 14 5B 48 8D 0D ? ? ? ? 48 8B 5C D0 ? FF 15 ? ? ? ? 48 8B 03 48 8B 48 08*/
|
||||
|
||||
p_CMDLCache__GetHardwareData = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 7C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 1F");
|
||||
v_CMDLCache__GetHardwareData = p_CMDLCache__GetHardwareData.RCast<studiohwdata_t* (*)(CMDLCache*, MDLHandle_t)>(); /*48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 0F B7 DA FF 15 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 14 5B 48 8D 0D ? ? ? ? 48 8B 7C D0 ? FF 15 ? ? ? ? 48 8B 1F*/
|
||||
|
||||
p_CStudioHWDataRef__SetFlags = g_GameDll.FindPatternSIMD("48 83 EC 08 4C 8D 14 12");
|
||||
v_CStudioHWDataRef__SetFlags = p_CStudioHWDataRef__SetFlags.RCast<bool (*)(CStudioHWDataRef*, int64_t)>(); /*48 83 EC 08 4C 8D 14 12*/
|
||||
#endif
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 0F B7 EA").GetPtr(CMDLCache__FindMDL);
|
||||
g_GameDll.FindPatternSIMD("4D 85 C0 74 7A 48 89 6C 24 ??").GetPtr(CMDLCache__FindCachedMDL);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B E9 0F B7 FA").GetPtr(CMDLCache__FindUncachedMDL);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 7C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 1F").GetPtr(CMDLCache__GetHardwareData);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetVCollide);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 B8 ?? ?? ?? ?? 0F B7 DA").GetPtr(CMDLCache__GetPhysicsGeometry);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 08 4C 8D 14 12").GetPtr(CMDLCache__CheckData);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
@ -189,11 +303,10 @@ class VMDLCache : public IDetour
|
||||
g_pMDLCache = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? 48 85 C0 48 0F 45 C8 FF 05 ?? ?? ?? ?? 48 83 3D ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ??")
|
||||
.FindPatternSelf("48 8D 05").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CMDLCache*>();
|
||||
|
||||
g_pMDLLock = p_CMDLCache__GetHardwareData.Offset(0x35).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<PSRWLOCK>();
|
||||
g_pMDLLock = CMemory(CMDLCache__GetHardwareData).Offset(0x35).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<PSRWLOCK>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1,12 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
inline CMemory p_EbisuSDK_Tier0_Init;
|
||||
inline void(*EbisuSDK_Tier0_Init)(void);
|
||||
|
||||
inline CMemory p_EbisuSDK_CVar_Init;
|
||||
inline void(*EbisuSDK_CVar_Init)(void);
|
||||
|
||||
inline CMemory p_EbisuSDK_SetState;
|
||||
inline void(*EbisuSDK_SetState)(void);
|
||||
|
||||
inline uint64_t* g_NucleusID = nullptr;
|
||||
@ -26,42 +21,32 @@ class VEbisuSDK : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("EbisuSDK_Tier0_Init", p_EbisuSDK_Tier0_Init.GetPtr());
|
||||
LogFunAdr("EbisuSDK_CVar_Init", p_EbisuSDK_CVar_Init.GetPtr());
|
||||
LogFunAdr("EbisuSDK_SetState", p_EbisuSDK_SetState.GetPtr());
|
||||
LogVarAdr("g_NucleusID", reinterpret_cast<uintptr_t>(g_NucleusID));
|
||||
LogVarAdr("g_NucleusToken", reinterpret_cast<uintptr_t>(g_NucleusToken));
|
||||
LogVarAdr("g_OriginAuthCode", reinterpret_cast<uintptr_t>(g_OriginAuthCode));
|
||||
LogVarAdr("g_OriginErrorLevel", reinterpret_cast<uintptr_t>(g_OriginErrorLevel));
|
||||
LogVarAdr("g_EbisuProfileInit", reinterpret_cast<uintptr_t>(g_EbisuProfileInit));
|
||||
LogVarAdr("g_EbisuSDKInit", reinterpret_cast<uintptr_t>(g_EbisuSDKInit));
|
||||
LogFunAdr("EbisuSDK_Tier0_Init", EbisuSDK_Tier0_Init);
|
||||
LogFunAdr("EbisuSDK_CVar_Init", EbisuSDK_CVar_Init);
|
||||
LogFunAdr("EbisuSDK_SetState", EbisuSDK_SetState);
|
||||
LogVarAdr("g_NucleusID", g_NucleusID);
|
||||
LogVarAdr("g_NucleusToken", g_NucleusToken);
|
||||
LogVarAdr("g_OriginAuthCode", g_OriginAuthCode);
|
||||
LogVarAdr("g_OriginErrorLevel", g_OriginErrorLevel);
|
||||
LogVarAdr("g_EbisuProfileInit", g_EbisuProfileInit);
|
||||
LogVarAdr("g_EbisuSDKInit", g_EbisuSDKInit);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_EbisuSDK_Tier0_Init = g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 0F 85 ?? 02 ?? ?? 48 89 5C 24 20");
|
||||
EbisuSDK_Tier0_Init = p_EbisuSDK_Tier0_Init.RCast<void(*)(void)>(); /*48 83 EC 28 80 3D ?? ?? ?? ?? 00 0F 85 ?? 02 00 00 48 89 5C 24 20*/
|
||||
|
||||
p_EbisuSDK_CVar_Init = g_GameDll.FindPatternSIMD("40 57 48 83 EC 40 83 3D");
|
||||
EbisuSDK_CVar_Init = p_EbisuSDK_CVar_Init.RCast<void(*)(void)>(); /*40 57 48 83 EC 40 83 3D*/
|
||||
|
||||
p_EbisuSDK_SetState = g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B");
|
||||
EbisuSDK_SetState = p_EbisuSDK_SetState.RCast<void(*)(void)>(); /*48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B*/
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 0F 85 ?? 02 ?? ?? 48 89 5C 24 20").GetPtr(EbisuSDK_Tier0_Init);
|
||||
g_GameDll.FindPatternSIMD("40 57 48 83 EC 40 83 3D").GetPtr(EbisuSDK_CVar_Init);
|
||||
g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B").GetPtr(EbisuSDK_SetState);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_NucleusID = p_EbisuSDK_CVar_Init.Offset(0x20).FindPatternSelf("4C 89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<uint64_t*>();
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
g_NucleusToken = p_EbisuSDK_SetState.Offset(0x1EF).FindPatternSelf("38 1D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<char*>(); // !TODO: TEST!
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
g_NucleusToken = p_EbisuSDK_SetState.Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<char*>();
|
||||
#endif
|
||||
g_OriginAuthCode = p_EbisuSDK_SetState.Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>();
|
||||
g_OriginErrorLevel = p_EbisuSDK_SetState.Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
g_EbisuProfileInit = p_EbisuSDK_CVar_Init.Offset(0x12A).FindPatternSelf("C6 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
g_EbisuSDKInit = p_EbisuSDK_Tier0_Init.Offset(0x0).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
g_NucleusID = CMemory(EbisuSDK_CVar_Init).Offset(0x20).FindPatternSelf("4C 89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<uint64_t*>();
|
||||
g_NucleusToken = CMemory(EbisuSDK_SetState).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<char*>();
|
||||
g_OriginAuthCode = CMemory(EbisuSDK_SetState).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>();
|
||||
g_OriginErrorLevel = CMemory(EbisuSDK_SetState).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
g_EbisuProfileInit = CMemory(EbisuSDK_CVar_Init).Offset(0x12A).FindPatternSelf("C6 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
g_EbisuSDKInit = CMemory(EbisuSDK_Tier0_Init).Offset(0x0).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -26,7 +26,16 @@ add_sources( SOURCE_GROUP "Debug"
|
||||
"debugoverlay.h"
|
||||
)
|
||||
|
||||
add_sources( SOURCE_GROUP "Input"
|
||||
"keys.cpp"
|
||||
"keys.h"
|
||||
)
|
||||
|
||||
add_sources( SOURCE_GROUP "Render"
|
||||
"framelimit.cpp"
|
||||
"framelimit.h"
|
||||
"gl_drawlights.cpp"
|
||||
"gl_drawlights.h"
|
||||
"gl_matsysiface.h"
|
||||
"gl_model_private.h"
|
||||
"gl_rmain.cpp"
|
||||
@ -127,6 +136,8 @@ add_sources( SOURCE_GROUP "Shared"
|
||||
"shared/base_rcon.h"
|
||||
"shared/shared_rcon.cpp"
|
||||
"shared/shared_rcon.h"
|
||||
"shared/datablock.cpp"
|
||||
"shared/datablock.h"
|
||||
)
|
||||
|
||||
if( NOT ${PROJECT_NAME} STREQUAL "engine_ds" )
|
||||
@ -150,6 +161,11 @@ add_sources( SOURCE_GROUP "GameUI"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IBrowser.h"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IConsole.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/IConsole.h"
|
||||
|
||||
"${ENGINE_SOURCE_DIR}/gameui/imgui_system.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/imgui_system.h"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/imgui_surface.cpp"
|
||||
"${ENGINE_SOURCE_DIR}/gameui/imgui_surface.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -185,6 +201,7 @@ add_sources( SOURCE_GROUP "Common"
|
||||
"${ENGINE_SOURCE_DIR}/common/qlimits.h"
|
||||
"${ENGINE_SOURCE_DIR}/common/sdkdefs.h"
|
||||
"${ENGINE_SOURCE_DIR}/common/x86defs.h"
|
||||
"${ENGINE_SOURCE_DIR}/common/xbox/xboxstubs.h"
|
||||
)
|
||||
|
||||
file( GLOB ENGINE_PUBLIC_HEADERS
|
||||
@ -197,10 +214,8 @@ add_sources( SOURCE_GROUP "Public"
|
||||
"${ENGINE_SOURCE_DIR}/public/dt_send.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/dt_recv.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/datamap.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/idatablock.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/idebugoverlay.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/iengine.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/igame.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/iserver.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/isnapshotmgr.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/inetchannel.h"
|
||||
@ -220,7 +235,6 @@ if( NOT ${PROJECT_NAME} STREQUAL "engine_ds" )
|
||||
add_sources( SOURCE_GROUP "Public"
|
||||
"${ENGINE_SOURCE_DIR}/public/client_class.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/ivrenderview.h"
|
||||
"${ENGINE_SOURCE_DIR}/public/isurfacesystem.h" # ImGui surface
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -236,6 +250,11 @@ target_compile_definitions( ${PROJECT_NAME} PRIVATE
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories( ${PROJECT_NAME} PRIVATE
|
||||
"${THIRDPARTY_SOURCE_DIR}/recast/"
|
||||
"${THIRDPARTY_SOURCE_DIR}/mbedtls/include"
|
||||
)
|
||||
|
||||
endmacro()
|
||||
|
||||
add_engine_project( "engine" )
|
||||
|
@ -10,18 +10,78 @@
|
||||
#include "engine/net_chan.h"
|
||||
#include "engine/client/cl_rcon.h"
|
||||
#include "networksystem/bansystem.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "geforce/reflex.h"
|
||||
#include "vengineclient_impl.h"
|
||||
#include "cdll_engine_int.h"
|
||||
#ifndef DEDICATED
|
||||
#include "materialsystem/cmaterialsystem.h"
|
||||
#endif // !DEDICATED
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef DEDICATED
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: pre frame stage notify hook
|
||||
//-----------------------------------------------------------------------------
|
||||
void FrameStageNotify_Pre(const ClientFrameStage_t frameStage)
|
||||
{
|
||||
switch (frameStage)
|
||||
{
|
||||
case ClientFrameStage_t::FRAME_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_END:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_RENDER_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_RENDER_END:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: post frame stage notify hook
|
||||
//-----------------------------------------------------------------------------
|
||||
void FrameStageNotify_Post(const ClientFrameStage_t frameStage)
|
||||
{
|
||||
switch (frameStage)
|
||||
{
|
||||
case ClientFrameStage_t::FRAME_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_UPDATE_END:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_RENDER_START:
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_RENDER_END:
|
||||
GFX_SetLatencyMarker(D3D11Device(), SIMULATION_END, MaterialSystem()->GetCurrentFrameCount());
|
||||
break;
|
||||
case ClientFrameStage_t::FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHLClient::FrameStageNotify(CHLClient* pHLClient, ClientFrameStage_t frameStage)
|
||||
{
|
||||
CHLClient_FrameStageNotify(pHLClient, frameStage);
|
||||
FrameStageNotify_Pre(frameStage);
|
||||
CHLClient__FrameStageNotify(pHLClient, frameStage);
|
||||
FrameStageNotify_Post(frameStage);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -31,21 +91,14 @@ void CHLClient::FrameStageNotify(CHLClient* pHLClient, ClientFrameStage_t frameS
|
||||
//-----------------------------------------------------------------------------
|
||||
ClientClass* CHLClient::GetAllClasses()
|
||||
{
|
||||
return CHLClient_GetAllClasses();
|
||||
return CHLClient__GetAllClasses();
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VDll_Engine_Int::Attach() const
|
||||
void VDll_Engine_Int::Detour(const bool bAttach) const
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
DetourAttach((LPVOID*)&CHLClient_FrameStageNotify, &CHLClient::FrameStageNotify);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
void VDll_Engine_Int::Detach() const
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
DetourDetach((LPVOID*)&CHLClient_FrameStageNotify, &CHLClient::FrameStageNotify);
|
||||
DetourSetup(&CHLClient__FrameStageNotify, &CHLClient::FrameStageNotify, bAttach);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ enum class ClientFrameStage_t : int
|
||||
FRAME_UNDEFINED = -1, // (haven't run any frames yet)
|
||||
FRAME_START,
|
||||
|
||||
// A network packet is being recieved
|
||||
// A network packet is being received
|
||||
FRAME_NET_UPDATE_START,
|
||||
// Data has been received and we're going to start calling PostDataUpdate
|
||||
FRAME_NET_UPDATE_POSTDATAUPDATE_START,
|
||||
@ -51,20 +51,11 @@ public:
|
||||
|
||||
/* ==== CHLCLIENT ======================================================================================================================================================= */
|
||||
#ifndef DEDICATED
|
||||
inline CMemory p_CHLClient_PostInit;
|
||||
inline void*(*CHLClient_PostInit)(void);
|
||||
|
||||
inline CMemory p_CHLClient_LevelShutdown;
|
||||
inline void*(*CHLClient_LevelShutdown)(CHLClient* thisptr);
|
||||
|
||||
inline CMemory p_CHLClient_HudProcessInput;
|
||||
inline void(*CHLClient_HudProcessInput)(CHLClient* thisptr, bool bActive);
|
||||
|
||||
inline CMemory p_CHLClient_FrameStageNotify;
|
||||
inline void(*CHLClient_FrameStageNotify)(CHLClient* thisptr, ClientFrameStage_t frameStage);
|
||||
|
||||
inline CMemory p_CHLClient_GetAllClasses;
|
||||
inline ClientClass*(*CHLClient_GetAllClasses)();
|
||||
inline void*(*CHLClient__PostInit)(void);
|
||||
inline void*(*CHLClient__LevelShutdown)(CHLClient* thisptr);
|
||||
inline void(*CHLClient__HudProcessInput)(CHLClient* thisptr, bool bActive);
|
||||
inline void(*CHLClient__FrameStageNotify)(CHLClient* thisptr, ClientFrameStage_t frameStage);
|
||||
inline ClientClass*(*CHLClient__GetAllClasses)();
|
||||
#endif // !DEDICATED
|
||||
|
||||
inline CHLClient* g_pHLClient = nullptr;
|
||||
@ -76,39 +67,25 @@ class VDll_Engine_Int : public IDetour
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
LogFunAdr("CHLClient::PostInit", p_CHLClient_PostInit.GetPtr());
|
||||
LogFunAdr("CHLClient::LevelShutdown", p_CHLClient_LevelShutdown.GetPtr());
|
||||
LogFunAdr("CHLClient::HudProcessInput", p_CHLClient_HudProcessInput.GetPtr());
|
||||
LogFunAdr("CHLClient::FrameStageNotify", p_CHLClient_FrameStageNotify.GetPtr());
|
||||
LogFunAdr("CHLClient::GetAllClasses", p_CHLClient_GetAllClasses.GetPtr());
|
||||
LogFunAdr("CHLClient::PostInit", CHLClient__PostInit);
|
||||
LogFunAdr("CHLClient::LevelShutdown", CHLClient__LevelShutdown);
|
||||
LogFunAdr("CHLClient::HudProcessInput", CHLClient__HudProcessInput);
|
||||
LogFunAdr("CHLClient::FrameStageNotify", CHLClient__FrameStageNotify);
|
||||
LogFunAdr("CHLClient::GetAllClasses", CHLClient__GetAllClasses);
|
||||
#endif // !DEDICATED
|
||||
LogVarAdr("g_HLClient", reinterpret_cast<uintptr_t>(g_pHLClient));
|
||||
LogVarAdr("g_pHLClient", reinterpret_cast<uintptr_t>(g_ppHLClient));
|
||||
LogVarAdr("g_HLClient", g_pHLClient);
|
||||
LogVarAdr("g_pHLClient", g_ppHLClient);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CHLClient_LevelShutdown = g_GameDll.FindPatternSIMD("40 53 56 41 54 41 56 48 83 EC 28 48 8B F1");
|
||||
#ifndef DEDICATED
|
||||
p_CHLClient_PostInit = g_GameDll.FindPatternSIMD("48 83 3D ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ??");
|
||||
p_CHLClient_FrameStageNotify = g_GameDll.FindPatternSIMD("48 83 EC 38 89 15 ?? ?? ?? ??");
|
||||
p_CHLClient_GetAllClasses = g_GameDll.FindPatternSIMD("48 8B 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 89 74 24 ??");
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 48 8D 0D ?? ?? ?? ??").GetPtr(CHLClient__LevelShutdown);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 48 83 3D ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ??").GetPtr(CHLClient__PostInit);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr(CHLClient__FrameStageNotify);
|
||||
g_GameDll.FindPatternSIMD("48 8B 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ??").GetPtr(CHLClient__GetAllClasses);
|
||||
#endif // !DEDICATED
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
#ifndef DEDICATED
|
||||
p_CHLClient_LevelShutdown = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 48 8D 0D ?? ?? ?? ??");
|
||||
p_CHLClient_PostInit = g_GameDll.FindPatternSIMD("48 83 EC 28 48 83 3D ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ??");
|
||||
p_CHLClient_FrameStageNotify = g_GameDll.FindPatternSIMD("48 83 EC 28 89 15 ?? ?? ?? ??");
|
||||
p_CHLClient_GetAllClasses = g_GameDll.FindPatternSIMD("48 8B 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ??");
|
||||
#endif // !DEDICATED
|
||||
#endif
|
||||
#ifndef DEDICATED
|
||||
p_CHLClient_HudProcessInput = g_GameDll.FindPatternSIMD("48 83 EC 28 0F B6 0D ?? ?? ?? ?? 88 15 ?? ?? ?? ??");
|
||||
CHLClient_LevelShutdown = p_CHLClient_LevelShutdown.RCast<void*(*)(CHLClient*)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 48 8D 0D ?? ?? ?? ??*/
|
||||
CHLClient_PostInit = p_CHLClient_PostInit.RCast<void*(*)(void)>(); /*48 83 EC 28 48 83 3D ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ??*/
|
||||
CHLClient_FrameStageNotify = p_CHLClient_FrameStageNotify.RCast<void(*)(CHLClient*, ClientFrameStage_t)>(); /*48 83 EC 28 89 15 ?? ?? ?? ??*/
|
||||
CHLClient_HudProcessInput = p_CHLClient_HudProcessInput.RCast<void(*)(CHLClient*, bool)>(); /*48 83 EC 28 0F B6 0D ?? ?? ?? ?? 88 15 ?? ?? ?? ??*/
|
||||
CHLClient_GetAllClasses = p_CHLClient_GetAllClasses.RCast<ClientClass*(*)()>(); /*48 8B 05 ? ? ? ? C3 CC CC CC CC CC CC CC CC 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ?*/
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 0F B6 0D ?? ?? ?? ?? 88 15 ?? ?? ?? ??").GetPtr(CHLClient__HudProcessInput);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
@ -120,7 +97,6 @@ class VDll_Engine_Int : public IDetour
|
||||
.FindPatternSelf("4C 8B", CMemory::Direction::DOWN, 512, 2).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CHLClient**>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef CL_ENTS_PARSE_H
|
||||
#define CL_ENTS_PARSE_H
|
||||
|
||||
inline CMemory p_CL_CopyExistingEntity;
|
||||
inline bool(*v_CL_CopyExistingEntity)(__int64 a1, unsigned int* a2, char* a3);
|
||||
|
||||
bool CL_CopyExistingEntity(__int64 a1, unsigned int* a2, char* a3);
|
||||
@ -10,22 +9,17 @@ class V_CL_Ents_Parse : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CL_CopyExistingEntity", p_CL_CopyExistingEntity.GetPtr());
|
||||
LogFunAdr("CL_CopyExistingEntity", v_CL_CopyExistingEntity);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_CL_CopyExistingEntity = g_GameDll.FindPatternSIMD("40 53 48 83 EC 70 4C 63 51 28");
|
||||
v_CL_CopyExistingEntity = p_CL_CopyExistingEntity.RCast<bool (*)(__int64, unsigned int*, char*)>(); /*40 53 48 83 EC 70 4C 63 51 28*/
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 70 4C 63 51 28").GetPtr(v_CL_CopyExistingEntity);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const
|
||||
virtual void Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_CL_CopyExistingEntity, &CL_CopyExistingEntity);
|
||||
}
|
||||
virtual void Detach(void) const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_CL_CopyExistingEntity, &CL_CopyExistingEntity);
|
||||
DetourSetup(&v_CL_CopyExistingEntity, &CL_CopyExistingEntity, bAttach);
|
||||
}
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "cl_main.h"
|
||||
#include "engine/net.h"
|
||||
#include "cdll_engine_int.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "geforce/reflex.h"
|
||||
|
||||
static float s_lastMovementCall = 0.0;
|
||||
static float s_LastFrameTime = 0.0;
|
||||
@ -17,9 +19,9 @@ static float s_LastFrameTime = 0.0;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: run client's movement frame
|
||||
//-----------------------------------------------------------------------------
|
||||
void H_CL_Move()
|
||||
void CL_MoveEx()
|
||||
{
|
||||
CClientState* cl = GetBaseLocalClient();
|
||||
CClientState* const cl = GetBaseLocalClient();
|
||||
|
||||
if (!cl->IsConnected())
|
||||
return;
|
||||
@ -40,15 +42,15 @@ void H_CL_Move()
|
||||
const float hostTimeScale = host_timescale->GetFloat();
|
||||
const bool isTimeScaleDefault = hostTimeScale == 1.0;
|
||||
|
||||
const float minFrameTime = usercmd_frametime_min->GetFloat();
|
||||
const float maxFrameTime = usercmd_frametime_max->GetFloat();
|
||||
const float minFrameTime = usercmd_frametime_min.GetFloat();
|
||||
const float maxFrameTime = usercmd_frametime_max.GetFloat();
|
||||
|
||||
const float netTime = float(*g_pNetTime);
|
||||
|
||||
if (cl->m_flNextCmdTime <= (maxFrameTime * 0.5f) + netTime)
|
||||
sendPacket = chan->CanPacket();
|
||||
|
||||
else if (cl->m_nOutgoingCommandNr - (commandTick+1) < MAX_BACKUP_COMMANDS || isTimeScaleDefault)
|
||||
else if (cl->m_nOutgoingCommandNr - (commandTick+1) < MAX_NEW_COMMANDS || isTimeScaleDefault)
|
||||
sendPacket = false;
|
||||
|
||||
const bool isActive = cl->IsActive();
|
||||
@ -68,8 +70,6 @@ void H_CL_Move()
|
||||
|
||||
float frameTime = 0.0f;
|
||||
|
||||
if (cl_move_use_dt->GetBool())
|
||||
{
|
||||
float timeScale;
|
||||
float deltaTime;
|
||||
|
||||
@ -102,19 +102,16 @@ void H_CL_Move()
|
||||
}
|
||||
|
||||
s_LastFrameTime = 0.0;
|
||||
}
|
||||
//else if (isPaused)
|
||||
// // This hlClient virtual call just returns false.
|
||||
|
||||
// Create and store usercmd structure.
|
||||
g_pHLClient->CreateMove(nextCommandNr, frameTime, !isPaused);
|
||||
cl->m_nOutgoingCommandNr = nextCommandNr;
|
||||
}
|
||||
|
||||
CL_RunPrediction();
|
||||
v_CL_RunPrediction();
|
||||
|
||||
if (sendPacket)
|
||||
CL_SendMove();
|
||||
v_CL_SendMove();
|
||||
else
|
||||
chan->SetChoked(); // Choke the packet...
|
||||
|
||||
@ -132,19 +129,14 @@ void H_CL_Move()
|
||||
chan->SendDatagram(nullptr);
|
||||
|
||||
// Use full update rate when active.
|
||||
float delta = netTime - float(cl->m_flNextCmdTime);
|
||||
float maxDelta = fminf(fmaxf(delta, 0.0f), minFrameTime);
|
||||
const float delta = netTime - float(cl->m_flNextCmdTime);
|
||||
const float maxDelta = fminf(fmaxf(delta, 0.0f), minFrameTime);
|
||||
|
||||
cl->m_flNextCmdTime = double(minFrameTime + netTime - maxDelta);
|
||||
}
|
||||
}
|
||||
|
||||
void VCL_Main::Attach() const
|
||||
void VCL_Main::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&CL_Move, &H_CL_Move);
|
||||
}
|
||||
|
||||
void VCL_Main::Detach() const
|
||||
{
|
||||
DetourDetach(&CL_Move, &H_CL_Move);
|
||||
DetourSetup(&v_CL_Move, &CL_MoveEx, bAttach);
|
||||
}
|
||||
|
@ -1,19 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
inline CMemory p_CL_Move;
|
||||
inline void(*CL_Move)(void);
|
||||
|
||||
inline CMemory p_CL_SendMove;
|
||||
inline void(*CL_SendMove)(void);
|
||||
|
||||
inline CMemory p_CL_EndMovie;
|
||||
inline int(*CL_EndMovie)(void);
|
||||
|
||||
inline CMemory p_CL_ClearState;
|
||||
inline int(*CL_ClearState)(void);
|
||||
|
||||
inline CMemory p_CL_RunPrediction;
|
||||
inline void(*CL_RunPrediction)(void);
|
||||
inline void(*v_CL_Move)(void);
|
||||
inline void(*v_CL_SendMove)(void);
|
||||
inline int(*v_CL_EndMovie)(void);
|
||||
inline int(*v_CL_ClearState)(void);
|
||||
inline void(*v_CL_RunPrediction)(void);
|
||||
|
||||
inline bool g_bClientDLL = false;
|
||||
|
||||
@ -28,36 +19,22 @@ class VCL_Main : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CL_Move", p_CL_Move.GetPtr());
|
||||
LogFunAdr("CL_SendMove", p_CL_SendMove.GetPtr());
|
||||
LogFunAdr("CL_EndMovie", p_CL_EndMovie.GetPtr());
|
||||
LogFunAdr("CL_ClearState", p_CL_ClearState.GetPtr());
|
||||
LogFunAdr("CL_RunPrediction", p_CL_RunPrediction.GetPtr());
|
||||
LogFunAdr("CL_Move", v_CL_Move);
|
||||
LogFunAdr("CL_SendMove", v_CL_SendMove);
|
||||
LogFunAdr("CL_EndMovie", v_CL_EndMovie);
|
||||
LogFunAdr("CL_ClearState", v_CL_ClearState);
|
||||
LogFunAdr("CL_RunPrediction", v_CL_RunPrediction);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CL_Move = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 83 3D ?? ?? ?? ?? ?? 0F B6 DA");
|
||||
p_CL_SendMove = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 05 ?? ?? ?? ??");
|
||||
p_CL_EndMovie = g_GameDll.FindPatternSIMD("48 8B C4 48 83 EC 68 80 3D ?? ?? ?? ?? ??");
|
||||
p_CL_ClearState = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 1D ?? ?? ?? ??");
|
||||
p_CL_RunPrediction = g_GameDll.FindPatternSIMD("4C 8B DC 48 83 EC 58 83 3D ?? ?? ?? ?? ??");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CL_Move = g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 83 3D ?? ?? ?? ?? ?? 44 0F 29 5C 24 ??");
|
||||
p_CL_SendMove = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 05 ?? ?? ?? ??");
|
||||
p_CL_EndMovie = g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 74 7B");
|
||||
p_CL_ClearState = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01");
|
||||
p_CL_RunPrediction = g_GameDll.FindPatternSIMD("48 83 EC 48 83 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??");
|
||||
#endif
|
||||
CL_Move = p_CL_Move.RCast<void(*)(void)>();
|
||||
CL_SendMove = p_CL_SendMove.RCast<void(*)(void)>();
|
||||
CL_EndMovie = p_CL_EndMovie.RCast<int(*)(void)>();
|
||||
CL_ClearState = p_CL_ClearState.RCast<int(*)(void)>();
|
||||
CL_RunPrediction = p_CL_RunPrediction.RCast<void(*)(void)>();
|
||||
g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 83 3D ?? ?? ?? ?? ?? 44 0F 29 5C 24 ??").GetPtr(v_CL_Move);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 05 ?? ?? ?? ??").GetPtr(v_CL_SendMove);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 74 7B").GetPtr(v_CL_EndMovie);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01").GetPtr(v_CL_ClearState);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 48 83 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??").GetPtr(v_CL_RunPrediction);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -16,6 +16,20 @@
|
||||
#include "common/igameserverdata.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: console variables
|
||||
//-----------------------------------------------------------------------------
|
||||
static ConVar rcon_address("rcon_address", "[loopback]:37015", FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access address");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: console commands
|
||||
//-----------------------------------------------------------------------------
|
||||
static void RCON_Disconnect_f();
|
||||
static void RCON_CmdQuery_f(const CCommand& args);
|
||||
|
||||
static ConCommand rcon("rcon", RCON_CmdQuery_f, "Forward RCON query to remote server", FCVAR_CLIENTDLL | FCVAR_RELEASE, nullptr, "rcon \"<query>\"");
|
||||
static ConCommand rcon_disconnect("rcon_disconnect", RCON_Disconnect_f, "Disconnect from RCON server", FCVAR_CLIENTDLL | FCVAR_RELEASE);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -29,6 +43,9 @@ CRConClient::CRConClient()
|
||||
//-----------------------------------------------------------------------------
|
||||
CRConClient::~CRConClient(void)
|
||||
{
|
||||
// NOTE: do not call Shutdown() from the destructor as the OS's socket
|
||||
// system would be shutdown by now, call Shutdown() in application
|
||||
// shutdown code instead
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -76,7 +93,7 @@ void CRConClient::Disconnect(const char* szReason)
|
||||
szReason = "unknown reason";
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::CLIENT, "Disconnect: (%s)\n", szReason);
|
||||
Msg(eDLL_T::CLIENT, "RCON disconnect: (%s)\n", szReason);
|
||||
m_Socket.CloseAcceptedSocket(0);
|
||||
}
|
||||
}
|
||||
@ -112,7 +129,7 @@ bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
|
||||
}
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::NETCON, "%s", response.responsemsg().c_str());
|
||||
Msg(eDLL_T::NETCON, "%s", response.responsemsg().c_str());
|
||||
break;
|
||||
}
|
||||
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
|
||||
@ -187,13 +204,23 @@ SocketHandle_t CRConClient::GetSocket(void)
|
||||
return SH_GetNetConSocketHandle(this, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: request whether to recv logs from RCON server when cvar changes
|
||||
//-----------------------------------------------------------------------------
|
||||
static void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString)
|
||||
{
|
||||
RCONClient()->RequestConsoleLog(RCONClient()->ShouldReceive());
|
||||
}
|
||||
|
||||
static ConVar cl_rcon_inputonly("cl_rcon_inputonly", "0", FCVAR_RELEASE, "Tells the rcon server whether or not we are input only.",
|
||||
false, 0.f, false, 0.f, RCON_InputOnlyChanged_f);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns whether or not we should receive logs from the server
|
||||
// Output : SOCKET_ERROR (-1) on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRConClient::ShouldReceive(void)
|
||||
{
|
||||
return (!IsRemoteLocal() && !cl_rcon_inputonly->GetBool());
|
||||
return (!IsRemoteLocal() && !cl_rcon_inputonly.GetBool());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -221,8 +248,102 @@ bool CRConClient::IsConnected(void)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
CRConClient* g_RCONClient(new CRConClient());
|
||||
static CRConClient s_RCONClient;
|
||||
CRConClient* RCONClient() // Singleton RCON Client.
|
||||
{
|
||||
return g_RCONClient;
|
||||
return &s_RCONClient;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RCON_CmdQuery_f
|
||||
|
||||
Issues an RCON command to the
|
||||
RCON server.
|
||||
=====================
|
||||
*/
|
||||
static void RCON_CmdQuery_f(const CCommand& args)
|
||||
{
|
||||
const int64_t argCount = args.ArgC();
|
||||
|
||||
if (argCount < 2)
|
||||
{
|
||||
const char* pszAddress = rcon_address.GetString();
|
||||
|
||||
if (RCONClient()->IsInitialized()
|
||||
&& !RCONClient()->IsConnected()
|
||||
&& pszAddress[0])
|
||||
{
|
||||
RCONClient()->Connect(pszAddress);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RCONClient()->IsInitialized())
|
||||
{
|
||||
Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "uninitialized");
|
||||
return;
|
||||
}
|
||||
else if (RCONClient()->IsConnected())
|
||||
{
|
||||
vector<char> vecMsg;
|
||||
bool bSuccess = false;
|
||||
const SocketHandle_t hSocket = RCONClient()->GetSocket();
|
||||
|
||||
if (strcmp(args.Arg(1), "PASS") == 0) // Auth with RCON server using rcon_password ConVar value.
|
||||
{
|
||||
if (argCount > 2)
|
||||
{
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", cl_rcon::request_t::SERVERDATA_REQUEST_AUTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "no password given");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (strcmp(args.Arg(1), "disconnect") == 0) // Disconnect from RCON server.
|
||||
{
|
||||
RCONClient()->Disconnect("issued by user");
|
||||
return;
|
||||
}
|
||||
|
||||
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND);
|
||||
if (bSuccess)
|
||||
{
|
||||
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "unconnected");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RCON_Disconnect_f
|
||||
|
||||
Disconnect from RCON server
|
||||
=====================
|
||||
*/
|
||||
static void RCON_Disconnect_f()
|
||||
{
|
||||
const bool bIsConnected = RCONClient()->IsConnected();
|
||||
RCONClient()->Disconnect("issued by user");
|
||||
|
||||
if (bIsConnected) // Log if client was indeed connected.
|
||||
{
|
||||
Msg(eDLL_T::CLIENT, "User closed RCON connection\n");
|
||||
}
|
||||
}
|
||||
|
@ -128,26 +128,18 @@ class VSplitScreen : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogVarAdr("g_SplitScreenMgr", reinterpret_cast<uintptr_t>(g_pSplitScreenMgr));
|
||||
LogVarAdr("g_SplitScreenMgr", g_pSplitScreenMgr);
|
||||
}
|
||||
virtual void GetFun(void) const { }
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
const char* pszPattern;
|
||||
const char* pszInstruction;
|
||||
const char* const pszPattern = "40 53 48 83 EC 20 48 8D 1D ?? ?? ?? ?? 83 FA FF 75 12 48 8B 05 ?? ?? ?? ?? 48 8B CB FF 50 28 48 63 C8 EB 03 48 63 CA 48 69 C1 ?? ?? ?? ?? 66 C7 84 18 ?? ?? ?? ?? ?? ??";;
|
||||
const char* const pszInstruction = "48 8D";
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
pszPattern = "83 FA FF 75 22 48 8D 05 ?? ?? ?? ??";
|
||||
pszInstruction = "4C 8D";
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
pszPattern = "40 53 48 83 EC 20 48 8D 1D ?? ?? ?? ?? 83 FA FF 75 12 48 8B 05 ?? ?? ?? ?? 48 8B CB FF 50 28 48 63 C8 EB 03 48 63 CA 48 69 C1 ?? ?? ?? ?? 66 C7 84 18 ?? ?? ?? ?? ?? ??";
|
||||
pszInstruction = "48 8D";
|
||||
#endif
|
||||
g_pSplitScreenMgr = g_GameDll.FindPatternSIMD(pszPattern).FindPatternSelf(pszInstruction).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CSplitScreen*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { };
|
||||
virtual void Detach(void) const { };
|
||||
virtual void Detour(const bool bAttach) const { };
|
||||
};
|
||||
|
||||
#endif // CL_SPLITSCREEN_H
|
||||
|
@ -13,9 +13,14 @@
|
||||
#include "tier1/strtools.h"
|
||||
#include "engine/server/server.h"
|
||||
#include "engine/client/client.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "networksystem/hostmanager.h"
|
||||
#include "jwt/include/decode.h"
|
||||
#include "mbedtls/include/mbedtls/sha256.h"
|
||||
#endif
|
||||
|
||||
// 128+1 so that the client still receives the 'console command too long' message.
|
||||
#define STRINGCMD_MAX_LEN 129
|
||||
// Absolute max string cmd length, any character past this will be NULLED.
|
||||
#define STRINGCMD_MAX_LEN 512
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: throw away any residual garbage in the channel
|
||||
@ -23,9 +28,9 @@
|
||||
void CClient::Clear(void)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
g_ServerPlayer[GetUserID()].Reset(); // Reset ServerPlayer slot.
|
||||
GetClientExtended()->Reset(); // Reset extended data.
|
||||
#endif // !CLIENT_DLL
|
||||
v_CClient_Clear(this);
|
||||
CClient__Clear(this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -37,39 +42,224 @@ void CClient::VClear(CClient* pClient)
|
||||
pClient->Clear();
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: gets the extended client data
|
||||
// Output : CClientExtended* -
|
||||
//---------------------------------------------------------------------------------
|
||||
CClientExtended* CClient::GetClientExtended(void) const
|
||||
{
|
||||
return m_pServer->GetClientExtended(m_nUserID);
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
|
||||
static const char JWT_PUBLIC_KEY[] =
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/335exIZ6LE8pYi6e50\n"
|
||||
"7tH19tXaeeEJVF5XXpTCXpndXIIWVimvg6xQ381eajySDw93wvG1DzW3U/6LHzyt\n"
|
||||
"Q++N8w7N+FwnXyoDUD5Y8hheTZv6jjLoYT8ZtsMl20k9UosrbFBTMUhgmIT2dVth\n"
|
||||
"LH+rT9ohpUNwQXHJvTOs9eY74GyfFw93+32LANBPZ8b+S8S3oZnKFVeCxRkYKsV0\n"
|
||||
"b34POHVBbXNw6Kt163gR5zaiCfJJtRto9AA7MV2t9pfy8CChs3uJ+Xn7QVHD5cqt\n"
|
||||
"Msg9MBac2Pvs2j+8wJ/igAVL5L81z3FXVt04id59TfPMUbYhRfY8pk7FB0MCigOH\n"
|
||||
"dwIDAQAB\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
static ConVar sv_onlineAuthEnable("sv_onlineAuthEnable", "1", FCVAR_RELEASE, "Enables the server-side online authentication system");
|
||||
|
||||
static ConVar sv_onlineAuthValidateExpiry("sv_onlineAuthValidateExpiry", "1", FCVAR_RELEASE, "Validate the online authentication token 'expiry' claim");
|
||||
static ConVar sv_onlineAuthValidateIssuedAt("sv_onlineAuthValidateIssuedAt", "1", FCVAR_RELEASE, "Validate the online authentication token 'issued at' claim");
|
||||
|
||||
static ConVar sv_onlineAuthExpiryTolerance("sv_onlineAuthExpiryTolerance", "1", FCVAR_DEVELOPMENTONLY, "The online authentication token 'expiry' claim tolerance in seconds", true, 0.f, true, float(UINT8_MAX), "Must range between [0,255]");
|
||||
static ConVar sv_onlineAuthIssuedAtTolerance("sv_onlineAuthIssuedAtTolerance", "30", FCVAR_DEVELOPMENTONLY, "The online authentication token 'issued at' claim tolerance in seconds", true, 0.f, true, float(UINT8_MAX), "Must range between [0,255]");
|
||||
|
||||
static ConVar sv_quota_stringCmdsPerSecond("sv_quota_stringCmdsPerSecond", "16", FCVAR_RELEASE, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands", true, 0.f, false, 0.f);
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: check whether this client is authorized to join this server
|
||||
// Input : *playerName -
|
||||
// *reasonBuf -
|
||||
// reasonBufLen -
|
||||
// Output : true if authorized, false otherwise
|
||||
//---------------------------------------------------------------------------------
|
||||
bool CClient::Authenticate(const char* const playerName, char* const reasonBuf, const size_t reasonBufLen)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
// don't bother checking origin auth on bots or local clients
|
||||
if (IsFakeClient() || GetNetChan()->GetRemoteAddress().IsLoopback())
|
||||
return true;
|
||||
|
||||
l8w8jwt_claim* claims = nullptr;
|
||||
size_t numClaims = 0;
|
||||
|
||||
// formats the error reason, and frees the claims and returns
|
||||
#define ERROR_AND_RETURN(fmt, ...) \
|
||||
do {\
|
||||
V_snprintf(reasonBuf, reasonBufLen, fmt, ##__VA_ARGS__); \
|
||||
if (claims) {\
|
||||
l8w8jwt_free_claims(claims, numClaims); \
|
||||
}\
|
||||
return false; \
|
||||
} while(0)\
|
||||
|
||||
KeyValues* const cl_onlineAuthTokenKv = this->m_ConVars->FindKey("cl_onlineAuthToken");
|
||||
KeyValues* const cl_onlineAuthTokenSignature1Kv = this->m_ConVars->FindKey("cl_onlineAuthTokenSignature1");
|
||||
KeyValues* const cl_onlineAuthTokenSignature2Kv = this->m_ConVars->FindKey("cl_onlineAuthTokenSignature2");
|
||||
|
||||
if (!cl_onlineAuthTokenKv || !cl_onlineAuthTokenSignature1Kv)
|
||||
ERROR_AND_RETURN("Missing token");
|
||||
|
||||
const char* const onlineAuthToken = cl_onlineAuthTokenKv->GetString();
|
||||
const char* const onlineAuthTokenSignature1 = cl_onlineAuthTokenSignature1Kv->GetString();
|
||||
const char* const onlineAuthTokenSignature2 = cl_onlineAuthTokenSignature2Kv->GetString();
|
||||
|
||||
char fullToken[1024]; // enough buffer for 3x255, which is cvar count * userinfo str limit.
|
||||
const int tokenLen = snprintf(fullToken, sizeof(fullToken), "%s.%s%s",
|
||||
onlineAuthToken, onlineAuthTokenSignature1, onlineAuthTokenSignature2);
|
||||
|
||||
if (tokenLen < 0)
|
||||
ERROR_AND_RETURN("Token stitching failed");
|
||||
|
||||
struct l8w8jwt_decoding_params params;
|
||||
l8w8jwt_decoding_params_init(¶ms);
|
||||
|
||||
params.alg = L8W8JWT_ALG_RS256;
|
||||
|
||||
params.jwt = (char*)fullToken;
|
||||
params.jwt_length = tokenLen;
|
||||
|
||||
params.verification_key = (unsigned char*)JWT_PUBLIC_KEY;
|
||||
params.verification_key_length = sizeof(JWT_PUBLIC_KEY);
|
||||
|
||||
params.validate_exp = sv_onlineAuthValidateExpiry.GetBool();
|
||||
params.exp_tolerance_seconds = (uint8_t)sv_onlineAuthExpiryTolerance.GetInt();
|
||||
|
||||
params.validate_iat = sv_onlineAuthValidateIssuedAt.GetBool();
|
||||
params.iat_tolerance_seconds = (uint8_t)sv_onlineAuthIssuedAtTolerance.GetInt();
|
||||
|
||||
enum l8w8jwt_validation_result validation_result;
|
||||
const int r = l8w8jwt_decode(¶ms, &validation_result, &claims, &numClaims);
|
||||
|
||||
if (r != L8W8JWT_SUCCESS)
|
||||
ERROR_AND_RETURN("Code %i", r);
|
||||
|
||||
if (validation_result != L8W8JWT_VALID)
|
||||
{
|
||||
char reasonBuffer[64];
|
||||
l8w8jwt_get_validation_result_desc(validation_result, reasonBuffer, sizeof(reasonBuffer));
|
||||
|
||||
ERROR_AND_RETURN("%s", reasonBuffer);
|
||||
}
|
||||
|
||||
bool foundSessionId = false;
|
||||
for (size_t i = 0; i < numClaims; ++i)
|
||||
{
|
||||
// session id
|
||||
if (!strcmp(claims[i].key, "sessionId"))
|
||||
{
|
||||
const char* const sessionId = claims[i].value;
|
||||
|
||||
char newId[256];
|
||||
const int idLen = snprintf(newId, sizeof(newId), "%llu-%s-%s",
|
||||
(NucleusID_t)this->m_DataBlock.userData,
|
||||
playerName,
|
||||
g_ServerHostManager.GetHostIP().c_str());
|
||||
|
||||
if (idLen < 0)
|
||||
ERROR_AND_RETURN("Session ID stitching failed");
|
||||
|
||||
uint8_t sessionHash[32]; // hash decoded from JWT token
|
||||
V_hextobinary(sessionId, strlen(sessionId), sessionHash, sizeof(sessionHash));
|
||||
|
||||
uint8_t oobHash[32]; // hash of data collected from out of band packet
|
||||
const int shRet = mbedtls_sha256((const uint8_t*)newId, idLen, oobHash, NULL);
|
||||
|
||||
if (shRet != NULL)
|
||||
ERROR_AND_RETURN("Session ID hashing failed");
|
||||
|
||||
if (memcmp(oobHash, sessionHash, sizeof(sessionHash)) != 0)
|
||||
ERROR_AND_RETURN("Token is not authorized for the connecting client");
|
||||
|
||||
foundSessionId = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSessionId)
|
||||
ERROR_AND_RETURN("No session ID");
|
||||
|
||||
l8w8jwt_free_claims(claims, numClaims);
|
||||
|
||||
#undef ERROR_AND_RETURN
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: connect new client
|
||||
// Input : *szName -
|
||||
// *pNetChannel -
|
||||
// *pNetChan -
|
||||
// bFakePlayer -
|
||||
// *a5 -
|
||||
// *conVars -
|
||||
// *szMessage -
|
||||
// nMessageSize -
|
||||
// Output : true if connection was successful, false otherwise
|
||||
//---------------------------------------------------------------------------------
|
||||
bool CClient::Connect(const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize)
|
||||
bool CClient::Connect(const char* szName, CNetChan* pNetChan, bool bFakePlayer,
|
||||
CUtlVector<NET_SetConVar::cvar_t>* conVars, char* szMessage, int nMessageSize)
|
||||
{
|
||||
return v_CClient_Connect(this, szName, pNetChannel, bFakePlayer, a5, szMessage, nMessageSize);
|
||||
#ifndef CLIENT_DLL
|
||||
GetClientExtended()->Reset(); // Reset extended data.
|
||||
#endif
|
||||
|
||||
if (!CClient__Connect(this, szName, pNetChan, bFakePlayer, conVars, szMessage, nMessageSize))
|
||||
return false;
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
#define REJECT_CONNECTION(fmt, ...) V_snprintf(szMessage, nMessageSize, fmt, ##__VA_ARGS__);
|
||||
|
||||
if (sv_onlineAuthEnable.GetBool())
|
||||
{
|
||||
char authFailReason[512];
|
||||
if (!Authenticate(szName, authFailReason, sizeof(authFailReason)))
|
||||
{
|
||||
REJECT_CONNECTION("Failed to verify authentication token [%s]", authFailReason);
|
||||
|
||||
const bool bEnableLogging = sv_showconnecting.GetBool();
|
||||
if (bEnableLogging)
|
||||
{
|
||||
const char* const netAdr = pNetChan ? pNetChan->GetAddress() : "<unknown>";
|
||||
|
||||
Warning(eDLL_T::SERVER, "Client '%s' ('%llu') failed online authentication! [%s]\n",
|
||||
netAdr, (NucleusID_t)m_DataBlock.userData, authFailReason);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#undef REJECT_CONNECTION
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: connect new client
|
||||
// Input : *pClient -
|
||||
// *szName -
|
||||
// *pNetChannel -
|
||||
// *pNetChan -
|
||||
// bFakePlayer -
|
||||
// *a5 -
|
||||
// *szMessage -
|
||||
// nMessageSize -
|
||||
// Output : true if connection was successful, false otherwise
|
||||
//---------------------------------------------------------------------------------
|
||||
bool CClient::VConnect(CClient* pClient, const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize)
|
||||
bool CClient::VConnect(CClient* pClient, const char* szName, CNetChan* pNetChan, bool bFakePlayer,
|
||||
CUtlVector<NET_SetConVar::cvar_t>* conVars, char* szMessage, int nMessageSize)
|
||||
{
|
||||
bool bResult = v_CClient_Connect(pClient, szName, pNetChannel, bFakePlayer, a5, szMessage, nMessageSize);
|
||||
#ifndef CLIENT_DLL
|
||||
g_ServerPlayer[pClient->GetUserID()].Reset(); // Reset ServerPlayer slot.
|
||||
#endif // !CLIENT_DLL
|
||||
return bResult;
|
||||
return pClient->Connect(szName, pNetChan, bFakePlayer, conVars, szMessage, nMessageSize);;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -92,7 +282,7 @@ void CClient::Disconnect(const Reputation_t nRepLvl, const char* szReason, ...)
|
||||
szBuf[sizeof(szBuf) - 1] = '\0';
|
||||
va_end(vArgs);
|
||||
}/////////////////////////////
|
||||
v_CClient_Disconnect(this, nRepLvl, szBuf);
|
||||
CClient__Disconnect(this, nRepLvl, szBuf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,14 +294,14 @@ void CClient::VActivatePlayer(CClient* pClient)
|
||||
{
|
||||
// Set the client instance to 'ready' before calling ActivatePlayer.
|
||||
pClient->SetPersistenceState(PERSISTENCE::PERSISTENCE_READY);
|
||||
v_CClient_ActivatePlayer(pClient);
|
||||
CClient__ActivatePlayer(pClient);
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
const CNetChan* pNetChan = pClient->GetNetChan();
|
||||
|
||||
if (pNetChan && sv_showconnecting->GetBool())
|
||||
if (pNetChan && sv_showconnecting.GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, "Activated player #%d; channel %s(%s) ('%llu')\n",
|
||||
Msg(eDLL_T::SERVER, "Activated player #%d; channel %s(%s) ('%llu')\n",
|
||||
pClient->GetUserID(), pNetChan->GetName(), pNetChan->GetAddress(), pClient->GetNucleusID());
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
@ -125,7 +315,7 @@ void CClient::VActivatePlayer(CClient* pClient)
|
||||
// bForceReliable -
|
||||
// bVoice -
|
||||
//---------------------------------------------------------------------------------
|
||||
bool CClient::SendNetMsgEx(CNetMessage* pMsg, char bLocal, bool bForceReliable, bool bVoice)
|
||||
bool CClient::SendNetMsgEx(CNetMessage* pMsg, bool bLocal, bool bForceReliable, bool bVoice)
|
||||
{
|
||||
if (!ShouldReplayMessage(pMsg))
|
||||
{
|
||||
@ -133,7 +323,7 @@ bool CClient::SendNetMsgEx(CNetMessage* pMsg, char bLocal, bool bForceReliable,
|
||||
pMsg->m_nGroup = NetMessageGroup::NoReplay;
|
||||
}
|
||||
|
||||
return v_CClient_SendNetMsgEx(this, pMsg, bLocal, bForceReliable, bVoice);
|
||||
return CClient__SendNetMsgEx(this, pMsg, bLocal, bForceReliable, bVoice);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -145,7 +335,64 @@ bool CClient::SendNetMsgEx(CNetMessage* pMsg, char bLocal, bool bForceReliable,
|
||||
//---------------------------------------------------------------------------------
|
||||
void* CClient::VSendSnapshot(CClient* pClient, CClientFrame* pFrame, int nTick, int nTickAck)
|
||||
{
|
||||
return v_CClient_SendSnapshot(pClient, pFrame, nTick, nTickAck);
|
||||
return CClient__SendSnapshot(pClient, pFrame, nTick, nTickAck);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: internal hook to 'CClient::SendNetMsgEx'
|
||||
// Input : *pClient -
|
||||
// *pMsg -
|
||||
// bLocal -
|
||||
// bForceReliable -
|
||||
// bVoice -
|
||||
//---------------------------------------------------------------------------------
|
||||
bool CClient::VSendNetMsgEx(CClient* pClient, CNetMessage* pMsg, bool bLocal, bool bForceReliable, bool bVoice)
|
||||
{
|
||||
return pClient->SendNetMsgEx(pMsg, bLocal, bForceReliable, bVoice);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: write data into data blocks to send to the client
|
||||
// Input : &buf
|
||||
//---------------------------------------------------------------------------------
|
||||
void CClient::WriteDataBlock(CClient* pClient, bf_write& buf)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if (net_data_block_enabled->GetBool())
|
||||
{
|
||||
buf.WriteUBitLong(net_NOP, NETMSG_TYPE_BITS);
|
||||
|
||||
const int remainingBits = buf.GetNumBitsWritten() % 8;
|
||||
|
||||
if (remainingBits && (8 - remainingBits) > 0)
|
||||
{
|
||||
// fill the last bits in the last byte with NOP
|
||||
buf.WriteUBitLong(net_NOP, 8 - remainingBits);
|
||||
}
|
||||
|
||||
const bool isMultiplayer = g_ServerGlobalVariables->m_nGameMode < GameMode_t::PVE_MODE;
|
||||
pClient->m_DataBlock.sender.WriteDataBlock(buf.GetData(), buf.GetNumBytesWritten(), isMultiplayer, buf.GetDebugName());
|
||||
}
|
||||
else
|
||||
{
|
||||
pClient->m_NetChannel->SendData(buf, true);
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: some versions of the binary have an optimization that shifts the 'this'
|
||||
// pointer of the CClient structure by 8 bytes to avoid having to cache the vftable
|
||||
// pointer if it never get used. Here we shift it back so it aligns again.
|
||||
//---------------------------------------------------------------------------------
|
||||
CClient* AdjustShiftedThisPointer(CClient* shiftedPointer)
|
||||
{
|
||||
/* Original function called method "CClient::ExecuteStringCommand" with an optimization
|
||||
* that shifted the 'this' pointer with 8 bytes.
|
||||
* Since this has been inlined with "CClient::ProcessStringCmd" as of S2, the shifting
|
||||
* happens directly to anything calling this function. */
|
||||
char* pShifted = reinterpret_cast<char*>(shiftedPointer) - 8;
|
||||
return reinterpret_cast<CClient*>(pShifted);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -157,21 +404,16 @@ void* CClient::VSendSnapshot(CClient* pClient, CClientFrame* pFrame, int nTick,
|
||||
bool CClient::VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
CClient* pClient_Adj = pClient;
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
/* Original function called method "CClient::ExecuteStringCommand" with an optimization
|
||||
* that shifted the 'this' pointer with 8 bytes.
|
||||
* Since this has been inlined with "CClient::ProcessStringCmd" as of S2, the shifting
|
||||
* happens directly to anything calling this function. */
|
||||
char* pShifted = reinterpret_cast<char*>(pClient) - 8;
|
||||
CClient* pClient_Adj = reinterpret_cast<CClient*>(pShifted);
|
||||
#endif // !GAMEDLL_S0 || !GAMEDLL_S1
|
||||
int nUserID = pClient_Adj->GetUserID();
|
||||
ServerPlayer_t* pSlot = &g_ServerPlayer[nUserID];
|
||||
CClient* const pClient_Adj = AdjustShiftedThisPointer(pClient);
|
||||
|
||||
double flStartTime = Plat_FloatTime();
|
||||
int nCmdQuotaLimit = sv_quota_stringCmdsPerSecond->GetInt();
|
||||
// Jettison the cmd if the client isn't active.
|
||||
if (!pClient_Adj->IsActive())
|
||||
return true;
|
||||
|
||||
CClientExtended* const pSlot = pClient_Adj->GetClientExtended();
|
||||
|
||||
const double flStartTime = Plat_FloatTime();
|
||||
const int nCmdQuotaLimit = sv_quota_stringCmdsPerSecond.GetInt();
|
||||
|
||||
if (!nCmdQuotaLimit)
|
||||
return true;
|
||||
@ -182,16 +424,13 @@ bool CClient::VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg)
|
||||
// The internal function discards the command if it's null.
|
||||
if (pCmd)
|
||||
{
|
||||
// If the string length exceeds 128, the will engine return a 'command
|
||||
// string too long' message back to the client that issued it and
|
||||
// subsequently jettison the string cmd. Before this routine gets hit,
|
||||
// the entire string gets parsed (up to 512 bytes). There is an issue
|
||||
// in CUtlBuffer::ParseToken() that causes it to read past its buffer;
|
||||
// mostly seems to happen on 32bit, but a carefully crafted string
|
||||
// should work on 64bit too). The fix is to just null everything past
|
||||
// the maximum allowed length. The second 'theoretical' fix would be to
|
||||
// properly fix CUtlBuffer::ParseToken() by computing the UTF8 character
|
||||
// size each iteration and check if it still doesn't exceed bounds.
|
||||
// There is an issue in CUtlBuffer::ParseToken() that causes it to read
|
||||
// past its buffer; mostly seems to happen on 32bit, but a carefully
|
||||
// crafted string should work on 64bit too). The fix is to just null
|
||||
// everything past the maximum allowed length. The second 'theoretical'
|
||||
// fix would be to properly fix CUtlBuffer::ParseToken() by computing
|
||||
// the UTF8 character size each iteration and check if it still doesn't
|
||||
// exceed bounds.
|
||||
memset(&pMsg->buffer[STRINGCMD_MAX_LEN],
|
||||
'\0', sizeof(pMsg->buffer) - (STRINGCMD_MAX_LEN));
|
||||
|
||||
@ -222,41 +461,80 @@ bool CClient::VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg)
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
return v_CClient_ProcessStringCmd(pClient, pMsg);
|
||||
return CClient__ProcessStringCmd(pClient, pMsg);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: internal hook to 'CClient::SendNetMsgEx'
|
||||
// Input : *pClient -
|
||||
// Purpose: process set convar
|
||||
// Input : *pClient - (ADJ)
|
||||
// *pMsg -
|
||||
// bLocal -
|
||||
// bForceReliable -
|
||||
// bVoice -
|
||||
// Output :
|
||||
//---------------------------------------------------------------------------------
|
||||
bool CClient::VSendNetMsgEx(CClient* pClient, CNetMessage* pMsg, char bLocal, bool bForceReliable, bool bVoice)
|
||||
bool CClient::VProcessSetConVar(CClient* pClient, NET_SetConVar* pMsg)
|
||||
{
|
||||
return pClient->SendNetMsgEx(pMsg, bLocal, bForceReliable, bVoice);
|
||||
#ifndef CLIENT_DLL
|
||||
CClient* const pAdj = AdjustShiftedThisPointer(pClient);
|
||||
CClientExtended* const pSlot = pAdj->GetClientExtended();
|
||||
|
||||
// This loop never exceeds 255 iterations, NET_SetConVar::ReadFromBuffer(...)
|
||||
// reads and inserts up to 255 entries in the vector (reads a byte for size).
|
||||
FOR_EACH_VEC(pMsg->m_ConVars, i)
|
||||
{
|
||||
const NET_SetConVar::cvar_t& entry = pMsg->m_ConVars[i];
|
||||
const char* const name = entry.name;
|
||||
const char* const value = entry.value;
|
||||
|
||||
// Discard any ConVar change request if it contains funky characters.
|
||||
bool bFunky = false;
|
||||
for (const char* s = name; *s != '\0'; ++s)
|
||||
{
|
||||
if (!V_isalnum(*s) && *s != '_')
|
||||
{
|
||||
bFunky = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bFunky)
|
||||
{
|
||||
DevWarning(eDLL_T::SERVER, "Ignoring ConVar change request for variable '%s' from client '%s'; invalid characters in the variable name\n",
|
||||
name, pAdj->GetClientName());
|
||||
continue;
|
||||
}
|
||||
|
||||
void VClient::Attach(void) const
|
||||
// The initial set of ConVars must contain all client ConVars that are
|
||||
// flagged UserInfo. This is a simple fix to exploits that send bogus
|
||||
// data later, and catches bugs, such as new UserInfo ConVars appearing
|
||||
// later, which shouldn't happen.
|
||||
if (pSlot->m_bInitialConVarsSet && !pAdj->m_ConVars->FindKey(name))
|
||||
{
|
||||
DevWarning(eDLL_T::SERVER, "UserInfo update from \"%s\" ignored: %s = %s\n",
|
||||
pAdj->GetClientName(), name, value);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add ConVar to list and set string.
|
||||
pAdj->m_ConVars->SetString(name, value);
|
||||
DevMsg(eDLL_T::SERVER, "UserInfo update from \"%s\": %s = %s\n", pAdj->GetClientName(), name, value);
|
||||
}
|
||||
|
||||
pSlot->m_bInitialConVarsSet = true;
|
||||
pAdj->m_bConVarsChanged = true;
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VClient::Detour(const bool bAttach) const
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
DetourAttach((LPVOID*)&v_CClient_Clear, &CClient::VClear);
|
||||
DetourAttach((LPVOID*)&v_CClient_Connect, &CClient::VConnect);
|
||||
DetourAttach((LPVOID*)&v_CClient_ActivatePlayer, &CClient::VActivatePlayer);
|
||||
DetourAttach((LPVOID*)&v_CClient_ProcessStringCmd, &CClient::VProcessStringCmd);
|
||||
DetourAttach((LPVOID*)&v_CClient_SendNetMsgEx, &CClient::VSendNetMsgEx);
|
||||
//DetourAttach((LPVOID*)&p_CClient_SendSnapshot, &CClient::VSendSnapshot);
|
||||
#endif // !CLIENT_DLL
|
||||
}
|
||||
void VClient::Detach(void) const
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
DetourDetach((LPVOID*)&v_CClient_Clear, &CClient::VClear);
|
||||
DetourDetach((LPVOID*)&v_CClient_Connect, &CClient::VConnect);
|
||||
DetourDetach((LPVOID*)&v_CClient_ActivatePlayer, &CClient::VActivatePlayer);
|
||||
DetourDetach((LPVOID*)&v_CClient_ProcessStringCmd, &CClient::VProcessStringCmd);
|
||||
DetourDetach((LPVOID*)&v_CClient_SendNetMsgEx, &CClient::VSendNetMsgEx);
|
||||
//DetourDetach((LPVOID*)&p_CClient_SendSnapshot, &CClient::VSendSnapshot);
|
||||
DetourSetup(&CClient__Clear, &CClient::VClear, bAttach);
|
||||
DetourSetup(&CClient__Connect, &CClient::VConnect, bAttach);
|
||||
DetourSetup(&CClient__ActivatePlayer, &CClient::VActivatePlayer, bAttach);
|
||||
DetourSetup(&CClient__SendNetMsgEx, &CClient::VSendNetMsgEx, bAttach);
|
||||
//DetourSetup(&CClient__SendSnapshot, &CClient::VSendSnapshot, bAttach);
|
||||
DetourSetup(&CClient__WriteDataBlock, &CClient::WriteDataBlock, bAttach);
|
||||
|
||||
DetourSetup(&CClient__ProcessStringCmd, &CClient::VProcessStringCmd, bAttach);
|
||||
DetourSetup(&CClient__ProcessSetConVar, &CClient::VProcessSetConVar, bAttach);
|
||||
#endif // !CLIENT_DLL
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "common/protocol.h"
|
||||
#include "ebisusdk/EbisuTypes.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/net_chan.h"
|
||||
#include "public/edict.h"
|
||||
#include "engine/server/datablock_sender.h"
|
||||
@ -20,6 +22,7 @@ enum Reputation_t
|
||||
//-----------------------------------------------------------------------------
|
||||
class CServer;
|
||||
class CClient;
|
||||
class CClientExtended;
|
||||
|
||||
struct Spike_t
|
||||
{
|
||||
@ -65,20 +68,24 @@ public:
|
||||
inline int64_t GetTeamNum() const { return m_iTeamNum; }
|
||||
inline edict_t GetHandle(void) const { return m_nHandle; }
|
||||
inline int GetUserID(void) const { return m_nUserID; }
|
||||
inline uint64_t GetNucleusID(void) const { return m_nNucleusID; }
|
||||
inline NucleusID_t GetNucleusID(void) const { return m_nNucleusID; }
|
||||
|
||||
inline SIGNONSTATE GetSignonState(void) const { return m_nSignonState; }
|
||||
inline PERSISTENCE GetPersistenceState(void) const { return m_nPersistenceState; }
|
||||
inline CNetChan* GetNetChan(void) const { return m_NetChannel; }
|
||||
inline CServer* GetServer(void) const { return m_pServer; }
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CClientExtended* GetClientExtended(void) const;
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
inline int GetCommandTick(void) const { return m_nCommandTick; }
|
||||
inline const char* GetServerName(void) const { return m_szServerName; }
|
||||
inline const char* GetClientName(void) const { return m_szClientName; }
|
||||
|
||||
inline void SetHandle(edict_t nHandle) { m_nHandle = nHandle; }
|
||||
inline void SetUserID(uint32_t nUserID) { m_nUserID = nUserID; }
|
||||
inline void SetNucleusID(uint64_t nNucleusID) { m_nNucleusID = nNucleusID; }
|
||||
inline void SetNucleusID(NucleusID_t nNucleusID) { m_nNucleusID = nNucleusID; }
|
||||
|
||||
inline void SetSignonState(SIGNONSTATE nSignonState) { m_nSignonState = nSignonState; }
|
||||
inline void SetPersistenceState(PERSISTENCE nPersistenceState) { m_nPersistenceState = nPersistenceState; }
|
||||
@ -92,18 +99,27 @@ public:
|
||||
inline bool IsFakeClient(void) const { return m_bFakePlayer; }
|
||||
inline bool IsHumanPlayer(void) const { if (!IsConnected() || IsFakeClient()) { return false; } return true; }
|
||||
|
||||
bool SendNetMsgEx(CNetMessage* pMsg, char bLocal, bool bForceReliable, bool bVoice);
|
||||
bool Connect(const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize);
|
||||
bool SendNetMsgEx(CNetMessage* pMsg, bool bLocal, bool bForceReliable, bool bVoice);
|
||||
|
||||
bool Authenticate(const char* const playerName, char* const reasonBuf, const size_t reasonBufLen);
|
||||
bool Connect(const char* szName, CNetChan* pNetChan, bool bFakePlayer,
|
||||
CUtlVector<NET_SetConVar::cvar_t>* conVars, char* szMessage, int nMessageSize);
|
||||
void Disconnect(const Reputation_t nRepLvl, const char* szReason, ...);
|
||||
static bool VConnect(CClient* pClient, const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize);
|
||||
void Clear(void);
|
||||
|
||||
public: // Hook statics:
|
||||
static void VClear(CClient* pClient);
|
||||
static bool VConnect(CClient* pClient, const char* szName, CNetChan* pNetChan, bool bFakePlayer,
|
||||
CUtlVector<NET_SetConVar::cvar_t>* conVars, char* szMessage, int nMessageSize);
|
||||
|
||||
static void VActivatePlayer(CClient* pClient);
|
||||
static bool VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg);
|
||||
static void* VSendSnapshot(CClient* pClient, CClientFrame* pFrame, int nTick, int nTickAck);
|
||||
static bool VSendNetMsgEx(CClient* pClient, CNetMessage* pMsg, char bLocal, bool bForceReliable, bool bVoice);
|
||||
static bool VSendNetMsgEx(CClient* pClient, CNetMessage* pMsg, bool bLocal, bool bForceReliable, bool bVoice);
|
||||
|
||||
static void WriteDataBlock(CClient* pClient, bf_write& buf);
|
||||
|
||||
static bool VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg);
|
||||
static bool VProcessSetConVar(CClient* pClient, NET_SetConVar* pMsg);
|
||||
|
||||
private:
|
||||
// Stub reimplementation to avoid the 'no overrider' compiler errors in the
|
||||
@ -146,24 +162,28 @@ private:
|
||||
char m_szClientName[256];
|
||||
char m_szMachineName[256];
|
||||
int m_nCommandTick;
|
||||
char m_bUsePersistence_MAYBE;
|
||||
bool m_bUsePersistence_MAYBE;
|
||||
char pad_0016[59];
|
||||
int64_t m_iTeamNum;
|
||||
KeyValues* m_ConVars;
|
||||
char m_bInitialConVarsSet;
|
||||
char m_bSendServerInfo;
|
||||
char m_bSendSignonData;
|
||||
char m_bFullStateAchieved;
|
||||
bool m_bConVarsChanged;
|
||||
bool m_bSendServerInfo;
|
||||
bool m_bSendSignonData;
|
||||
bool m_bFullStateAchieved;
|
||||
char pad_0368[4];
|
||||
CServer* m_pServer;
|
||||
char pad_0378[24];
|
||||
char pad_0378[20];
|
||||
int m_nDisconnectTick;
|
||||
bool m_bKickedByFairFight_MAYBE;
|
||||
char pad_0398[14];
|
||||
char pad_0398[3];
|
||||
int m_nSendtableCRC;
|
||||
int m_nMmDev;
|
||||
char pad_039C[4];
|
||||
CNetChan* m_NetChannel;
|
||||
char pad_03A8[8];
|
||||
SIGNONSTATE m_nSignonState;
|
||||
int unk0;
|
||||
uint64_t m_nNucleusID;
|
||||
NucleusID_t m_nNucleusID;
|
||||
int unk1;
|
||||
int unk2;
|
||||
int m_nDeltaTick;
|
||||
@ -171,10 +191,8 @@ private:
|
||||
int m_nSignonTick;
|
||||
int m_nBaselineUpdateTick_MAYBE;
|
||||
char pad_03C0[448];
|
||||
#if defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
int unk3;
|
||||
int m_nForceWaitForTick;
|
||||
#endif
|
||||
bool m_bFakePlayer;
|
||||
bool m_bReceivedPacket;
|
||||
bool m_bLowViolence;
|
||||
@ -183,92 +201,108 @@ private:
|
||||
PERSISTENCE m_nPersistenceState;
|
||||
char pad_05C0[48];
|
||||
ServerDataBlock m_DataBlock;
|
||||
char pad_4A3D8[16];
|
||||
char pad_4A3D8[60];
|
||||
int m_LastMovementTick;
|
||||
#if defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
char pad_4A418[130];
|
||||
#endif
|
||||
char pad_4A49A[80];
|
||||
char pad_4A418[86];
|
||||
char pad_4A46E[80];
|
||||
};
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
static_assert(sizeof(CClient) == 0x4A440);
|
||||
#else
|
||||
static_assert(sizeof(CClient) == 0x4A4C0);
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Extended CClient class
|
||||
//-----------------------------------------------------------------------------
|
||||
// NOTE: since we interface directly with the engine, we cannot modify the
|
||||
// client structure. In order to add new data to each client instance, we
|
||||
// need to use this new class which we link directly to the corresponding
|
||||
// client instance through its UserID.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CClientExtended
|
||||
{
|
||||
friend class CClient;
|
||||
public:
|
||||
CClientExtended(void)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
inline void Reset(void)
|
||||
{
|
||||
m_flNetProcessingTimeMsecs = 0.0;
|
||||
m_flNetProcessTimeBase = 0.0;
|
||||
m_flStringCommandQuotaTimeStart = 0.0;
|
||||
m_nStringCommandQuotaCount = NULL;
|
||||
m_bInitialConVarsSet = false;
|
||||
}
|
||||
|
||||
public: // Inlines:
|
||||
inline void SetNetProcessingTimeMsecs(const double flStartTime, const double flCurrentTime)
|
||||
{ m_flNetProcessingTimeMsecs = (flCurrentTime * 1000) - (flStartTime * 1000); }
|
||||
inline double GetNetProcessingTimeMsecs(void) const { return m_flNetProcessingTimeMsecs; }
|
||||
|
||||
inline void SetNetProcessingTimeBase(const double flTime) { m_flNetProcessTimeBase = flTime; }
|
||||
inline double GetNetProcessingTimeBase(void) const { return m_flNetProcessTimeBase; }
|
||||
|
||||
inline void SetStringCommandQuotaTimeStart(const double flTime) { m_flStringCommandQuotaTimeStart = flTime; }
|
||||
inline double GetStringCommandQuotaTimeStart(void) const { return m_flStringCommandQuotaTimeStart; }
|
||||
|
||||
inline void SetStringCommandQuotaCount(const int iCount) { m_nStringCommandQuotaCount = iCount; }
|
||||
inline int GetStringCommandQuotaCount(void) const { return m_nStringCommandQuotaCount; }
|
||||
|
||||
private:
|
||||
// Measure how long this client's packets took to process.
|
||||
double m_flNetProcessingTimeMsecs;
|
||||
double m_flNetProcessTimeBase;
|
||||
|
||||
// The start time of the first stringcmd since reset.
|
||||
double m_flStringCommandQuotaTimeStart;
|
||||
int m_nStringCommandQuotaCount;
|
||||
|
||||
bool m_bInitialConVarsSet; // Whether or not the initial ConVar KV's are set
|
||||
};
|
||||
|
||||
/* ==== CBASECLIENT ===================================================================================================================================================== */
|
||||
inline CMemory p_CClient_Connect;
|
||||
inline bool(*v_CClient_Connect)(CClient* pClient, const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize);
|
||||
|
||||
inline CMemory p_CClient_Disconnect;
|
||||
inline bool(*v_CClient_Disconnect)(CClient* pClient, const Reputation_t nRepLvl, const char* szReason, ...);
|
||||
|
||||
inline CMemory p_CClient_Clear;
|
||||
inline void(*v_CClient_Clear)(CClient* pClient);
|
||||
|
||||
inline CMemory p_CClient_ActivatePlayer;
|
||||
inline void(*v_CClient_ActivatePlayer)(CClient* pClient);
|
||||
|
||||
inline CMemory p_CClient_ProcessStringCmd;
|
||||
inline bool(*v_CClient_ProcessStringCmd)(CClient* pClient, NET_StringCmd* pMsg);
|
||||
|
||||
inline CMemory p_CClient_SetSignonState;
|
||||
inline bool(*v_CClient_SetSignonState)(CClient* pClient, SIGNONSTATE signon);
|
||||
|
||||
inline CMemory p_CClient_SendNetMsgEx;
|
||||
inline bool(*v_CClient_SendNetMsgEx)(CClient* pClient, CNetMessage* pMsg, bool bLocal, bool bForceReliable, bool bVoice);
|
||||
|
||||
inline CMemory p_CClient_SendSnapshot;
|
||||
inline void*(*v_CClient_SendSnapshot)(CClient* pClient, CClientFrame* pFrame, int nTick, int nTickAck);
|
||||
inline bool(*CClient__Connect)(CClient* pClient, const char* szName, CNetChan* pNetChan, bool bFakePlayer, CUtlVector<NET_SetConVar::cvar_t>* conVars, char* szMessage, int nMessageSize);
|
||||
inline bool(*CClient__Disconnect)(CClient* pClient, const Reputation_t nRepLvl, const char* szReason, ...);
|
||||
inline void(*CClient__Clear)(CClient* pClient);
|
||||
inline void(*CClient__ActivatePlayer)(CClient* pClient);
|
||||
inline bool(*CClient__SetSignonState)(CClient* pClient, SIGNONSTATE signon);
|
||||
inline bool(*CClient__SendNetMsgEx)(CClient* pClient, CNetMessage* pMsg, bool bLocal, bool bForceReliable, bool bVoice);
|
||||
inline void*(*CClient__SendSnapshot)(CClient* pClient, CClientFrame* pFrame, int nTick, int nTickAck);
|
||||
inline void(*CClient__WriteDataBlock)(CClient* pClient, bf_write& buf);
|
||||
inline bool(*CClient__ProcessStringCmd)(CClient* pClient, NET_StringCmd* pMsg);
|
||||
inline bool(*CClient__ProcessSetConVar)(CClient* pClient, NET_SetConVar* pMsg);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VClient : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CClient::Connect", p_CClient_Connect.GetPtr());
|
||||
LogFunAdr("CClient::Disconnect", p_CClient_Disconnect.GetPtr());
|
||||
LogFunAdr("CClient::Clear", p_CClient_Clear.GetPtr());
|
||||
LogFunAdr("CClient::ActivatePlayer", p_CClient_ActivatePlayer.GetPtr());
|
||||
LogFunAdr("CClient::ProcessStringCmd", p_CClient_ProcessStringCmd.GetPtr());
|
||||
LogFunAdr("CClient::SetSignonState", p_CClient_SetSignonState.GetPtr());
|
||||
LogFunAdr("CClient::SendNetMsgEx", p_CClient_SendNetMsgEx.GetPtr());
|
||||
LogFunAdr("CClient::SendSnapshot", p_CClient_SendSnapshot.GetPtr());
|
||||
LogFunAdr("CClient::Connect", CClient__Connect);
|
||||
LogFunAdr("CClient::Disconnect", CClient__Disconnect);
|
||||
LogFunAdr("CClient::Clear", CClient__Clear);
|
||||
LogFunAdr("CClient::ActivatePlayer", CClient__ActivatePlayer);
|
||||
LogFunAdr("CClient::SetSignonState", CClient__SetSignonState);
|
||||
LogFunAdr("CClient::SendNetMsgEx", CClient__SendNetMsgEx);
|
||||
LogFunAdr("CClient::SendSnapshot", CClient__SendSnapshot);
|
||||
LogFunAdr("CClient::WriteDataBlock", CClient__WriteDataBlock);
|
||||
LogFunAdr("CClient::ProcessStringCmd", CClient__ProcessStringCmd);
|
||||
LogFunAdr("CClient::ProcessSetConVar", CClient__ProcessSetConVar);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_CClient_Connect = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 20 41 0F B6 E9");
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
p_CClient_Disconnect = g_GameDll.FindPatternSIMD("48 8B C4 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 49 8B F8 0F B6 F2");
|
||||
#else // !GAMEDLL_S0 || !GAMEDLL_S1 || !GAMEDLL_S2
|
||||
p_CClient_Disconnect = g_GameDll.FindPatternSIMD("48 8B C4 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 49 8B F8 8B F2");
|
||||
#endif
|
||||
p_CClient_Clear = g_GameDll.FindPatternSIMD("40 53 41 56 41 57 48 83 EC 20 48 8B D9 48 89 74");
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CClient_ActivatePlayer = g_GameDll.FindPatternSIMD("40 53 57 41 57 48 83 EC 30 8B 81 ?? ?? ?? ??");
|
||||
p_CClient_ProcessStringCmd = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 81 EC ?? ?? ?? ?? 49 8B D8");
|
||||
p_CClient_SendNetMsg = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 48 8B 05 ?? ?? ?? ?? 45 0F B6 F1");
|
||||
p_CClient_SendSnapshot = g_GameDll.FindPatternSIMD("44 89 44 24 ?? 48 89 4C 24 ?? 55 53 56 57 41 55");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CClient_ActivatePlayer = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 8B 81 B0 03 ?? ?? 48 8B D9 C6");
|
||||
p_CClient_ProcessStringCmd = g_GameDll.FindPatternSIMD("48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 7A 20");
|
||||
p_CClient_SendNetMsgEx = g_GameDll.FindPatternSIMD("40 53 55 56 57 41 56 48 83 EC 40 48 8B 05 ?? ?? ?? ??");
|
||||
p_CClient_SendSnapshot = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 41 55 41 56 41 57 48 8D 6C 24 ??");
|
||||
#endif // !GAMEDLL_S0 || !GAMEDLL_S1
|
||||
p_CClient_SetSignonState = g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 10 48 89 70 18 57 48 81 EC ?? ?? ?? ?? 0F 29 70 E8 8B F2");
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 20 41 0F B6 E9").GetPtr(CClient__Connect);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 49 8B F8 8B F2").GetPtr(CClient__Disconnect);
|
||||
g_GameDll.FindPatternSIMD("40 53 41 56 41 57 48 83 EC 20 48 8B D9 48 89 74").GetPtr(CClient__Clear);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 8B 81 B0 03 ?? ?? 48 8B D9 C6").GetPtr(CClient__ActivatePlayer);
|
||||
g_GameDll.FindPatternSIMD("40 53 55 56 57 41 56 48 83 EC 40 48 8B 05 ?? ?? ?? ??").GetPtr(CClient__SendNetMsgEx);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 41 55 41 56 41 57 48 8D 6C 24 ??").GetPtr(CClient__SendSnapshot);
|
||||
g_GameDll.FindPatternSIMD("40 53 57 48 83 EC 38 48 8B 05 ?? ?? ?? ??").GetPtr(CClient__WriteDataBlock);
|
||||
g_GameDll.FindPatternSIMD("48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 7A 20").GetPtr(CClient__ProcessStringCmd);
|
||||
|
||||
v_CClient_Connect = p_CClient_Connect.RCast<bool (*)(CClient*, const char*, void*, bool, void*, char*, int)>();
|
||||
v_CClient_Disconnect = p_CClient_Disconnect.RCast<bool (*)(CClient*, const Reputation_t, const char*, ...)>();
|
||||
v_CClient_Clear = p_CClient_Clear.RCast<void (*)(CClient*)>();
|
||||
v_CClient_ActivatePlayer = p_CClient_ActivatePlayer.RCast<void (*)(CClient* pClient)>();
|
||||
v_CClient_ProcessStringCmd = p_CClient_ProcessStringCmd.RCast<bool (*)(CClient*, NET_StringCmd*)>();
|
||||
v_CClient_SetSignonState = p_CClient_SetSignonState.RCast<bool (*)(CClient*, SIGNONSTATE)>();
|
||||
v_CClient_SendNetMsgEx = p_CClient_SendNetMsgEx.RCast<bool (*)(CClient*, CNetMessage*, bool, bool, bool)>();
|
||||
v_CClient_SendSnapshot = p_CClient_SendSnapshot.RCast<void* (*)(CClient*, CClientFrame*, int, int)>();
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 48 83 C2 20").GetPtr(CClient__ProcessSetConVar);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 10 48 89 70 18 57 48 81 EC ?? ?? ?? ?? 0F 29 70 E8 8B F2").GetPtr(CClient__SetSignonState);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -9,13 +9,20 @@
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "core/stdafx.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "tier0/frametask.h"
|
||||
#include "engine/common.h"
|
||||
#include "engine/host.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/server.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "clientstate.h"
|
||||
#include "common/callback.h"
|
||||
#include "cdll_engine_int.h"
|
||||
#include "vgui/vgui_baseui_interface.h"
|
||||
#include "rtech/playlists/playlists.h"
|
||||
#include <ebisusdk/EbisuSDK.h>
|
||||
#include <engine/cmd.h>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -58,7 +65,7 @@ float CClientState::GetClientTime() const
|
||||
{
|
||||
if (m_bClockCorrectionEnabled)
|
||||
{
|
||||
return (float)m_ClockDriftMgr.m_nSimulationTick * (*(float*)&interval_per_tick); // VERIFY DEREF
|
||||
return (float)m_ClockDriftMgr.m_nSimulationTick * g_pCommonHostState->interval_per_tick;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -128,12 +135,12 @@ void CClientState::VConnectionClosing(CClientState* thisptr, const char* szReaso
|
||||
|
||||
// Delay execution to the next frame; this is required to avoid a rare crash.
|
||||
// Cannot reload playlists while still disconnecting.
|
||||
g_TaskScheduler->Dispatch([]()
|
||||
g_TaskQueue.Dispatch([]()
|
||||
{
|
||||
// Reload the local playlist to override the cached
|
||||
// one from the server we got disconnected from.
|
||||
_DownloadPlaylists_f();
|
||||
KeyValues::InitPlaylists();
|
||||
v_Playlists_Download_f();
|
||||
Playlists_SDKInit();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@ -144,35 +151,258 @@ void CClientState::VConnectionClosing(CClientState* thisptr, const char* szReaso
|
||||
// no longer can process server ticks every frame unlike previous games.
|
||||
// Without this, the server CPU and frame time don't get updated to the client.
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::VProcessServerTick(CClientState* pClientState, SVC_ServerTick* pServerTick)
|
||||
bool CClientState::VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg)
|
||||
{
|
||||
if (pServerTick->m_NetTick.m_nCommandTick != -1)
|
||||
if (msg->m_NetTick.m_nCommandTick != -1)
|
||||
{
|
||||
return CClientState__ProcessServerTick(pClientState, pServerTick);
|
||||
// Updates statistics and updates clockdrift.
|
||||
return CClientState__ProcessServerTick(thisptr, msg);
|
||||
}
|
||||
else // Statistics only.
|
||||
{
|
||||
char* pShifted = reinterpret_cast<char*>(pClientState) - 0x10; // Shifted due to compiler optimizations.
|
||||
CClientState* pClient_Adj = reinterpret_cast<CClientState*>(pShifted);
|
||||
CClientState* const thisptr_ADJ = thisptr->GetShiftedBasePointer();
|
||||
|
||||
CNetChan* pChan = pClient_Adj->m_NetChannel;
|
||||
pChan->SetRemoteFramerate(pServerTick->m_NetTick.m_flHostFrameTime, pServerTick->m_NetTick.m_flHostFrameTimeStdDeviation);
|
||||
pChan->SetRemoteCPUStatistics(pServerTick->m_NetTick.m_nServerCPU);
|
||||
if (thisptr_ADJ->IsConnected())
|
||||
{
|
||||
CNetChan* const pChan = thisptr_ADJ->m_NetChannel;
|
||||
|
||||
pChan->SetRemoteFramerate(msg->m_NetTick.m_flHostFrameTime, msg->m_NetTick.m_flHostFrameTimeStdDeviation);
|
||||
pChan->SetRemoteCPUStatistics(msg->m_NetTick.m_nServerCPU);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void VClientState::Attach() const
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: processes string commands sent from server
|
||||
// Input : *thisptr -
|
||||
// *msg -
|
||||
// Output : true on success, false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::_ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg)
|
||||
{
|
||||
DetourAttach(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing);
|
||||
DetourAttach(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick);
|
||||
CClientState* const thisptr_ADJ = thisptr->GetShiftedBasePointer();
|
||||
|
||||
if (thisptr_ADJ->m_bRestrictServerCommands
|
||||
#ifndef CLIENT_DLL
|
||||
&& !g_pServer->IsActive()
|
||||
#endif // !CLIENT_DLL
|
||||
)
|
||||
{
|
||||
CCommand args;
|
||||
args.Tokenize(msg->cmd, cmd_source_t::kCommandSrcInvalid);
|
||||
|
||||
if (args.ArgC() > 0)
|
||||
{
|
||||
if (!Cbuf_AddTextWithMarkers(msg->cmd,
|
||||
eCmdExecutionMarker_Enable_FCVAR_SERVER_CAN_EXECUTE,
|
||||
eCmdExecutionMarker_Disable_FCVAR_SERVER_CAN_EXECUTE))
|
||||
{
|
||||
DevWarning(eDLL_T::CLIENT, "%s: No room for %i execution markers; command \"%s\" ignored\n",
|
||||
__FUNCTION__, 2, msg->cmd);
|
||||
}
|
||||
|
||||
void VClientState::Detach() const
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DetourDetach(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing);
|
||||
DetourDetach(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), msg->cmd, cmd_source_t::kCommandSrcCode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: create's string tables from string table data sent from server
|
||||
// Input : *thisptr -
|
||||
// *msg -
|
||||
// Output : true on success, false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::_ProcessCreateStringTable(CClientState* thisptr, SVC_CreateStringTable* msg)
|
||||
{
|
||||
CClientState* const cl = thisptr->GetShiftedBasePointer();
|
||||
|
||||
if (!cl->IsConnected())
|
||||
return false;
|
||||
|
||||
CNetworkStringTableContainer* const container = cl->m_StringTableContainer;
|
||||
|
||||
// Must have a string table container at this point!
|
||||
if (!container)
|
||||
{
|
||||
Assert(0);
|
||||
|
||||
COM_ExplainDisconnection(true, "String table container missing.\n");
|
||||
v_Host_Disconnect(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
container->AllowCreation(true);
|
||||
const ssize_t startbit = msg->m_DataIn.GetNumBitsRead();
|
||||
|
||||
CNetworkStringTable* const table = (CNetworkStringTable*)container->CreateStringTable(false, msg->m_szTableName,
|
||||
msg->m_nMaxEntries, msg->m_nUserDataSize, msg->m_nUserDataSizeBits, msg->m_nDictFlags);
|
||||
|
||||
table->SetTick(cl->GetServerTickCount());
|
||||
CClientState__HookClientStringTable(cl, msg->m_szTableName);
|
||||
|
||||
if (msg->m_bDataCompressed)
|
||||
{
|
||||
// TODO[ AMOS ]: check sizes before proceeding to decode
|
||||
// the string tables
|
||||
unsigned int msgUncompressedSize = msg->m_DataIn.ReadLong();
|
||||
unsigned int msgCompressedSize = msg->m_DataIn.ReadLong();
|
||||
|
||||
size_t uncompressedSize = msgUncompressedSize;
|
||||
size_t compressedSize = msgCompressedSize;
|
||||
|
||||
bool bSuccess = false;
|
||||
|
||||
// TODO[ AMOS ]: this could do better. The engine does UINT_MAX-3
|
||||
// which doesn't look very great. Clamp to more reasonable values
|
||||
// than UINT_MAX-3 or UINT_MAX/2? The largest string tables sent
|
||||
// are settings layout string tables which are roughly 256KiB
|
||||
// compressed with LZSS. perhaps clamp this to something like 16MiB?
|
||||
if (msg->m_DataIn.TotalBytesAvailable() > 0 &&
|
||||
msgCompressedSize <= (unsigned int)msg->m_DataIn.TotalBytesAvailable() &&
|
||||
msgCompressedSize < UINT_MAX / 2 && msgUncompressedSize < UINT_MAX / 2)
|
||||
{
|
||||
// allocate buffer for uncompressed data, align to 4 bytes boundary
|
||||
uint8_t* const uncompressedBuffer = new uint8_t[PAD_NUMBER(msgUncompressedSize, 4)];
|
||||
uint8_t* const compressedBuffer = new uint8_t[PAD_NUMBER(msgCompressedSize, 4)];
|
||||
|
||||
msg->m_DataIn.ReadBytes(compressedBuffer, msgCompressedSize);
|
||||
|
||||
// uncompress data
|
||||
bSuccess = NET_BufferToBufferDecompress(compressedBuffer, compressedSize, uncompressedBuffer, uncompressedSize);
|
||||
bSuccess &= (uncompressedSize == msgUncompressedSize);
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
bf_read data(uncompressedBuffer, (int)uncompressedSize);
|
||||
table->ParseUpdate(data, msg->m_nNumEntries);
|
||||
}
|
||||
|
||||
delete[] uncompressedBuffer;
|
||||
delete[] compressedBuffer;
|
||||
}
|
||||
|
||||
if (!bSuccess)
|
||||
{
|
||||
Assert(false);
|
||||
DevWarning(eDLL_T::CLIENT, "%s: Received malformed string table message!\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
table->ParseUpdate(msg->m_DataIn, msg->m_nNumEntries);
|
||||
}
|
||||
|
||||
container->AllowCreation(false);
|
||||
const ssize_t endbit = msg->m_DataIn.GetNumBitsRead();
|
||||
|
||||
return (endbit - startbit) == msg->m_nLength;
|
||||
}
|
||||
|
||||
static ConVar cl_onlineAuthEnable("cl_onlineAuthEnable", "1", FCVAR_RELEASE, "Enables the client-side online authentication system");
|
||||
|
||||
static ConVar cl_onlineAuthToken("cl_onlineAuthToken", "", FCVAR_HIDDEN | FCVAR_USERINFO | FCVAR_DONTRECORD | FCVAR_SERVER_CANNOT_QUERY | FCVAR_PLATFORM_SYSTEM, "The client's online authentication token");
|
||||
static ConVar cl_onlineAuthTokenSignature1("cl_onlineAuthTokenSignature1", "", FCVAR_HIDDEN | FCVAR_USERINFO | FCVAR_DONTRECORD | FCVAR_SERVER_CANNOT_QUERY | FCVAR_PLATFORM_SYSTEM, "The client's online authentication token signature", false, 0.f, false, 0.f, "Primary");
|
||||
static ConVar cl_onlineAuthTokenSignature2("cl_onlineAuthTokenSignature2", "", FCVAR_HIDDEN | FCVAR_USERINFO | FCVAR_DONTRECORD | FCVAR_SERVER_CANNOT_QUERY | FCVAR_PLATFORM_SYSTEM, "The client's online authentication token signature", false, 0.f, false, 0.f, "Secondary");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: get authentication token for current connection context
|
||||
// Input : *connectParams -
|
||||
// *reasonBuf -
|
||||
// reasonBufLen -
|
||||
// Output : true on success, false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::Authenticate(connectparams_t* connectParams, char* const reasonBuf, const size_t reasonBufLen) const
|
||||
{
|
||||
#define FORMAT_ERROR_REASON(fmt, ...) V_snprintf(reasonBuf, reasonBufLen, fmt, ##__VA_ARGS__);
|
||||
|
||||
string msToken; // token returned by the masterserver authorising the client to play online
|
||||
string message; // message returned by the masterserver about the result of the auth
|
||||
|
||||
// verify that the client is not lying about their account identity
|
||||
// code is immediately discarded upon verification
|
||||
|
||||
const bool ret = g_MasterServer.AuthForConnection(*g_NucleusID, connectParams->netAdr, g_OriginAuthCode, msToken, message);
|
||||
if (!ret)
|
||||
{
|
||||
FORMAT_ERROR_REASON("%s", message.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// get full token
|
||||
const char* token = msToken.c_str();
|
||||
|
||||
// get a pointer to the delimiter that begins the token's signature
|
||||
const char* tokenSignatureDelim = strrchr(token, '.');
|
||||
|
||||
if (!tokenSignatureDelim)
|
||||
{
|
||||
FORMAT_ERROR_REASON("Invalid token returned by MS");
|
||||
return false;
|
||||
}
|
||||
|
||||
// replace the delimiter with a null char so the first cvar only takes the header and payload data
|
||||
*(char*)tokenSignatureDelim = '\0';
|
||||
const size_t sigLength = strlen(tokenSignatureDelim) - 1;
|
||||
|
||||
cl_onlineAuthToken.SetValue(token);
|
||||
|
||||
if (sigLength > 0)
|
||||
{
|
||||
// get a pointer to the first part of the token signature to store in cl_onlineAuthTokenSignature1
|
||||
const char* tokenSignaturePart1 = tokenSignatureDelim + 1;
|
||||
|
||||
cl_onlineAuthTokenSignature1.SetValue(tokenSignaturePart1);
|
||||
|
||||
if (sigLength > 255)
|
||||
{
|
||||
// get a pointer to the rest of the token signature to store in cl_onlineAuthTokenSignature2
|
||||
const char* tokenSignaturePart2 = tokenSignaturePart1 + 255;
|
||||
|
||||
cl_onlineAuthTokenSignature2.SetValue(tokenSignaturePart2);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#undef REJECT_CONNECTION
|
||||
}
|
||||
|
||||
bool IsLocalHost(connectparams_t* connectParams)
|
||||
{
|
||||
return (strstr(connectParams->netAdr, "localhost") || strstr(connectParams->netAdr, "127.0.0.1"));
|
||||
}
|
||||
|
||||
void CClientState::VConnect(CClientState* thisptr, connectparams_t* connectParams)
|
||||
{
|
||||
if (cl_onlineAuthEnable.GetBool() && !IsLocalHost(connectParams))
|
||||
{
|
||||
char authFailReason[512];
|
||||
|
||||
if (!thisptr->Authenticate(connectParams, authFailReason, sizeof(authFailReason)))
|
||||
{
|
||||
COM_ExplainDisconnection(true, "Failed to authenticate for online play: %s", authFailReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CClientState__Connect(thisptr, connectParams);
|
||||
}
|
||||
|
||||
void VClientState::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing, bAttach);
|
||||
DetourSetup(&CClientState__ProcessStringCmd, &CClientState::_ProcessStringCmd, bAttach);
|
||||
DetourSetup(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick, bAttach);
|
||||
DetourSetup(&CClientState__ProcessCreateStringTable, &CClientState::_ProcessCreateStringTable, bAttach);
|
||||
DetourSetup(&CClientState__Connect, &CClientState::VConnect, bAttach);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -5,12 +5,23 @@
|
||||
#include "public/inetmsghandler.h"
|
||||
#include "public/isnapshotmgr.h"
|
||||
#include "engine/net_chan.h"
|
||||
#include "engine/networkstringtable.h"
|
||||
#include "engine/debugoverlay.h"
|
||||
#include "engine/clockdriftmgr.h"
|
||||
#include "engine/framesnapshot.h"
|
||||
#include "engine/packed_entity.h"
|
||||
#include "datablock_receiver.h"
|
||||
|
||||
struct connectparams_t
|
||||
{
|
||||
const char* netAdr;
|
||||
const char* netKey;
|
||||
int unkReconnect;
|
||||
int unk;
|
||||
bool challengeRequest;
|
||||
bool asSpectator_MAYBE;
|
||||
};
|
||||
|
||||
class CClientSnapshotManager : public IClientSnapshotManager
|
||||
{
|
||||
public:
|
||||
@ -26,7 +37,11 @@ class CClientState : CS_INetChannelHandler, IConnectionlessPacketHandler, IServe
|
||||
friend class ClientDataBlockReceiver;
|
||||
public: // Hook statics.
|
||||
static void VConnectionClosing(CClientState* thisptr, const char* szReason);
|
||||
static bool _ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg);
|
||||
static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg);
|
||||
static bool _ProcessCreateStringTable(CClientState* thisptr, SVC_CreateStringTable* msg);
|
||||
static void VConnect(CClientState* thisptr, connectparams_t* connectParams);
|
||||
|
||||
|
||||
public:
|
||||
bool IsPaused() const;
|
||||
@ -46,6 +61,21 @@ public:
|
||||
|
||||
float GetFrameTime(void) const;
|
||||
|
||||
bool Authenticate(connectparams_t* connectParams, char* const reasonBuf, const size_t reasonBufLen) const;
|
||||
|
||||
protected:
|
||||
FORCEINLINE CClientState* GetShiftedBasePointer(void)
|
||||
{
|
||||
// NOTE: you must check in the disassembler if the CClientState method
|
||||
// you detour is shifting the 'this' pointer with 16 bytes forward, if
|
||||
// so, you need to call this and use this pointer instead! The shifting
|
||||
// happens as part of a compiler optimization that truncated the vtable
|
||||
// pointers off so the 'this' pointer points directly to the class data
|
||||
char* const pShifted = reinterpret_cast<char*>(this) - 0x10;
|
||||
return reinterpret_cast<CClientState*>(pShifted);
|
||||
}
|
||||
|
||||
public:
|
||||
int m_Socket;
|
||||
int _padding_maybe;
|
||||
CNetChan* m_NetChannel;
|
||||
@ -84,9 +114,9 @@ public:
|
||||
int m_nPlayerSlot;
|
||||
char m_szLevelFileName[64];
|
||||
char m_szLevelBaseName[64];
|
||||
char field_1F0[64];
|
||||
char field_230[64];
|
||||
_BYTE m_szServerAddresString[128];
|
||||
char m_szLastLevelBaseName[64];
|
||||
char m_szSkyBoxBaseName[64];
|
||||
char m_szServerAddresString[128];
|
||||
int m_bInMpLobbyMenu;
|
||||
int m_nTeam;
|
||||
_DWORD m_nMaxClients;
|
||||
@ -97,22 +127,19 @@ public:
|
||||
_BYTE m_bSignonChallengeReceived;
|
||||
_DWORD challenge;
|
||||
netadr_t challengeAddr;
|
||||
_BYTE byte33C;
|
||||
bool m_bUseLocalSendTableFile;
|
||||
_QWORD m_pServerClasses;
|
||||
int m_nServerClasses;
|
||||
int m_nServerClassBits;
|
||||
__int64 m_StringTableContainer;
|
||||
CNetworkStringTableContainer* m_StringTableContainer;
|
||||
char m_PersistenceData[98304];
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
char pads0[8];
|
||||
#endif
|
||||
_BYTE m_bPersistenceBaselineRecvd;
|
||||
int m_nPersistenceBaselineEntries;
|
||||
int field_18350;
|
||||
bool m_bRestrictServerCommands;
|
||||
bool m_bRestrictClientCommands;
|
||||
char buffer_0x400[1024];
|
||||
ClientDataBlockReceiver blockReceiver;
|
||||
ClientDataBlockReceiver m_DataBlockReceiver;
|
||||
char client_requested_disconnect;
|
||||
char error_message[512];
|
||||
_BYTE gap18CA1[3];
|
||||
@ -148,9 +175,7 @@ public:
|
||||
__int64 qword18D20;
|
||||
int dword18D28;
|
||||
int dword18D2C;
|
||||
float field_18D30;
|
||||
float m_flUnk1;
|
||||
float m_flUnk2;
|
||||
Vector3D field_18D30;
|
||||
int dword18D3C;
|
||||
int dword18D40;
|
||||
char gap18D44[4];
|
||||
@ -160,7 +185,6 @@ public:
|
||||
int dword18D60;
|
||||
char gap18D64[4];
|
||||
__int64 qword18D68;
|
||||
char gap18D70[8];
|
||||
char buffer_47128[47128];
|
||||
char entitlements_bitfield[16];
|
||||
__int64 maybe_some_ll_stuff;
|
||||
@ -176,9 +200,7 @@ public:
|
||||
__int64 qword245F0;
|
||||
int dword245F8;
|
||||
char gap245FC[1024];
|
||||
int dword249EC;//249EC
|
||||
int dword249F0;
|
||||
char gap24A04[4];
|
||||
int dword249EC;
|
||||
__int64 m_pModelPrecacheTable;
|
||||
__int64 qword24A10;
|
||||
__int64 m_pInstanceBaselineTable;
|
||||
@ -189,11 +211,7 @@ public:
|
||||
char byte34A38;
|
||||
char field_34A39[7];
|
||||
};
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
static_assert(sizeof(CClientState) == 0x34A38);
|
||||
#else
|
||||
static_assert(sizeof(CClientState) == 0x34A30);
|
||||
#endif
|
||||
static_assert(sizeof(CClientState) == 0x34A20);
|
||||
|
||||
#ifndef DEDICATED
|
||||
extern CClientState* g_pClientState;
|
||||
@ -201,48 +219,42 @@ extern CClientState** g_pClientState_Shifted; // Shifted by 0x10 forward!
|
||||
#endif // DEDICATED
|
||||
|
||||
/* ==== CCLIENTSTATE ==================================================================================================================================================== */
|
||||
inline CMemory p_CClientState__RunFrame;
|
||||
inline void(*CClientState__RunFrame)(CClientState* thisptr);
|
||||
|
||||
inline CMemory p_CClientState__Disconnect;
|
||||
inline void(*CClientState__Connect)(CClientState* thisptr, connectparams_t* connectParams);
|
||||
inline void(*CClientState__Disconnect)(CClientState* thisptr, bool bSendTrackingContext);
|
||||
|
||||
inline CMemory p_CClientState__ConnectionClosing;
|
||||
inline void(*CClientState__ConnectionClosing)(CClientState* thisptr, const char* szReason);
|
||||
inline bool(*CClientState__HookClientStringTable)(CClientState* thisptr, const char* tableName);
|
||||
|
||||
inline CMemory p_CClientState__ProcessServerTick;
|
||||
inline bool(*CClientState__ProcessStringCmd)(CClientState* thisptr, NET_StringCmd* msg);
|
||||
inline bool(*CClientState__ProcessServerTick)(CClientState* thisptr, SVC_ServerTick* msg);
|
||||
inline bool(*CClientState__ProcessCreateStringTable)(CClientState* thisptr, SVC_CreateStringTable* msg);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VClientState : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CClientState::RunFrame", p_CClientState__RunFrame.GetPtr());
|
||||
LogFunAdr("CClientState::Disconnect", p_CClientState__Disconnect.GetPtr());
|
||||
LogFunAdr("CClientState::ConnectionClosing", p_CClientState__ConnectionClosing.GetPtr());
|
||||
LogFunAdr("CClientState::ProcessServerTick", p_CClientState__ProcessServerTick.GetPtr());
|
||||
LogVarAdr("g_ClientState", reinterpret_cast<uintptr_t>(g_pClientState));
|
||||
LogVarAdr("g_ClientState_Shifted", reinterpret_cast<uintptr_t>(g_pClientState_Shifted));
|
||||
LogFunAdr("CClientState::RunFrame", CClientState__RunFrame);
|
||||
LogFunAdr("CClientState::Connect", CClientState__Connect);
|
||||
LogFunAdr("CClientState::Disconnect", CClientState__Disconnect);
|
||||
LogFunAdr("CClientState::ConnectionClosing", CClientState__ConnectionClosing);
|
||||
LogFunAdr("CClientState::HookClientStringTable", CClientState__HookClientStringTable);
|
||||
LogFunAdr("CClientState::ProcessStringCmd", CClientState__ProcessStringCmd);
|
||||
LogFunAdr("CClientState::ProcessServerTick", CClientState__ProcessServerTick);
|
||||
LogFunAdr("CClientState::ProcessCreateStringTable", CClientState__ProcessCreateStringTable);
|
||||
LogVarAdr("g_ClientState", g_pClientState);
|
||||
LogVarAdr("g_ClientState_Shifted", g_pClientState_Shifted);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CClientState__RunFrame = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 57 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ??");
|
||||
p_CClientState__Disconnect = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 57 41 56 48 83 EC 30 0F B6 EA");
|
||||
p_CClientState__ConnectionClosing = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B DA 7E 6E");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CClientState__RunFrame = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 48 8B D9 7D 0B");
|
||||
p_CClientState__Disconnect = g_GameDll.FindPatternSIMD("40 56 57 41 54 41 55 41 57 48 83 EC 30 44 0F B6 FA");
|
||||
p_CClientState__ConnectionClosing = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B DA 0F 8E ?? ?? ?? ??");
|
||||
#endif
|
||||
p_CClientState__ProcessServerTick = g_GameDll.FindPatternSIMD("40 57 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B F9 7C 66");
|
||||
|
||||
CClientState__RunFrame = p_CClientState__RunFrame.RCast<void(*)(CClientState*)>();
|
||||
CClientState__Disconnect = p_CClientState__Disconnect.RCast<void(*)(CClientState*, bool)>();
|
||||
CClientState__ConnectionClosing = p_CClientState__ConnectionClosing.RCast<void(*)(CClientState*, const char*)>();
|
||||
CClientState__ProcessServerTick = p_CClientState__ProcessServerTick.RCast<bool(*)(CClientState*, SVC_ServerTick*)>();
|
||||
g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 48 8B D9 7D 0B").GetPtr(CClientState__RunFrame);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC ?? ?? ?? ?? 48 8B 32").GetPtr(CClientState__Connect);
|
||||
g_GameDll.FindPatternSIMD("40 56 57 41 54 41 55 41 57 48 83 EC 30 44 0F B6 FA").GetPtr(CClientState__Disconnect);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B DA 0F 8E ?? ?? ?? ??").GetPtr(CClientState__ConnectionClosing);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B D9 48 8B FA 48 8B 89 ?? ?? ?? ?? 48 85 C9 0F 84 ?? ?? ?? ??").GetPtr(CClientState__HookClientStringTable);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 80 B9 ?? ?? ?? ?? ?? 48 8B DA").GetPtr(CClientState__ProcessStringCmd);
|
||||
g_GameDll.FindPatternSIMD("40 57 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B F9 7C 66").GetPtr(CClientState__ProcessServerTick);
|
||||
g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 53 56 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ??").GetPtr(CClientState__ProcessCreateStringTable);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
@ -250,7 +262,6 @@ class VClientState : public IDetour
|
||||
g_pClientState_Shifted = reinterpret_cast<CClientState**>(reinterpret_cast<int64_t*>(g_pClientState)+1); // Shift by 8 bytes.
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -5,14 +5,9 @@
|
||||
//===========================================================================//
|
||||
#include "engine/client/clientstate.h"
|
||||
#include "datablock_receiver.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
ClientDataBlockReceiver::~ClientDataBlockReceiver()
|
||||
{
|
||||
v_ClientDataBlockReceiver__Destructor(this);
|
||||
}
|
||||
#include "common/proto_oob.h"
|
||||
#include "engine/common.h"
|
||||
#include "engine/host_cmd.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send an ack back to the server to let them know
|
||||
@ -20,5 +15,148 @@ ClientDataBlockReceiver::~ClientDataBlockReceiver()
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClientDataBlockReceiver::AcknowledgeTransmission()
|
||||
{
|
||||
v_ClientDataBlockReceiver__AcknowledgeTransmission(this);
|
||||
const CClientState* const cl = m_pClientState;
|
||||
|
||||
if (!cl)
|
||||
{
|
||||
Assert(0, "ClientDataBlockReceiver::AcknowledgeTransmission() called without a valid client handle!");
|
||||
return;
|
||||
}
|
||||
|
||||
const CNetChan* const chan = cl->m_NetChannel;
|
||||
|
||||
if (!chan)
|
||||
{
|
||||
Assert(0, "ClientDataBlockReceiver::AcknowledgeTransmission() called without a net channel!");
|
||||
return;
|
||||
}
|
||||
|
||||
char dataBuf[DATABLOCK_FRAGMENT_PACKET_SIZE];
|
||||
bf_write buf(&dataBuf, sizeof(dataBuf));
|
||||
|
||||
buf.WriteLong(CONNECTIONLESS_HEADER);
|
||||
buf.WriteByte(C2S_DATABLOCK_ACK);
|
||||
|
||||
buf.WriteShort(m_TransferId);
|
||||
buf.WriteShort(m_nTransferNr);
|
||||
|
||||
for (int i = m_nTotalBlocks; (i--) > 0;)
|
||||
{
|
||||
if (m_BlockStatus[i])
|
||||
{
|
||||
// ack the last blockNr we recv'd and processed
|
||||
buf.WriteShort(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// send the data block ack packet
|
||||
v_NET_SendPacket(NULL,
|
||||
chan->GetSocket(),
|
||||
chan->GetRemoteAddress(),
|
||||
buf.GetData(),
|
||||
buf.GetNumBytesWritten(),
|
||||
NULL, false, NULL, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: process the recv'd data block and reconstruct the fragmented data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ClientDataBlockReceiver::ProcessDataBlock(const double startTime, const short transferId, const int transferSize,
|
||||
const short transferNr, const short currentBlockId, const void* const blockBuffer, const int blockBufferBytes)
|
||||
{
|
||||
// should we process a new transfer?
|
||||
if (transferNr != m_nTransferNr)
|
||||
ResetBlockReceiver(transferNr);
|
||||
|
||||
m_bInitialized = true;
|
||||
|
||||
// make sure we always receive fragments in order
|
||||
if (transferId != m_TransferId || m_bCompletedRecv)
|
||||
return false;
|
||||
|
||||
// initialize the receiver if this is the firs fragment
|
||||
if (!m_bStartedRecv)
|
||||
StartBlockReceiver(transferSize, startTime);
|
||||
|
||||
// received more blocks than the total # expected?
|
||||
if (currentBlockId >= m_nTotalBlocks)
|
||||
return false;
|
||||
|
||||
// check if we have already copied the data block
|
||||
if (!m_BlockStatus[currentBlockId])
|
||||
{
|
||||
const int scratchBufferOffset = currentBlockId * MAX_DATABLOCK_FRAGMENT_SIZE;
|
||||
|
||||
if (blockBufferBytes + scratchBufferOffset <= m_nTransferSize)
|
||||
memcpy(m_pScratchBuffer + scratchBufferOffset + (sizeof(ClientDataBlockHeader_s) -1), blockBuffer, blockBufferBytes);
|
||||
|
||||
++m_nBlockAckTick;
|
||||
m_BlockStatus[currentBlockId] = true;
|
||||
}
|
||||
|
||||
// check if we have recv'd enough fragments to decode the data
|
||||
if (m_nBlockAckTick != m_nTotalBlocks)
|
||||
return true;
|
||||
|
||||
AcknowledgeTransmission();
|
||||
m_bCompletedRecv = true;
|
||||
|
||||
const ClientDataBlockHeader_s* const pHeader = reinterpret_cast<ClientDataBlockHeader_s*>(m_pScratchBuffer);
|
||||
|
||||
if (pHeader->isCompressed)
|
||||
{
|
||||
// NOTE: the engine's implementation of this function does NOT free
|
||||
// this buffer when a malformed/corrupt LZ4 packet is sent to the
|
||||
// receiver; wrapped buffer in unique_ptr to make sure it never leaks!
|
||||
std::unique_ptr<char> encodedDataBuf(new char[SNAPSHOT_SCRATCH_BUFFER_SIZE]);
|
||||
|
||||
char* const pEncodedDataBuf = encodedDataBuf.get();
|
||||
char* const dataLocation = m_pScratchBuffer + sizeof(ClientDataBlockHeader_s);
|
||||
|
||||
// copy the encoded data in the newly allocated buffer so we can decode back
|
||||
// into the data block buffer we copied the encoded data from
|
||||
const int compressedSize = m_nTransferSize -1;
|
||||
|
||||
memcpy(pEncodedDataBuf, dataLocation, compressedSize);
|
||||
const int numDecode = LZ4_decompress_safe(pEncodedDataBuf, dataLocation, compressedSize, SNAPSHOT_SCRATCH_BUFFER_SIZE);
|
||||
|
||||
if (numDecode < 0)
|
||||
{
|
||||
Assert(0);
|
||||
|
||||
COM_ExplainDisconnection(true, "LZ4 error decompressing data block from server.\n");
|
||||
v_Host_Disconnect(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nTransferSize = numDecode;
|
||||
}
|
||||
else
|
||||
{
|
||||
// truncate the byte that determines whether the data was compressed
|
||||
m_nTransferSize--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NOTE: detoured for 2 reasons:
|
||||
// 1: when a corrupt or malformed compress packet is sent, the code never freed
|
||||
// the temporary copy buffer it made to decode the data into the scratch buf
|
||||
// 2: exploring other compression algorithms for potential optimizations
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool HK_ProcessDataBlock(ClientDataBlockReceiver* receiver, const double startTime,
|
||||
const short transferId, const int transferSize, const short transferNr,
|
||||
const short currentBlockId, const void* const blockBuffer, const int blockBufferBytes)
|
||||
{
|
||||
return receiver->ProcessDataBlock(startTime, transferId, transferSize, transferNr,
|
||||
currentBlockId, blockBuffer, blockBufferBytes);
|
||||
}
|
||||
|
||||
void VClientDataBlockReceiver::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&ClientDataBlockReceiver__ProcessDataBlock, HK_ProcessDataBlock);
|
||||
}
|
||||
|
@ -1,60 +1,55 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: client side data block receiver
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef DATABLOCK_RECEIVER_H
|
||||
#define DATABLOCK_RECEIVER_H
|
||||
#include "idatablock.h"
|
||||
#include "engine/shared/datablock.h"
|
||||
|
||||
class CClientState;
|
||||
|
||||
class ClientDataBlockReceiver : public NetDataBlockReceiver
|
||||
{
|
||||
friend class CClientState;
|
||||
public:
|
||||
virtual ~ClientDataBlockReceiver();
|
||||
virtual void AcknowledgeTransmission() override;
|
||||
|
||||
protected:
|
||||
CClientState* m_pClientState;
|
||||
bool m_bStartedRecv;
|
||||
bool m_bCompletedRecv;
|
||||
bool byte12;
|
||||
short m_TransferId;
|
||||
short m_Counter;
|
||||
bool m_bInitialized;
|
||||
int m_nTransferSize;
|
||||
int m_nTotalBlocks;
|
||||
int m_nBlockAckTick;
|
||||
double m_flStartTime;
|
||||
bool m_BlockStatus[DATABLOCK_STATUS_SIZE];
|
||||
void* m_pBigBuffer;
|
||||
bool ProcessDataBlock(const double startTime, const short transferId, const int transferSize,
|
||||
const short counter, const short currentBlockId, const void* const blockBuffer, const int blockBufferBytes);
|
||||
};
|
||||
|
||||
inline CMemory p_ClientDataBlockReceiver__Destructor;
|
||||
inline void*(*v_ClientDataBlockReceiver__Destructor)(ClientDataBlockReceiver* thisptr);
|
||||
struct ClientDataBlockHeader_s
|
||||
{
|
||||
char reserved[3]; // unused in retail
|
||||
bool isCompressed;
|
||||
};
|
||||
|
||||
inline CMemory p_ClientDataBlockReceiver__AcknowledgeTransmission;
|
||||
inline void*(*v_ClientDataBlockReceiver__AcknowledgeTransmission)(ClientDataBlockReceiver* thisptr);
|
||||
// virtual methods
|
||||
inline void*(*ClientDataBlockReceiver__AcknowledgeTransmission)(ClientDataBlockReceiver* thisptr);
|
||||
|
||||
// non-virtual methods
|
||||
inline bool (*ClientDataBlockReceiver__ProcessDataBlock)(ClientDataBlockReceiver* thisptr, const double time,
|
||||
const short transferId, const int transferSize, const short counter, const short currentBlockId,
|
||||
const void* const blockBuffer, const int blockBufferBytes);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VClientDataBlockReceiver : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("ClientDataBlockReceiver::~ClientDataBlockReceiver", p_ClientDataBlockReceiver__Destructor.GetPtr());
|
||||
LogFunAdr("ClientDataBlockReceiver::AcknowledgeTransmission", p_ClientDataBlockReceiver__AcknowledgeTransmission.GetPtr());
|
||||
LogFunAdr("ClientDataBlockReceiver::AcknowledgeTransmission", ClientDataBlockReceiver__AcknowledgeTransmission);
|
||||
LogFunAdr("ClientDataBlockReceiver::ProcessDataBlock", ClientDataBlockReceiver__ProcessDataBlock);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_ClientDataBlockReceiver__Destructor = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 8B DA 48 8B F9 E8 ?? ?? ?? ?? F6 C3 01 74"
|
||||
" 0D BA ?? ?? ?? ?? 48 8B CF E8 ?? ?? ?? ?? 48 8B C7 48 8B 5C 24 ?? 48 83 C4 20 5F C3 CC CC CC CC CC CC CC CC CC CC CC CC 48 89 5C 24"
|
||||
" ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 05 ?? ?? ?? ?? C6 41 12 00");
|
||||
v_ClientDataBlockReceiver__Destructor = p_ClientDataBlockReceiver__Destructor.RCast<void* (*)(ClientDataBlockReceiver*)>();
|
||||
g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 4C 8B 51 08").GetPtr(ClientDataBlockReceiver__AcknowledgeTransmission);
|
||||
|
||||
p_ClientDataBlockReceiver__AcknowledgeTransmission = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 4C 8B 51 08");
|
||||
v_ClientDataBlockReceiver__AcknowledgeTransmission = p_ClientDataBlockReceiver__AcknowledgeTransmission.RCast<void* (*)(ClientDataBlockReceiver*)>();
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 0F B7 44 24 ??")
|
||||
.GetPtr(ClientDataBlockReceiver__ProcessDataBlock);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
//=============================================================================//
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/cmd.h"
|
||||
#include "clientstate.h"
|
||||
#include "vengineclient_impl.h"
|
||||
|
||||
@ -55,10 +56,43 @@ bool CEngineClient::GetRestrictClientCommands() const
|
||||
//---------------------------------------------------------------------------------
|
||||
int CEngineClient::GetLocalPlayer()
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
const static int index = 35;
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
const static int index = 36;
|
||||
#endif
|
||||
return CallVFunc<int>(index, this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: execute client command
|
||||
// Input : *thisptr -
|
||||
// *szCmdString -
|
||||
// Output :
|
||||
//---------------------------------------------------------------------------------
|
||||
void CEngineClient::_ClientCmd(CEngineClient* thisptr, const char* const szCmdString)
|
||||
{
|
||||
const bool restrictClientCommands = g_pClientState->m_bRestrictClientCommands;
|
||||
const int numMarkers = 2;
|
||||
|
||||
if (restrictClientCommands && !Cbuf_HasRoomForExecutionMarkers(numMarkers))
|
||||
{
|
||||
DevWarning(eDLL_T::CLIENT, "%s: No room for %i execution markers; command \"%s\" ignored\n",
|
||||
__FUNCTION__, numMarkers, szCmdString);
|
||||
return;
|
||||
}
|
||||
|
||||
if (restrictClientCommands)
|
||||
{
|
||||
Cbuf_AddExecutionMarker(Cbuf_GetCurrentPlayer(), eCmdExecutionMarker_Enable_FCVAR_CLIENTCMD_CAN_EXECUTE);
|
||||
}
|
||||
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), szCmdString, cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "\n", cmd_source_t::kCommandSrcCode);
|
||||
|
||||
if (restrictClientCommands)
|
||||
{
|
||||
Cbuf_AddExecutionMarker(Cbuf_GetCurrentPlayer(), eCmdExecutionMarker_Disable_FCVAR_CLIENTCMD_CAN_EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
void HVEngineClient::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&CEngineClient__ClientCmd, &CEngineClient::_ClientCmd, bAttach);
|
||||
}
|
||||
|
@ -8,10 +8,15 @@ public:
|
||||
void SetRestrictClientCommands(bool bRestrict);
|
||||
bool GetRestrictClientCommands() const;
|
||||
int GetLocalPlayer(); // Local player index.
|
||||
|
||||
// Hook statics:
|
||||
static void _ClientCmd(CEngineClient* thisptr, const char* const szCmdString);
|
||||
};
|
||||
|
||||
/* ==== CVENGINECLIENT ================================================================================================================================================== */
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline void(*CEngineClient__ClientCmd)(CEngineClient* thisptr, const char* const szCmdString);
|
||||
|
||||
inline CMemory g_pEngineClientVFTable = nullptr;
|
||||
inline CEngineClient* g_pEngineClient = nullptr;
|
||||
|
||||
@ -20,16 +25,19 @@ class HVEngineClient : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogConAdr("CEngineClient::`vftable'", g_pEngineClientVFTable.GetPtr());
|
||||
LogConAdr("CEngineClient::`vftable'", (void*)g_pEngineClientVFTable.GetPtr());
|
||||
LogFunAdr("CEngineClient::ClientCmd", CEngineClient__ClientCmd);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 80 3D ?? ?? ?? ?? ?? 48 8B DA 74 0C").GetPtr(CEngineClient__ClientCmd);
|
||||
}
|
||||
virtual void GetFun(void) const { }
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const
|
||||
{
|
||||
g_pEngineClientVFTable = g_GameDll.GetVirtualMethodTable(".?AVCEngineClient@@");
|
||||
g_pEngineClient = g_pEngineClientVFTable.RCast<CEngineClient*>();
|
||||
}
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,13 +1,69 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cmd.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "tier1/commandbuffer.h"
|
||||
#include "engine/cmd.h"
|
||||
|
||||
CCommandBuffer** s_pCommandBuffer = nullptr; // array size = ECommandTarget_t::CBUF_COUNT.
|
||||
LPCRITICAL_SECTION s_pCommandBufferMutex = nullptr;
|
||||
|
||||
//=============================================================================
|
||||
// List of execution markers
|
||||
//=============================================================================
|
||||
CUtlVector<int>* g_pExecutionMarkers = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if there's room left for execution markers
|
||||
// Input : cExecutionMarkers -
|
||||
// Output : true if there's room for execution markers, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Cbuf_HasRoomForExecutionMarkers(const int cExecutionMarkers)
|
||||
{
|
||||
return (g_pExecutionMarkers->Count() + cExecutionMarkers) < MAX_EXECUTION_MARKERS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds command text at the end of the command buffer with execution markers
|
||||
// Input : *pText -
|
||||
// markerLeft -
|
||||
// markerRight -
|
||||
// Output : true if there's room for execution markers, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Cbuf_AddTextWithMarkers(const char* const pText, const ECmdExecutionMarker markerLeft, const ECmdExecutionMarker markerRight)
|
||||
{
|
||||
if (Cbuf_HasRoomForExecutionMarkers(2))
|
||||
{
|
||||
Cbuf_AddExecutionMarker(Cbuf_GetCurrentPlayer(), markerLeft);
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), pText, cmd_source_t::kCommandSrcCode);
|
||||
Cbuf_AddExecutionMarker(Cbuf_GetCurrentPlayer(), markerRight);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds command text at the end of the buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
//void Cbuf_AddText(ECommandTarget_t eTarget, const char* pText, int nTickDelay)
|
||||
//{
|
||||
// LOCK_COMMAND_BUFFER();
|
||||
// if (!s_pCommandBuffer[(int)eTarget]->AddText(pText, nTickDelay, cmd_source_t::kCommandSrcInvalid))
|
||||
// {
|
||||
// Error(eDLL_T::ENGINE, NO_ERROR, "%s: buffer overflow\n", __FUNCTION__);
|
||||
// }
|
||||
//}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sends the entire command line over to the server
|
||||
// Input : *args -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef DEDICATED
|
||||
ConVar cl_quota_stringCmdsPerSecond("cl_quota_stringCmdsPerSecond", "16", FCVAR_RELEASE, "How many string commands per second user is allowed to submit, 0 to allow all submissions.", true, 0.f, false, 0.f);
|
||||
#endif // DEDICATED
|
||||
|
||||
bool Cmd_ForwardToServer(const CCommand* args)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
@ -19,8 +75,8 @@ bool Cmd_ForwardToServer(const CCommand* args)
|
||||
if (args->ArgC() == 0)
|
||||
return false;
|
||||
|
||||
double flStartTime = Plat_FloatTime();
|
||||
int nCmdQuotaLimit = cl_quota_stringCmdsPerSecond->GetInt();
|
||||
const double flStartTime = Plat_FloatTime();
|
||||
const int nCmdQuotaLimit = cl_quota_stringCmdsPerSecond.GetInt();
|
||||
const char* pszCmdString = nullptr;
|
||||
|
||||
// Special case: "cmd whatever args..." is forwarded as "whatever args...";
|
||||
@ -49,16 +105,13 @@ bool Cmd_ForwardToServer(const CCommand* args)
|
||||
}
|
||||
return v_Cmd_ForwardToServer(args);
|
||||
#else // !DEDICATED
|
||||
Assert(0);
|
||||
return false; // Client only.
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VCmd::Attach() const
|
||||
void VCmd::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_Cmd_ForwardToServer, &Cmd_ForwardToServer);
|
||||
}
|
||||
void VCmd::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_Cmd_ForwardToServer, &Cmd_ForwardToServer);
|
||||
DetourSetup(&v_Cmd_ForwardToServer, &Cmd_ForwardToServer, bAttach);
|
||||
}
|
||||
|
@ -1,5 +1,17 @@
|
||||
#ifndef CMD_H
|
||||
#define CMD_H
|
||||
#include "tier1/commandbuffer.h"
|
||||
|
||||
#define MAX_EXECUTION_MARKERS 2048
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eCmdExecutionMarker_Enable_FCVAR_SERVER_CAN_EXECUTE = 'a',
|
||||
eCmdExecutionMarker_Disable_FCVAR_SERVER_CAN_EXECUTE = 'b',
|
||||
|
||||
eCmdExecutionMarker_Enable_FCVAR_CLIENTCMD_CAN_EXECUTE = 'c',
|
||||
eCmdExecutionMarker_Disable_FCVAR_CLIENTCMD_CAN_EXECUTE = 'd'
|
||||
} ECmdExecutionMarker;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns current player calling this function
|
||||
@ -11,46 +23,53 @@ FORCEINLINE ECommandTarget_t Cbuf_GetCurrentPlayer(void)
|
||||
return ECommandTarget_t::CBUF_FIRST_PLAYER;
|
||||
}
|
||||
|
||||
extern bool Cbuf_HasRoomForExecutionMarkers(const int cExecutionMarkers);
|
||||
extern bool Cbuf_AddTextWithMarkers(const char* text, const ECmdExecutionMarker markerLeft, const ECmdExecutionMarker markerRight);
|
||||
|
||||
/* ==== COMMAND_BUFFER ================================================================================================================================================== */
|
||||
inline CMemory p_Cbuf_AddText;
|
||||
inline void(*Cbuf_AddText)(ECommandTarget_t eTarget, const char* pText, cmd_source_t cmdSource);
|
||||
|
||||
inline CMemory p_Cbuf_Execute;
|
||||
inline void(*Cbuf_AddExecutionMarker)(ECommandTarget_t target, ECmdExecutionMarker marker);
|
||||
inline void(*Cbuf_Execute)(void);
|
||||
|
||||
inline CMemory p_Cmd_Dispatch;
|
||||
inline void(*v_Cmd_Dispatch)(ECommandTarget_t eTarget, const ConCommandBase* pCmdBase, const CCommand* pCommand, bool bCallBackupCallback);
|
||||
|
||||
inline CMemory p_Cmd_ForwardToServer;
|
||||
inline bool(*v_Cmd_ForwardToServer)(const CCommand* pCommand);
|
||||
|
||||
extern CCommandBuffer** s_pCommandBuffer;
|
||||
extern LPCRITICAL_SECTION s_pCommandBufferMutex;
|
||||
|
||||
extern CUtlVector<int>* g_pExecutionMarkers;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCmd : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("Cbuf_AddText", p_Cbuf_AddText.GetPtr());
|
||||
LogFunAdr("Cbuf_Execute", p_Cbuf_Execute.GetPtr());
|
||||
LogFunAdr("Cmd_Dispatch", p_Cmd_Dispatch.GetPtr());
|
||||
LogFunAdr("Cmd_ForwardToServer", p_Cmd_ForwardToServer.GetPtr());
|
||||
LogFunAdr("Cbuf_AddText", Cbuf_AddText);
|
||||
LogFunAdr("Cbuf_AddExecutionMarker", Cbuf_AddExecutionMarker);
|
||||
LogFunAdr("Cbuf_Execute", Cbuf_Execute);
|
||||
LogFunAdr("Cmd_Dispatch", v_Cmd_Dispatch);
|
||||
LogFunAdr("Cmd_ForwardToServer", v_Cmd_ForwardToServer);
|
||||
LogVarAdr("s_CommandBuffer", s_pCommandBuffer);
|
||||
LogVarAdr("s_CommandBufferMutex", s_pCommandBufferMutex);
|
||||
LogVarAdr("g_ExecutionMarkers", g_pExecutionMarkers);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_Cbuf_AddText = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??");
|
||||
p_Cbuf_Execute = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??");
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??").GetPtr(Cbuf_AddText);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 05 ?? ?? ?? ??").GetPtr(Cbuf_AddExecutionMarker);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??").GetPtr(Cbuf_Execute);
|
||||
|
||||
p_Cmd_Dispatch = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 8B ?? 0C 49 FF C7").FollowNearCallSelf();
|
||||
p_Cmd_ForwardToServer = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04");
|
||||
|
||||
Cbuf_AddText = p_Cbuf_AddText.RCast<void (*)(ECommandTarget_t, const char*, cmd_source_t)>(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??*/
|
||||
Cbuf_Execute = p_Cbuf_Execute.RCast<void (*)(void)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??*/
|
||||
v_Cmd_Dispatch = p_Cmd_Dispatch.RCast<void (*)(ECommandTarget_t, const ConCommandBase*, const CCommand*, bool)>();
|
||||
v_Cmd_ForwardToServer = p_Cmd_ForwardToServer.RCast<bool (*)(const CCommand*)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04*/
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 8B ?? 0C 49 FF C7").FollowNearCallSelf().GetPtr(v_Cmd_Dispatch);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04").GetPtr(v_Cmd_ForwardToServer);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
s_pCommandBuffer = CMemory(Cbuf_AddText).FindPattern("48 8D 05").ResolveRelativeAddressSelf(3, 7).RCast<CCommandBuffer**>();
|
||||
s_pCommandBufferMutex = CMemory(Cbuf_AddText).FindPattern("48 8D 0D").ResolveRelativeAddressSelf(3, 7).RCast<LPCRITICAL_SECTION>();
|
||||
g_pExecutionMarkers = CMemory(Cbuf_AddExecutionMarker).FindPattern("48 8B 0D").ResolveRelativeAddressSelf(3, 7).RCast<CUtlVector<int>*>();
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
|
||||
#endif // CMD_H
|
||||
|
@ -8,37 +8,110 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier0/memstd.h"
|
||||
#include "tier0/jobthread.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
#include "tier2/fileutils.h"
|
||||
#include "engine/sys_dll2.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "rtech/rtech_game.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
|
||||
#include "rtech/pak/pakstate.h"
|
||||
#include "rtech/pak/pakparse.h"
|
||||
#include "rtech/pak/paktools.h"
|
||||
#include "rtech/pak/pakstream.h"
|
||||
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "datacache/mdlcache.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#ifndef DEDICATED
|
||||
#include "client/clientstate.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
vector<string> g_InstalledMaps;
|
||||
string s_LevelName;
|
||||
CUtlVector<CUtlString> g_InstalledMaps;
|
||||
CFmtStrN<MAX_MAP_NAME> s_CurrentLevelName;
|
||||
|
||||
std::regex s_ArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" };
|
||||
static std::regex s_ArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" };
|
||||
|
||||
bool s_bLevelResourceInitialized = false;
|
||||
bool s_bBasePaksInitialized = false;
|
||||
KeyValues* s_pLevelSetKV = nullptr;
|
||||
static CustomPakData_t s_customPakData;
|
||||
static KeyValues* s_pLevelSetKV = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: load a custom pak and add it to the list
|
||||
//-----------------------------------------------------------------------------
|
||||
PakHandle_t CustomPakData_t::LoadAndAddPak(const char* const pakFile)
|
||||
{
|
||||
if (numHandles >= MAX_CUSTOM_PAKS)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Tried to load pak '%s', but already reached the SDK's limit of %d!\n", pakFile, MAX_CUSTOM_PAKS);
|
||||
return INVALID_PAK_HANDLE;
|
||||
}
|
||||
|
||||
const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
// failure, don't add and return the invalid handle.
|
||||
if (pakId == INVALID_PAK_HANDLE)
|
||||
return pakId;
|
||||
|
||||
handles[numHandles++] = pakId;
|
||||
return pakId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unloads all active custom pak handles
|
||||
//-----------------------------------------------------------------------------
|
||||
void CustomPakData_t::UnloadAndRemoveAll()
|
||||
{
|
||||
for (; numHandles-1 >= CustomPakData_t::PAK_TYPE_COUNT; numHandles--)
|
||||
{
|
||||
const PakHandle_t pakId = handles[numHandles-1];
|
||||
|
||||
if (pakId == INVALID_PAK_HANDLE)
|
||||
{
|
||||
assert(0); // invalid handles should not be inserted
|
||||
return;
|
||||
}
|
||||
|
||||
g_pakLoadApi->UnloadAsync(pakId);
|
||||
handles[numHandles-1] = INVALID_PAK_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads the base SDK pak file by type
|
||||
//-----------------------------------------------------------------------------
|
||||
PakHandle_t CustomPakData_t::LoadBasePak(const char* const pakFile, const EPakType type)
|
||||
{
|
||||
const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
// the file is most likely missing
|
||||
assert(pakId != INVALID_PAK_HANDLE);
|
||||
handles[type] = pakId;
|
||||
|
||||
return pakId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unload the SDK base pak file by type
|
||||
//-----------------------------------------------------------------------------
|
||||
void CustomPakData_t::UnloadBasePak(const EPakType type)
|
||||
{
|
||||
const PakHandle_t pakId = handles[type];
|
||||
|
||||
// only unload if it was actually successfully loaded
|
||||
if (pakId != INVALID_PAK_HANDLE)
|
||||
{
|
||||
g_pakLoadApi->UnloadAsync(pakId);
|
||||
handles[type] = INVALID_PAK_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if level has changed
|
||||
// Input : *pszLevelName -
|
||||
// Output : true if level name deviates from previous level
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Mod_LevelHasChanged(const char* pszLevelName)
|
||||
bool Mod_LevelHasChanged(const char* const pszLevelName)
|
||||
{
|
||||
return (s_LevelName.compare(pszLevelName) != 0);
|
||||
return (V_strcmp(pszLevelName, s_CurrentLevelName.String()) != NULL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -52,7 +125,7 @@ void Mod_GetAllInstalledMaps()
|
||||
std::cmatch regexMatches;
|
||||
std::lock_guard<std::mutex> l(g_InstalledMapsMutex);
|
||||
|
||||
g_InstalledMaps.clear(); // Clear current list.
|
||||
g_InstalledMaps.Purge(); // Clear current list.
|
||||
|
||||
FOR_EACH_VEC(fileList, i)
|
||||
{
|
||||
@ -67,201 +140,148 @@ void Mod_GetAllInstalledMaps()
|
||||
|
||||
if (!regexMatches.empty())
|
||||
{
|
||||
if (regexMatches[1].str().compare("frontend") == 0)
|
||||
const std::sub_match<const char*>& match = regexMatches[1];
|
||||
|
||||
if (match.compare("frontend") == 0)
|
||||
continue; // Frontend contains no BSP's.
|
||||
|
||||
else if (regexMatches[1].str().compare("mp_common") == 0)
|
||||
else if (match.compare("mp_common") == 0)
|
||||
{
|
||||
if (std::find(g_InstalledMaps.begin(), g_InstalledMaps.end(), "mp_lobby") == g_InstalledMaps.end())
|
||||
g_InstalledMaps.push_back("mp_lobby");
|
||||
if (!g_InstalledMaps.HasElement("mp_lobby"))
|
||||
g_InstalledMaps.AddToTail("mp_lobby");
|
||||
|
||||
continue; // Common contains mp_lobby.
|
||||
}
|
||||
|
||||
if (std::find(g_InstalledMaps.begin(), g_InstalledMaps.end(), regexMatches[1].str()) == g_InstalledMaps.end())
|
||||
g_InstalledMaps.push_back(regexMatches[1].str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the queued pak handles
|
||||
// Input : *a1 -
|
||||
// *a2 -
|
||||
// a3 -
|
||||
// Output : __int64
|
||||
//-----------------------------------------------------------------------------
|
||||
__int64 __fastcall Mod_GetQueuedPakHandle(char* a1, char* a2, __int64 a3)
|
||||
else
|
||||
{
|
||||
char v3; // al
|
||||
signed int v4; // er11
|
||||
__int64 v5; // r10
|
||||
char* v6; // r9
|
||||
signed __int64 v7; // rdx
|
||||
char v8; // al
|
||||
char* v10; // r8
|
||||
char* v11; // r8
|
||||
|
||||
v3 = *a2;
|
||||
v4 = 0;
|
||||
*a1 = *a2;
|
||||
v5 = 0i64;
|
||||
if (v3)
|
||||
{
|
||||
v6 = a1;
|
||||
v7 = a2 - a1;
|
||||
while (1)
|
||||
{
|
||||
++v5;
|
||||
++v6;
|
||||
if (v5 == a3)
|
||||
break;
|
||||
v8 = v6[v7];
|
||||
*v6 = v8;
|
||||
if (!v8)
|
||||
return v5;
|
||||
}
|
||||
*(v6 - 1) = 0;
|
||||
if (--v5)
|
||||
{
|
||||
v10 = &a1[v5 - 1];
|
||||
if ((*v10 & 0xC0) == 0x80)
|
||||
{
|
||||
do
|
||||
++v4;
|
||||
while ((v10[-v4] & 0xC0) == 0x80);
|
||||
}
|
||||
v11 = &v10[-v4];
|
||||
if (v4 != (signed int)((0xE5000000 >> (((unsigned __int8)*v11 >> 3) & 0x1E)) & 3))
|
||||
{
|
||||
*v11 = 0;
|
||||
v5 -= v4;
|
||||
const string mapName = match.str();
|
||||
if (!g_InstalledMaps.HasElement(mapName.c_str()))
|
||||
g_InstalledMaps.AddToTail(mapName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return v5;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: processes queued pak files
|
||||
//-----------------------------------------------------------------------------
|
||||
void Mod_ProcessPakQueue()
|
||||
void Mod_QueuedPakCacheFrame()
|
||||
{
|
||||
char v0; // bl
|
||||
char** v1; // r10
|
||||
__int64 i; // er9
|
||||
char* v3; // rcx
|
||||
signed __int64 v4; // r8
|
||||
int v5; // eax
|
||||
int v6; // edx
|
||||
__int64 v7; // eax
|
||||
__int64 v8; // rbp
|
||||
__int64 v9; // rsi
|
||||
char* v10; // rbx
|
||||
unsigned int v11; // ecx
|
||||
__int64 v12; // rax
|
||||
int v13; // edi
|
||||
char v14; // al
|
||||
char* v15; // rbx
|
||||
__int64 v16; // edi
|
||||
char* v17; // rsi
|
||||
char* v18; // rax
|
||||
int v19; // ecx
|
||||
int v20; // er8
|
||||
int v21; // ecx
|
||||
__int64 v22; // rdx
|
||||
__int64 v24{}; // rdx
|
||||
__int64 v25{}; // rcx
|
||||
|
||||
v0 = 0;
|
||||
#ifndef DEDICATED
|
||||
bool bUnconnected = !(*g_pClientState_Shifted)->IsConnected();
|
||||
#else // !DEDICATED
|
||||
bool bUnconnected = true; // Always true for dedicated.
|
||||
#endif
|
||||
|
||||
if (*(float*)&*dword_14B383420 == 1.0 && *qword_167ED7BB8 && bUnconnected)
|
||||
bool startFromFirst = false;
|
||||
|
||||
if (Pak_StreamingDownloadFinished() && Pak_GetNumStreamableAssets() && bUnconnected)
|
||||
{
|
||||
*byte_16709DDDF = 0;
|
||||
v0 = 1;
|
||||
*g_pPakPrecacheJobFinished = false;
|
||||
startFromFirst = true;
|
||||
}
|
||||
else if (*byte_16709DDDF)
|
||||
else if (*g_pPakPrecacheJobFinished)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (FileSystem()->ResetItemCache() && !*dword_1634F445C)
|
||||
|
||||
if (!FileSystem()->ResetItemCache() || *g_pNumPrecacheItemsMTVTF)
|
||||
{
|
||||
v1 = &*off_141874660;
|
||||
return;
|
||||
}
|
||||
|
||||
const char** pPakName = &g_commonPakData[0].basePakName;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 5; ++i)
|
||||
{
|
||||
if (*((_BYTE*)v1 - 268))
|
||||
if (*((_BYTE*)pPakName - 268))
|
||||
break;
|
||||
v3 = (char*)&*unk_141874555 + 280 * i;
|
||||
v4 = *v1 - v3;
|
||||
|
||||
const char* pakName = g_commonPakData[i].pakName;
|
||||
const int64_t v4 = *pPakName - pakName;
|
||||
|
||||
int v5;
|
||||
int v6;
|
||||
|
||||
do
|
||||
{
|
||||
v5 = (unsigned __int8)v3[v4];
|
||||
v6 = (unsigned __int8)*v3 - v5;
|
||||
v5 = (unsigned __int8)pakName[v4];
|
||||
v6 = (unsigned __int8)*pakName - v5;
|
||||
if (v6)
|
||||
break;
|
||||
++v3;
|
||||
|
||||
++pakName;
|
||||
} while (v5);
|
||||
|
||||
if (v6)
|
||||
break;
|
||||
v1 += 35;
|
||||
|
||||
pPakName += 35;
|
||||
}
|
||||
v7 = 0;
|
||||
if (!v0)
|
||||
v7 = i;
|
||||
v8 = v7;
|
||||
if (v7 <= 4i64)
|
||||
|
||||
int startIndex = 0;
|
||||
|
||||
if (!startFromFirst)
|
||||
startIndex = i; // start from last pre-cached
|
||||
|
||||
const int numToProcess = startIndex;
|
||||
|
||||
if (startIndex <= 4)
|
||||
{
|
||||
v9 = 4i64;
|
||||
v10 = (char*)&*unk_1418749B0;
|
||||
int numLeftToProcess = 4;
|
||||
CommonPakData_t* data = &g_commonPakData[4];
|
||||
|
||||
do
|
||||
{
|
||||
if (v10[5])
|
||||
if (*data->pakName)
|
||||
{
|
||||
v11 = *(_DWORD*)v10;
|
||||
v12 = *(_DWORD*)v10 & 0x1FF;
|
||||
v10[4] = 1;
|
||||
if (*((_DWORD*)&*g_pLoadedPakInfo + 46 * v12) == v11)
|
||||
PakLoadedInfo_t* const pakInfo = Pak_GetPakInfo(data->pakId);
|
||||
EPakStatus status;
|
||||
|
||||
// TODO: revisit this, this appears incorrect but also the way
|
||||
// respawn does this. it this always supposed to be true on
|
||||
// retail builds?
|
||||
bool keepLoaded = true;
|
||||
data->keepLoaded = true;
|
||||
|
||||
if (pakInfo->handle == data->pakId)
|
||||
{
|
||||
v13 = *((_DWORD*)&*g_pLoadedPakInfo + 46 * v12 + 1);
|
||||
v14 = v10[4];
|
||||
status = pakInfo->status;
|
||||
keepLoaded = data->keepLoaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
v13 = 14;
|
||||
v14 = 1;
|
||||
status = PAK_STATUS_INVALID_PAKHANDLE;
|
||||
keepLoaded = true;
|
||||
}
|
||||
if (!v14 || v13 == 9)
|
||||
|
||||
if (!keepLoaded || status == PAK_STATUS_LOADED)
|
||||
{
|
||||
// SDK pak files must be unloaded before the engine pak files,
|
||||
// as we reference assets within engine pak files.
|
||||
const RPakLoadedInfo_t* pLoadedPakInfo = g_pRTech->GetPakLoadedInfo(*(RPakHandle_t*)v10);
|
||||
if (pLoadedPakInfo)
|
||||
// as we use assets within engine pak files.
|
||||
switch (numLeftToProcess)
|
||||
{
|
||||
const char* pszLoadedPakName = pLoadedPakInfo->m_pszFileName;
|
||||
|
||||
if (strcmp(pszLoadedPakName, "common_mp.rpak") == 0 ||
|
||||
strcmp(pszLoadedPakName, "common_sp.rpak") == 0 ||
|
||||
strcmp(pszLoadedPakName, "common_pve.rpak") == 0)
|
||||
{
|
||||
const RPakLoadedInfo_t* pLoadedSdkPak = g_pRTech->GetPakLoadedInfo("common_sdk.rpak");
|
||||
|
||||
if (pLoadedSdkPak) // Only unload if sdk pak file is loaded.
|
||||
g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_nHandle);
|
||||
|
||||
}
|
||||
#ifndef DEDICATED
|
||||
else if (strcmp(pszLoadedPakName, "ui_mp.rpak") == 0)
|
||||
{
|
||||
const RPakLoadedInfo_t* pLoadedSdkPak = g_pRTech->GetPakLoadedInfo("ui_sdk.rpak");
|
||||
|
||||
if (pLoadedSdkPak) // Only unload if sdk pak file is loaded.
|
||||
g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_nHandle);
|
||||
}
|
||||
case CommonPakData_t::PAK_TYPE_UI_GM:
|
||||
s_customPakData.UnloadBasePak(CustomPakData_t::PAK_TYPE_UI_SDK);
|
||||
break;
|
||||
#endif // !DEDICATED
|
||||
|
||||
case CommonPakData_t::PAK_TYPE_COMMON:
|
||||
g_StudioMdlFallbackHandler.Clear();
|
||||
break;
|
||||
|
||||
case CommonPakData_t::PAK_TYPE_COMMON_GM:
|
||||
s_customPakData.UnloadBasePak(CustomPakData_t::PAK_TYPE_COMMON_SDK);
|
||||
break;
|
||||
|
||||
case CommonPakData_t::PAK_TYPE_LOBBY:
|
||||
s_customPakData.basePaksLoaded = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// The old gather props is set if a model couldn't be
|
||||
@ -269,14 +289,14 @@ void Mod_ProcessPakQueue()
|
||||
// enable the new implementation again and re-evaluate
|
||||
// on the next level load. If we load a missing/bad
|
||||
// model again, we toggle the old implementation as
|
||||
// the helper functions for this implementation have
|
||||
// been restored in the SDK, and modified to support
|
||||
// stubbing missing model assets. See the function
|
||||
// 'CMDLCache::GetErrorModel' for more information.
|
||||
if (old_gather_props->GetBool())
|
||||
old_gather_props->SetValue(false);
|
||||
// otherwise the fallback models won't render; the new
|
||||
// gather props solution does not attempt to obtain
|
||||
// studio hardware data on bad mdl handles. See
|
||||
// 'GatherStaticPropsSecondPass_PreInit()' for details.
|
||||
g_StudioMdlFallbackHandler.DisableLegacyGatherProps();
|
||||
|
||||
g_pakLoadApi->UnloadAsync(data->pakId);
|
||||
|
||||
g_pakLoadApi->UnloadPak(*(RPakHandle_t*)v10);
|
||||
Mod_UnloadPakFile(); // Unload mod pak files.
|
||||
|
||||
if (s_pLevelSetKV)
|
||||
@ -286,107 +306,133 @@ void Mod_ProcessPakQueue()
|
||||
s_pLevelSetKV = nullptr;
|
||||
}
|
||||
}
|
||||
if (v13 && (unsigned int)(v13 - 13) > 1)
|
||||
|
||||
if (status && (unsigned int)(status - 13) > 1)
|
||||
return;
|
||||
*((_WORD*)v10 + 2) = 0;
|
||||
*(_DWORD*)v10 = 0xFFFFFFFF;
|
||||
|
||||
data->keepLoaded = false;
|
||||
data->pakName[0] = '\0';
|
||||
|
||||
data->pakId = INVALID_PAK_HANDLE;
|
||||
}
|
||||
--v9;
|
||||
v10 -= 280;
|
||||
} while (v9 >= v8);
|
||||
}
|
||||
*byte_16709DDDF = 1;
|
||||
v15 = (char*)&*unk_141874550;
|
||||
v16 = 0;
|
||||
while (1)
|
||||
{
|
||||
v17 = (char*)&*unk_141874550 + 280 * v16 + 5;
|
||||
v18 = v17;
|
||||
do
|
||||
{
|
||||
v19 = (unsigned __int8)v18[*((_QWORD*)v15 + 34) - (_QWORD)v17];
|
||||
v20 = (unsigned __int8)*v18 - v19;
|
||||
if (v20)
|
||||
break;
|
||||
++v18;
|
||||
} while (v19);
|
||||
if (!v20)
|
||||
goto LABEL_37;
|
||||
Mod_GetQueuedPakHandle(v17, *((char**)v15 + 34), 260i64);
|
||||
if (v15[5])
|
||||
break;
|
||||
*(_DWORD*)v15 = 0xFFFFFFFF;
|
||||
LABEL_40:
|
||||
++v16;
|
||||
v15 += 280;
|
||||
if (v16 >= 5)
|
||||
{
|
||||
if (*byte_16709DDDF)
|
||||
{
|
||||
if (*g_pMTVFTaskItem)
|
||||
{
|
||||
if (!*(_BYTE*)(*g_pMTVFTaskItem + 4))
|
||||
{
|
||||
if (*qword_167ED7BC0 || WORD2(*g_pPakLoadJobID) != HIWORD(*g_pPakLoadJobID))
|
||||
{
|
||||
if (!JT_AcquireFifoLock(g_pPakFifoLock)
|
||||
&& !(unsigned __int8)sub_14045BAC0((__int64(__fastcall*)(__int64, _DWORD*, __int64, _QWORD*))g_pPakFifoLockWrapper, g_pPakFifoLock, -1i64, 0i64))
|
||||
{
|
||||
sub_14045A1D0((unsigned __int8(__fastcall*)(_QWORD))g_pPakFifoLockWrapper, g_pPakFifoLock, -1i64, 0i64, 0i64, 1);
|
||||
--numLeftToProcess;
|
||||
--data;
|
||||
} while (numLeftToProcess >= numToProcess);
|
||||
}
|
||||
|
||||
sub_140441220(v25, v24);
|
||||
*g_pPakPrecacheJobFinished = true;
|
||||
CommonPakData_t* commonData = g_commonPakData;
|
||||
|
||||
int it = 0;
|
||||
|
||||
char* name;
|
||||
char* nameIt;
|
||||
|
||||
while (true)
|
||||
{
|
||||
name = g_commonPakData[it].pakName;
|
||||
nameIt = name;
|
||||
char c;
|
||||
int v20;
|
||||
do
|
||||
{
|
||||
c = (unsigned __int8)nameIt[(unsigned __int64)(commonData->basePakName - (const char*)name)];
|
||||
v20 = (unsigned __int8)*nameIt - c;
|
||||
if (v20)
|
||||
break;
|
||||
|
||||
++nameIt;
|
||||
} while (c);
|
||||
|
||||
if (!v20)
|
||||
goto CHECK_FOR_FAILURE;
|
||||
|
||||
V_strncpy(name, commonData->basePakName, MAX_PATH);
|
||||
|
||||
if (*commonData->pakName)
|
||||
break;
|
||||
|
||||
commonData->pakId = INVALID_PAK_HANDLE;
|
||||
LOOP_AGAIN_OR_FINISH:
|
||||
|
||||
++it;
|
||||
++commonData;
|
||||
if (it >= 5)
|
||||
{
|
||||
if (*g_pPakPrecacheJobFinished)
|
||||
{
|
||||
__int64 pMTVFTaskItem = *g_pMTVFTaskItem;
|
||||
if (pMTVFTaskItem)
|
||||
{
|
||||
if (!*(_BYTE*)(pMTVFTaskItem + 4))
|
||||
{
|
||||
JobFifoLock_s* const pakFifoLock = &g_pakGlobals->fifoLock;
|
||||
|
||||
if (g_pakGlobals->hasPendingUnloadJobs || g_pakGlobals->loadedPakCount != g_pakGlobals->requestedPakCount)
|
||||
{
|
||||
if (!JT_AcquireFifoLockOrHelp(pakFifoLock)
|
||||
&& !JT_HelpWithJobTypes(g_pPakFifoLockWrapper, pakFifoLock, -1i64, 0i64))
|
||||
{
|
||||
JT_HelpWithJobTypesOrSleep(g_pPakFifoLockWrapper, pakFifoLock, -1i64, 0i64, 0i64, 1);
|
||||
}
|
||||
|
||||
Mod_UnloadPendingAndPrecacheRequestedPaks();
|
||||
|
||||
if (ThreadInMainThread())
|
||||
{
|
||||
if (*g_bPakFifoLockAcquired)
|
||||
{
|
||||
*g_bPakFifoLockAcquired = 0;
|
||||
JT_ReleaseFifoLock(g_pPakFifoLock);
|
||||
JT_ReleaseFifoLock(pakFifoLock);
|
||||
}
|
||||
}
|
||||
JT_ReleaseFifoLock(g_pPakFifoLock);
|
||||
|
||||
JT_ReleaseFifoLock(pakFifoLock);
|
||||
|
||||
pMTVFTaskItem = *g_pMTVFTaskItem;
|
||||
}
|
||||
|
||||
FileSystem()->ResetItemCacheSize(256);
|
||||
FileSystem()->PrecacheTaskItem(*g_pMTVFTaskItem);
|
||||
FileSystem()->PrecacheTaskItem(pMTVFTaskItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (strcmp(v17, "mp_lobby.rpak") == 0)
|
||||
s_bBasePaksInitialized = true;
|
||||
|
||||
if (s_bBasePaksInitialized && !s_bLevelResourceInitialized)
|
||||
if (it == CommonPakData_t::PAK_TYPE_LOBBY)
|
||||
s_customPakData.basePaksLoaded = true;
|
||||
|
||||
if (s_customPakData.basePaksLoaded && !s_customPakData.levelResourcesLoaded)
|
||||
{
|
||||
Mod_PreloadLevelPaks(s_LevelName.c_str());
|
||||
s_bLevelResourceInitialized = true;
|
||||
Mod_PreloadLevelPaks(s_CurrentLevelName.String());
|
||||
s_customPakData.levelResourcesLoaded = true;
|
||||
}
|
||||
*(_DWORD*)v15 = g_pakLoadApi->LoadAsync(v17, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
if (strcmp(v17, "common_mp.rpak") == 0 || strcmp(v17, "common_sp.rpak") == 0 || strcmp(v17, "common_pve.rpak") == 0)
|
||||
g_pakLoadApi->LoadAsync("common_sdk.rpak", AlignedMemAlloc(), 4, 0);
|
||||
commonData->pakId = g_pakLoadApi->LoadAsync(name, AlignedMemAlloc(), 4, 0);
|
||||
|
||||
#ifndef DEDICATED
|
||||
if (strcmp(v17, "ui_mp.rpak") == 0)
|
||||
g_pakLoadApi->LoadAsync("ui_sdk.rpak", AlignedMemAlloc(), 4, 0);
|
||||
if (it == CommonPakData_t::PAK_TYPE_UI_GM)
|
||||
s_customPakData.LoadBasePak("ui_sdk.rpak", CustomPakData_t::PAK_TYPE_UI_SDK);
|
||||
#endif // !DEDICATED
|
||||
if (it == CommonPakData_t::PAK_TYPE_COMMON_GM)
|
||||
s_customPakData.LoadBasePak("common_sdk.rpak", CustomPakData_t::PAK_TYPE_COMMON_SDK);
|
||||
|
||||
LABEL_37:
|
||||
v21 = *(_DWORD*)v15;
|
||||
if (*(_DWORD*)v15 != INVALID_PAK_HANDLE)
|
||||
CHECK_FOR_FAILURE:
|
||||
|
||||
if (commonData->pakId != INVALID_PAK_HANDLE)
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
v22 = 232i64 * (v21 & 0x1FF);
|
||||
#else
|
||||
v22 = 184i64 * (v21 & 0x1FF);
|
||||
#endif
|
||||
if (*(_DWORD*)((char*)&*g_pLoadedPakInfo + v22) != _DWORD(v21) || ((*(_DWORD*)((char*)&*g_pLoadedPakInfo + v22 + 4) - 9) & 0xFFFFFFFB) != 0)
|
||||
const PakLoadedInfo_t* const pli = Pak_GetPakInfo(commonData->pakId);
|
||||
|
||||
if (pli->handle != commonData->pakId || ((pli->status - 9) & 0xFFFFFFFB) != 0)
|
||||
{
|
||||
*byte_16709DDDF = 0; return;
|
||||
*g_pPakPrecacheJobFinished = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
goto LABEL_40;
|
||||
}
|
||||
|
||||
goto LOOP_AGAIN_OR_FINISH;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -394,12 +440,12 @@ void Mod_ProcessPakQueue()
|
||||
// Input : *szLevelName -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
void Mod_LoadPakForMap(const char* pszLevelName)
|
||||
void Mod_LoadPakForMap(const char* const pszLevelName)
|
||||
{
|
||||
if (Mod_LevelHasChanged(pszLevelName))
|
||||
s_bLevelResourceInitialized = false;
|
||||
s_customPakData.levelResourcesLoaded = false;
|
||||
|
||||
s_LevelName = pszLevelName;
|
||||
s_CurrentLevelName = pszLevelName;
|
||||
|
||||
// Dedicated should not load loadscreens.
|
||||
#ifndef DEDICATED
|
||||
@ -412,11 +458,12 @@ void Mod_LoadPakForMap(const char* pszLevelName)
|
||||
// Input : *pszLevelName -
|
||||
// Output : KeyValues*
|
||||
//-----------------------------------------------------------------------------
|
||||
KeyValues* Mod_GetLevelSettings(const char* pszLevelName)
|
||||
KeyValues* Mod_GetLevelSettings(const char* const pszLevelName)
|
||||
{
|
||||
if (s_pLevelSetKV)
|
||||
{
|
||||
if (s_bLevelResourceInitialized)
|
||||
// If we didn't change the level, return the current one
|
||||
if (s_customPakData.levelResourcesLoaded)
|
||||
return s_pLevelSetKV;
|
||||
|
||||
s_pLevelSetKV->DeleteThis();
|
||||
@ -433,14 +480,14 @@ KeyValues* Mod_GetLevelSettings(const char* pszLevelName)
|
||||
// Purpose: loads required pakfile assets for specified BSP level
|
||||
// Input : &svSetFile -
|
||||
//-----------------------------------------------------------------------------
|
||||
void Mod_PreloadLevelPaks(const char* pszLevelName)
|
||||
void Mod_PreloadLevelPaks(const char* const pszLevelName)
|
||||
{
|
||||
KeyValues* pSettingsKV = Mod_GetLevelSettings(pszLevelName);
|
||||
KeyValues* const pSettingsKV = Mod_GetLevelSettings(pszLevelName);
|
||||
|
||||
if (!pSettingsKV)
|
||||
return;
|
||||
|
||||
KeyValues* pPakListKV = pSettingsKV->FindKey("PakList");
|
||||
KeyValues* const pPakListKV = pSettingsKV->FindKey("PakList");
|
||||
|
||||
if (!pPakListKV)
|
||||
return;
|
||||
@ -453,12 +500,10 @@ void Mod_PreloadLevelPaks(const char* pszLevelName)
|
||||
continue;
|
||||
|
||||
snprintf(szPathBuffer, sizeof(szPathBuffer), "%s.rpak", pSubKey->GetName());
|
||||
RPakHandle_t nPakId = g_pakLoadApi->LoadAsync(szPathBuffer, AlignedMemAlloc(), 4, 0);
|
||||
const PakHandle_t nPakId = s_customPakData.LoadAndAddPak(szPathBuffer);
|
||||
|
||||
if (nPakId == INVALID_PAK_HANDLE)
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, szPathBuffer, nPakId);
|
||||
else
|
||||
g_vLoadedPakHandle.AddToTail(nPakId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,25 +512,14 @@ void Mod_PreloadLevelPaks(const char* pszLevelName)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Mod_UnloadPakFile(void)
|
||||
{
|
||||
for (const RPakHandle_t& it : g_vLoadedPakHandle)
|
||||
{
|
||||
if (it >= 0)
|
||||
{
|
||||
g_pakLoadApi->UnloadPak(it);
|
||||
}
|
||||
}
|
||||
g_vLoadedPakHandle.Purge();
|
||||
g_vBadMDLHandles.clear();
|
||||
s_customPakData.UnloadAndRemoveAll();
|
||||
|
||||
g_StudioMdlFallbackHandler.ClearBadModelHandleCache();
|
||||
g_StudioMdlFallbackHandler.ClearSuppresionList();
|
||||
}
|
||||
|
||||
void VModel_BSP::Attach() const
|
||||
void VModel_BSP::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_Mod_LoadPakForMap, &Mod_LoadPakForMap);
|
||||
DetourAttach((LPVOID*)&v_Mod_ProcessPakQueue, &Mod_ProcessPakQueue);
|
||||
}
|
||||
|
||||
void VModel_BSP::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_Mod_LoadPakForMap, &Mod_LoadPakForMap);
|
||||
DetourDetach((LPVOID*)&v_Mod_ProcessPakQueue, &Mod_ProcessPakQueue);
|
||||
DetourSetup(&v_Mod_LoadPakForMap, &Mod_LoadPakForMap, bAttach);
|
||||
DetourSetup(&v_Mod_QueuedPakCacheFrame, &Mod_QueuedPakCacheFrame, bAttach);
|
||||
}
|
@ -1,33 +1,135 @@
|
||||
#pragma once
|
||||
#include "tier0/jobthread.h"
|
||||
#include "rtech/ipakfile.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class KeyValues;
|
||||
|
||||
inline CMemory p_Mod_LoadPakForMap;
|
||||
//-----------------------------------------------------------------------------
|
||||
// this structure contains handles and names to the base pak files the engine
|
||||
// loads for a level, this is used for load/unload management during level
|
||||
// changes or engine shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CommonPakData_t
|
||||
{
|
||||
enum EPakType
|
||||
{
|
||||
// the UI pak assigned to the current gamemode (range in GameMode_t)
|
||||
PAK_TYPE_UI_GM = 0,
|
||||
PAK_TYPE_COMMON,
|
||||
|
||||
// the base pak assigned to the current gamemode (range in GameMode_t)
|
||||
PAK_TYPE_COMMON_GM,
|
||||
PAK_TYPE_LOBBY,
|
||||
|
||||
// NOTE: this one is assigned to the name of the level, the prior ones are
|
||||
// all static!
|
||||
PAK_TYPE_LEVEL,
|
||||
|
||||
// the total number of pak files to watch and manage
|
||||
PAK_TYPE_COUNT
|
||||
};
|
||||
|
||||
CommonPakData_t()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
pakId = INVALID_PAK_HANDLE;
|
||||
keepLoaded = false;
|
||||
basePakName = nullptr;
|
||||
|
||||
memset(pakName, '\0', sizeof(pakName));
|
||||
}
|
||||
|
||||
PakHandle_t pakId;
|
||||
bool keepLoaded;
|
||||
|
||||
// the pak name that's being requested to be loaded for this particular slot
|
||||
char pakName[MAX_PATH];
|
||||
|
||||
// the actual base pak name, like "common_pve.rpak" as set when this array is
|
||||
// being initialized
|
||||
const char* basePakName;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// this structure contains handles and names to the custom pak files that are
|
||||
// loaded with the settings KV for that level, these paks are loaded after the
|
||||
// common paks are loaded, but unloaded before the common paks are unloaded
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomPakData_t
|
||||
{
|
||||
enum EPakType
|
||||
{
|
||||
// the pak that loads after CommonPakData_t::PAK_TYPE_UI_GM has loaded, and
|
||||
// unloads before CommonPakData_t::PAK_TYPE_UI_GM gets unloaded
|
||||
PAK_TYPE_UI_SDK = 0,
|
||||
|
||||
// the pak that loads after CommonPakData_t::PAK_TYPE_COMMON_GM has loaded,
|
||||
// and unloads before CommonPakData_t::PAK_TYPE_COMMON_GM gets unloaded
|
||||
PAK_TYPE_COMMON_SDK,
|
||||
|
||||
// the total number of base SDK pak files
|
||||
PAK_TYPE_COUNT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// the absolute max number of custom paks, note that the engine's limit
|
||||
// could still be reached before this number as game scripts and other
|
||||
// code still loads paks such as gladiator cards or load screens
|
||||
MAX_CUSTOM_PAKS = (PAK_MAX_HANDLES - CommonPakData_t::PAK_TYPE_COUNT)
|
||||
};
|
||||
|
||||
CustomPakData_t()
|
||||
{
|
||||
for (size_t i = 0; i < V_ARRAYSIZE(handles); i++)
|
||||
{
|
||||
handles[i] = INVALID_PAK_HANDLE;
|
||||
}
|
||||
|
||||
// the first # handles are reserved for base SDK paks
|
||||
numHandles = PAK_TYPE_COUNT;
|
||||
|
||||
levelResourcesLoaded = false;
|
||||
basePaksLoaded = false;
|
||||
}
|
||||
|
||||
PakHandle_t LoadAndAddPak(const char* const pakFile);
|
||||
void UnloadAndRemoveAll();
|
||||
|
||||
PakHandle_t LoadBasePak(const char* const pakFile, const EPakType type);
|
||||
void UnloadBasePak(const EPakType type);
|
||||
|
||||
// Pak handles that have been loaded with the level
|
||||
// from within the level settings KV (located in
|
||||
// scripts/levels/settings/*.kv). On level unload,
|
||||
// each pak listed in this vector gets unloaded.
|
||||
PakHandle_t handles[MAX_CUSTOM_PAKS];
|
||||
size_t numHandles;
|
||||
|
||||
bool levelResourcesLoaded;
|
||||
bool basePaksLoaded;
|
||||
};
|
||||
|
||||
// array size = CommonPakData_t::PAK_TYPE_COUNT
|
||||
inline CommonPakData_t* g_commonPakData;
|
||||
|
||||
inline void(*v_Mod_LoadPakForMap)(const char* szLevelName);
|
||||
inline void(*v_Mod_QueuedPakCacheFrame)(void);
|
||||
|
||||
inline CMemory p_Mod_ProcessPakQueue;
|
||||
inline void(*v_Mod_ProcessPakQueue)(void);
|
||||
inline int32_t * g_pNumPrecacheItemsMTVTF;
|
||||
inline bool* g_pPakPrecacheJobFinished;
|
||||
|
||||
inline float* dword_14B383420;
|
||||
inline int32_t * dword_1634F445C;
|
||||
inline void** qword_167ED7BB8;
|
||||
inline bool* byte_16709DDDF;
|
||||
inline char** off_141874660;
|
||||
inline void** unk_141874555;
|
||||
inline void** unk_1418749B0;
|
||||
inline void** unk_141874550;
|
||||
inline int64_t* qword_167ED7BC0;
|
||||
inline void(*Mod_UnloadPendingAndPrecacheRequestedPaks)(void);
|
||||
|
||||
inline __int64(*sub_14045BAC0)(__int64(__fastcall* a1)(__int64, _DWORD*, __int64, _QWORD*), JobFifoLock_s* pFifoLock, __int64 a3, __int64 a4);
|
||||
inline __int64(*sub_14045A1D0)(unsigned __int8(__fastcall* a1)(_QWORD), JobFifoLock_s* pFifoLock, __int64 a3, __int64 a4, volatile signed __int64* a5, char a6);
|
||||
inline void(*sub_140441220)(__int64 a1, __int64 a2);
|
||||
|
||||
extern bool s_bBasePaksInitialized;
|
||||
extern vector<string> g_InstalledMaps;
|
||||
extern CUtlVector<CUtlString> g_InstalledMaps;
|
||||
extern std::mutex g_InstalledMapsMutex;
|
||||
|
||||
bool Mod_LevelHasChanged(const char* pszLevelName);
|
||||
void Mod_GetAllInstalledMaps();
|
||||
@ -41,55 +143,30 @@ class VModel_BSP : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("Mod_LoadPakForMap", p_Mod_LoadPakForMap.GetPtr());
|
||||
LogFunAdr("Mod_ProcessPakQueue", p_Mod_ProcessPakQueue.GetPtr());
|
||||
LogFunAdr("sub_14045BAC0", reinterpret_cast<uintptr_t>(sub_14045BAC0));
|
||||
LogFunAdr("sub_14045A1D0", reinterpret_cast<uintptr_t>(sub_14045A1D0));
|
||||
LogFunAdr("sub_140441220", reinterpret_cast<uintptr_t>(sub_140441220));
|
||||
LogVarAdr("dword_14B383420", reinterpret_cast<uintptr_t>(dword_14B383420));
|
||||
LogVarAdr("dword_1634F445C", reinterpret_cast<uintptr_t>(dword_1634F445C));
|
||||
LogVarAdr("qword_167ED7BB8", reinterpret_cast<uintptr_t>(qword_167ED7BB8));
|
||||
LogVarAdr("byte_16709DDDF", reinterpret_cast<uintptr_t>(byte_16709DDDF));
|
||||
LogVarAdr("off_141874660", reinterpret_cast<uintptr_t>(off_141874660));
|
||||
LogVarAdr("unk_141874555", reinterpret_cast<uintptr_t>(unk_141874555));
|
||||
LogVarAdr("unk_1418749B0", reinterpret_cast<uintptr_t>(unk_1418749B0));
|
||||
LogVarAdr("unk_141874550", reinterpret_cast<uintptr_t>(unk_141874550));
|
||||
LogVarAdr("qword_167ED7BC0", reinterpret_cast<uintptr_t>(qword_167ED7BC0));
|
||||
LogFunAdr("Mod_LoadPakForMap", v_Mod_LoadPakForMap);
|
||||
LogFunAdr("Mod_QueuedPakCacheFrame", v_Mod_QueuedPakCacheFrame);
|
||||
|
||||
LogFunAdr("Mod_UnloadPendingAndPrecacheRequestedPaks", Mod_UnloadPendingAndPrecacheRequestedPaks);
|
||||
|
||||
LogVarAdr("g_numPrecacheItemsMTVTF", g_pNumPrecacheItemsMTVTF);
|
||||
LogVarAdr("g_pakPrecacheJobFinished", g_pPakPrecacheJobFinished);
|
||||
|
||||
LogVarAdr("g_commonPakData", g_commonPakData);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_Mod_LoadPakForMap = g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 4C 8B C1 48 8D 15 ?? ?? ?? ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 4C 8D 0D ?? ?? ?? ??");
|
||||
v_Mod_LoadPakForMap = p_Mod_LoadPakForMap.RCast<void(*)(const char*)>(); /*48 81 EC ? ? ? ? 4C 8B C1 48 8D 15 ? ? ? ? 48 8D 4C 24 ? E8 ? ? ? ? 4C 8D 0D ? ? ? ?*/
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_Mod_LoadPakForMap = g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 0F B6 05 ?? ?? ?? ?? 4C 8D 05 ?? ?? ?? ?? 84 C0");
|
||||
v_Mod_LoadPakForMap = p_Mod_LoadPakForMap.RCast<void(*)(const char*)>(); /*48 81 EC ? ? ? ? 0F B6 05 ? ? ? ? 4C 8D 05 ? ? ? ? 84 C0*/
|
||||
#endif
|
||||
p_Mod_ProcessPakQueue = g_GameDll.FindPatternSIMD("40 53 48 83 EC ?? F3 0F 10 05 ?? ?? ?? ?? 32 DB");
|
||||
v_Mod_ProcessPakQueue = p_Mod_ProcessPakQueue.RCast<void(*)(void)>(); /*40 53 48 83 EC ?? F3 0F 10 05 ? ? ? ? 32 DB*/
|
||||
|
||||
sub_14045BAC0 = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 4C 89 4C 24 ?? 4C 89 44 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 60").RCast<__int64(*)(__int64(__fastcall* a1)(__int64, _DWORD*, __int64, _QWORD*), JobFifoLock_s* pFifoLock, __int64 a3, __int64 a4)>();
|
||||
sub_14045A1D0 = g_GameDll.FindPatternSIMD("4C 89 4C 24 ?? 4C 89 44 24 ?? 48 89 54 24 ?? 48 89 4C 24 ?? 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 ??").RCast<__int64(*)(unsigned __int8(__fastcall* a1)(_QWORD), JobFifoLock_s* pFifoLock, __int64 a3, __int64 a4, volatile signed __int64* a5, char a6)>();
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
sub_140441220 = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 83 EC 20 33 ED 48 39 2D ?? ?? ?? ??").RCast<void(*)(__int64 a1, __int64 a2)>();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
sub_140441220 = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 33 ED 48 8D 35 ?? ?? ?? ?? 48 39 2D ?? ?? ?? ??").RCast<void(*)(__int64 a1, __int64 a2)>();
|
||||
#endif
|
||||
g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 0F B6 05 ?? ?? ?? ?? 4C 8D 05 ?? ?? ?? ?? 84 C0").GetPtr(v_Mod_LoadPakForMap);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC ?? F3 0F 10 05 ?? ?? ?? ?? 32 DB").GetPtr(v_Mod_QueuedPakCacheFrame);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 33 ED 48 8D 35 ?? ?? ?? ?? 48 39 2D ?? ?? ?? ??").GetPtr(Mod_UnloadPendingAndPrecacheRequestedPaks);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
dword_14B383420 = p_Mod_ProcessPakQueue.FindPattern("F3 0F 10").ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
dword_1634F445C = p_Mod_ProcessPakQueue.FindPattern("8B 05").ResolveRelativeAddressSelf(0x2, 0x6).RCast<int32_t*>();
|
||||
qword_167ED7BB8 = p_Mod_ProcessPakQueue.Offset(0x10).FindPatternSelf("48 83").ResolveRelativeAddressSelf(0x3, 0x8).RCast<void**>();
|
||||
byte_16709DDDF = p_Mod_ProcessPakQueue.Offset(0x20).FindPatternSelf("88 1D").ResolveRelativeAddressSelf(0x2, 0x6).RCast<bool*>();
|
||||
off_141874660 = p_Mod_ProcessPakQueue.Offset(0x40).FindPatternSelf("4C 8D 15").ResolveRelativeAddressSelf(0x3, 0x7).RCast<char**>();
|
||||
unk_141874555 = p_Mod_ProcessPakQueue.Offset(0x40).FindPatternSelf("4C 8D 1D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<void**>();
|
||||
unk_1418749B0 = p_Mod_ProcessPakQueue.Offset(0xA0).FindPatternSelf("48 8D 1D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<void**>();
|
||||
unk_141874550 = p_Mod_ProcessPakQueue.Offset(0x150).FindPatternSelf("48 8D 2D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<void**>();
|
||||
qword_167ED7BC0 = p_Mod_ProcessPakQueue.Offset(0x200).FindPatternSelf("48 83 3D").ResolveRelativeAddressSelf(0x3, 0x8).RCast<int64_t*>();
|
||||
g_pNumPrecacheItemsMTVTF = CMemory(v_Mod_QueuedPakCacheFrame).FindPattern("8B 05").ResolveRelativeAddressSelf(0x2, 0x6).RCast<int32_t*>();
|
||||
g_pPakPrecacheJobFinished = CMemory(v_Mod_QueuedPakCacheFrame).Offset(0x20).FindPatternSelf("88 1D").ResolveRelativeAddressSelf(0x2, 0x6).RCast<bool*>();
|
||||
|
||||
CMemory(v_Mod_QueuedPakCacheFrame).Offset(0xA0).FindPatternSelf("48 8D 2D").ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(g_commonPakData);
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <core/stdafx.h>
|
||||
#include <tier1/strtools.h>
|
||||
#include <localize/localize.h>
|
||||
#include <engine/common.h>
|
||||
|
||||
/*
|
||||
@ -43,3 +44,53 @@ const char* COM_FormatSeconds(int seconds)
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
/*
|
||||
==============================
|
||||
COM_ExplainDisconnection
|
||||
|
||||
==============================
|
||||
*/
|
||||
void COM_ExplainDisconnection(bool bPrint, const char* fmt, ...)
|
||||
{
|
||||
char szBuf[1024];
|
||||
{/////////////////////////////
|
||||
va_list vArgs;
|
||||
va_start(vArgs, fmt);
|
||||
|
||||
vsnprintf(szBuf, sizeof(szBuf), fmt, vArgs);
|
||||
|
||||
szBuf[sizeof(szBuf) - 1] = '\0';
|
||||
va_end(vArgs);
|
||||
}/////////////////////////////
|
||||
|
||||
if (bPrint)
|
||||
{
|
||||
if (szBuf[0] == '#')
|
||||
{
|
||||
wchar_t formatStr[1024];
|
||||
const wchar_t* wpchReason = (*g_ppVGuiLocalize) ? (*g_ppVGuiLocalize)->Find(szBuf) : nullptr;
|
||||
if (wpchReason)
|
||||
{
|
||||
wcsncpy(formatStr, wpchReason, sizeof(formatStr) / sizeof(wchar_t));
|
||||
|
||||
char conStr[256];
|
||||
(*g_ppVGuiLocalize)->ConvertUnicodeToANSI(formatStr, conStr, sizeof(conStr));
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "%s\n", conStr);
|
||||
}
|
||||
else
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "%s\n", szBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(eDLL_T::CLIENT, NO_ERROR, "%s\n", szBuf);
|
||||
}
|
||||
}
|
||||
|
||||
v_COM_ExplainDisconnection(bPrint, szBuf);
|
||||
}
|
||||
|
||||
void VCommon::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&v_COM_ExplainDisconnection, COM_ExplainDisconnection, bAttach);
|
||||
}
|
||||
|
@ -1,32 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
/* ==== COMMON ========================================================================================================================================================== */
|
||||
inline CMemory p_COM_InitFilesystem;
|
||||
inline void*(*COM_InitFilesystem)(const char* pFullModPath);
|
||||
|
||||
inline CMemory p_COM_ExplainDisconnection;
|
||||
inline void*(*COM_ExplainDisconnection)(uint64_t level, const char* fmt, ...);
|
||||
inline void*(*v_COM_InitFilesystem)(const char* pFullModPath);
|
||||
inline char* const(*v_COM_GetPrintMessageBuffer)(void);
|
||||
inline void(*v_COM_ExplainDisconnection)(bool bPrint, const char* fmt, ...);
|
||||
|
||||
const char* COM_FormatSeconds(int seconds);
|
||||
void COM_ExplainDisconnection(bool bPrint, const char* fmt, ...);
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCommon : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("COM_InitFilesystem", p_COM_InitFilesystem.GetPtr());
|
||||
LogFunAdr("COM_ExplainDisconnection", p_COM_ExplainDisconnection.GetPtr());
|
||||
LogFunAdr("COM_InitFilesystem", v_COM_InitFilesystem);
|
||||
LogFunAdr("COM_GetPrintMessageBuffer", v_COM_GetPrintMessageBuffer);
|
||||
LogFunAdr("COM_ExplainDisconnection", v_COM_ExplainDisconnection);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_COM_InitFilesystem = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 48 C7 44 24 ?? ?? ?? ?? ??");
|
||||
p_COM_ExplainDisconnection = g_GameDll.FindPatternSIMD("48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 48 81 EC ?? ?? ?? ??");
|
||||
|
||||
COM_InitFilesystem = p_COM_InitFilesystem.RCast<void* (*)(const char*)>(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 48 C7 44 24 ?? ?? ?? ?? ??*/
|
||||
COM_ExplainDisconnection = p_COM_ExplainDisconnection.RCast<void* (*)(uint64_t, const char*, ...)>(); /*48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 48 81 EC ?? ?? ?? ??*/
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 48 C7 44 24 ?? ?? ?? ?? ??").GetPtr(v_COM_InitFilesystem);
|
||||
g_GameDll.FindPatternSIMD("48 8D 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 4C 89 44 24 ??").GetPtr(v_COM_GetPrintMessageBuffer);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 48 81 EC ?? ?? ?? ??").GetPtr(v_COM_ExplainDisconnection);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -20,6 +20,11 @@
|
||||
#include "game/server/ai_network.h"
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
ConVar r_debug_draw_depth_test("r_debug_draw_depth_test", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Toggle depth test for other debug draw functionality");
|
||||
|
||||
static ConVar r_debug_overlay_nodecay("r_debug_overlay_nodecay", "0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Keeps all debug overlays alive regardless of their lifetime. Use command 'clear_debug_overlays' to clear everything");
|
||||
static ConVar r_debug_overlay_invisible("r_debug_overlay_invisible", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Show invisible debug overlays (alpha < 1 = 255)");
|
||||
static ConVar r_debug_overlay_wireframe("r_debug_overlay_wireframe", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Use wireframe in debug overlay");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: checks if overlay should be decayed
|
||||
@ -27,7 +32,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
bool OverlayBase_t::IsDead() const
|
||||
{
|
||||
if (r_debug_overlay_nodecay->GetBool())
|
||||
if (r_debug_overlay_nodecay.GetBool())
|
||||
{
|
||||
// Keep rendering the overlay if no-decay is set.
|
||||
return false;
|
||||
@ -107,7 +112,7 @@ void DrawOverlay(OverlayBase_t* pOverlay)
|
||||
OverlayBox_t* pBox = static_cast<OverlayBox_t*>(pOverlay);
|
||||
if (pBox->a < 1)
|
||||
{
|
||||
if (r_debug_overlay_invisible->GetBool())
|
||||
if (r_debug_overlay_invisible.GetBool())
|
||||
{
|
||||
pBox->a = 255;
|
||||
}
|
||||
@ -126,7 +131,7 @@ void DrawOverlay(OverlayBase_t* pOverlay)
|
||||
OverlaySphere_t* pSphere = static_cast<OverlaySphere_t*>(pOverlay);
|
||||
if (pSphere->a < 1)
|
||||
{
|
||||
if (r_debug_overlay_invisible->GetBool())
|
||||
if (r_debug_overlay_invisible.GetBool())
|
||||
{
|
||||
pSphere->a = 255;
|
||||
}
|
||||
@ -137,14 +142,14 @@ void DrawOverlay(OverlayBase_t* pOverlay)
|
||||
}
|
||||
}
|
||||
|
||||
if (r_debug_overlay_wireframe->GetBool())
|
||||
if (r_debug_overlay_wireframe.GetBool())
|
||||
{
|
||||
v_RenderWireframeSphere(pSphere->vOrigin, pSphere->flRadius, pSphere->nTheta, pSphere->nPhi,
|
||||
Color(pSphere->r, pSphere->g, pSphere->b, pSphere->a), r_debug_draw_depth_test->GetBool());
|
||||
Color(pSphere->r, pSphere->g, pSphere->b, pSphere->a), r_debug_draw_depth_test.GetBool());
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugDrawSphere(pSphere->vOrigin, pSphere->flRadius, Color(pSphere->r, pSphere->g, pSphere->b, pSphere->a), 16, r_debug_draw_depth_test->GetBool());
|
||||
DebugDrawSphere(pSphere->vOrigin, pSphere->flRadius, Color(pSphere->r, pSphere->g, pSphere->b, pSphere->a), 16, r_debug_draw_depth_test.GetBool());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -153,7 +158,7 @@ void DrawOverlay(OverlayBase_t* pOverlay)
|
||||
OverlayLine_t* pLine = static_cast<OverlayLine_t*>(pOverlay);
|
||||
if (pLine->a < 1)
|
||||
{
|
||||
if (r_debug_overlay_invisible->GetBool())
|
||||
if (r_debug_overlay_invisible.GetBool())
|
||||
{
|
||||
pLine->a = 255;
|
||||
}
|
||||
@ -188,7 +193,7 @@ void DrawOverlay(OverlayBase_t* pOverlay)
|
||||
OverlayCapsule_t* pCapsule = static_cast<OverlayCapsule_t*>(pOverlay);
|
||||
if (pCapsule->a < 1)
|
||||
{
|
||||
if (r_debug_overlay_invisible->GetBool())
|
||||
if (r_debug_overlay_invisible.GetBool())
|
||||
{
|
||||
pCapsule->a = 255;
|
||||
}
|
||||
@ -205,7 +210,7 @@ void DrawOverlay(OverlayBase_t* pOverlay)
|
||||
AngleInverse(angles, angles);
|
||||
|
||||
DebugDrawCapsule(pCapsule->start, angles, pCapsule->radius, pCapsule->start.DistTo(pCapsule->end),
|
||||
Color(pCapsule->r, pCapsule->g, pCapsule->b, pCapsule->a), r_debug_draw_depth_test->GetBool());
|
||||
Color(pCapsule->r, pCapsule->g, pCapsule->b, pCapsule->a), r_debug_draw_depth_test.GetBool());
|
||||
break;
|
||||
}
|
||||
case OverlayType_t::OVERLAY_UNK0:
|
||||
@ -292,16 +297,7 @@ void DrawAllOverlays(bool bRender)
|
||||
#ifndef CLIENT_DLL
|
||||
if (bOverlayEnabled)
|
||||
{
|
||||
if (ai_script_nodes_draw->GetInt() > -1)
|
||||
g_pAIUtility->DrawAIScriptNetwork(*g_pAINetwork);
|
||||
if (navmesh_draw_bvtree->GetInt() > -1)
|
||||
g_pAIUtility->DrawNavMeshBVTree();
|
||||
if (navmesh_draw_portal->GetInt() > -1)
|
||||
g_pAIUtility->DrawNavMeshPortals();
|
||||
if (navmesh_draw_polys->GetInt() > -1)
|
||||
g_pAIUtility->DrawNavMeshPolys();
|
||||
if (navmesh_draw_poly_bounds->GetInt() > -1)
|
||||
g_pAIUtility->DrawNavMeshPolyBoundaries();
|
||||
g_pAIUtility->RunRenderFrame();
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
@ -309,12 +305,7 @@ void DrawAllOverlays(bool bRender)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VDebugOverlay::Attach() const
|
||||
void VDebugOverlay::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&v_DrawAllOverlays, &DrawAllOverlays);
|
||||
}
|
||||
|
||||
void VDebugOverlay::Detach() const
|
||||
{
|
||||
DetourDetach(&v_DrawAllOverlays, &DrawAllOverlays);
|
||||
DetourSetup(&v_DrawAllOverlays, &DrawAllOverlays, bAttach);
|
||||
}
|
||||
|
@ -4,22 +4,8 @@
|
||||
#include "mathlib/color.h"
|
||||
#include "mathlib/ssemath.h"
|
||||
|
||||
// Something has to be hardcoded..
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
|
||||
constexpr auto MATERIALSYSTEM_VCALL_OFF_0 = 0x3F8;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_0 = 0x278;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_1 = 0x280;
|
||||
|
||||
#elif defined (GAMEDLL_S3)
|
||||
|
||||
constexpr auto MATERIALSYSTEM_VCALL_OFF_0 = 0x3F0;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_0 = 0x288;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_1 = 0x290;
|
||||
|
||||
#endif
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_2 = 0x8;
|
||||
constexpr auto NDEBUG_PERSIST_TILL_NEXT_SERVER = (0.01023f);
|
||||
extern ConVar r_debug_draw_depth_test;
|
||||
|
||||
enum class OverlayType_t
|
||||
{
|
||||
@ -159,19 +145,10 @@ struct OverlayCapsule_t : public OverlayBase_t
|
||||
void DestroyOverlay(OverlayBase_t* pOverlay);
|
||||
void DrawOverlay(OverlayBase_t* pOverlay);
|
||||
|
||||
inline CMemory p_DrawAllOverlays;
|
||||
inline void(*v_DrawAllOverlays)(bool bDraw);
|
||||
|
||||
inline CMemory p_DestroyOverlay;
|
||||
inline void(*v_DestroyOverlay)(OverlayBase_t* pOverlay);
|
||||
|
||||
inline CMemory p_RenderLine;
|
||||
inline void*(*v_RenderLine)(const Vector3D& vOrigin, const Vector3D& vDest, Color color, bool bZBuffer);
|
||||
|
||||
inline CMemory p_RenderBox;
|
||||
inline void*(*v_RenderBox)(const matrix3x4_t& vTransforms, const Vector3D& vMins, const Vector3D& vMaxs, Color color, bool bZBuffer);
|
||||
|
||||
inline CMemory p_RenderWireframeSphere;
|
||||
inline void*(*v_RenderWireframeSphere)(const Vector3D& vCenter, float flRadius, int nTheta, int nPhi, Color color, bool bZBuffer);
|
||||
|
||||
inline OverlayBase_t** s_pOverlays = nullptr;
|
||||
@ -185,50 +162,33 @@ class VDebugOverlay : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("DrawAllOverlays", p_DrawAllOverlays.GetPtr());
|
||||
LogFunAdr("DestroyOverlay", p_DestroyOverlay.GetPtr());
|
||||
LogFunAdr("RenderLine", p_RenderLine.GetPtr());
|
||||
LogFunAdr("RenderBox", p_RenderBox.GetPtr());
|
||||
LogFunAdr("RenderWireframeSphere", p_RenderWireframeSphere.GetPtr());
|
||||
LogVarAdr("s_Overlays", reinterpret_cast<uintptr_t>(s_pOverlays));
|
||||
LogVarAdr("s_OverlayMutex", reinterpret_cast<uintptr_t>(s_OverlayMutex));
|
||||
LogVarAdr("g_nOverlayTickCount", reinterpret_cast<uintptr_t>(g_nOverlayTickCount));
|
||||
LogVarAdr("g_nRenderTickCount", reinterpret_cast<uintptr_t>(g_nRenderTickCount));
|
||||
LogFunAdr("DrawAllOverlays", v_DrawAllOverlays);
|
||||
LogFunAdr("DestroyOverlay", v_DestroyOverlay);
|
||||
LogFunAdr("RenderLine", v_RenderLine);
|
||||
LogFunAdr("RenderBox", v_RenderBox);
|
||||
LogFunAdr("RenderWireframeSphere", v_RenderWireframeSphere);
|
||||
LogVarAdr("s_Overlays", s_pOverlays);
|
||||
LogVarAdr("s_OverlayMutex", s_OverlayMutex);
|
||||
LogVarAdr("g_nOverlayTickCount", g_nOverlayTickCount);
|
||||
LogVarAdr("g_nRenderTickCount", g_nRenderTickCount);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_DrawAllOverlays = g_GameDll.FindPatternSIMD("40 55 48 83 EC 50 48 8B 05 ?? ?? ?? ??");
|
||||
p_RenderBox = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 44 89 4C 24 ?? 55 41 56");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_DrawAllOverlays = g_GameDll.FindPatternSIMD("40 55 48 83 EC 30 48 8B 05 ?? ?? ?? ?? 0F B6 E9");
|
||||
p_RenderBox = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 44 89 4C 24 ??");
|
||||
#endif
|
||||
p_DestroyOverlay = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B D9 48 8D 0D ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 63 03");
|
||||
p_RenderWireframeSphere = g_GameDll.FindPatternSIMD("40 56 41 54 41 55 48 81 EC ?? ?? ?? ??");
|
||||
p_RenderLine = g_GameDll.FindPatternSIMD("48 89 74 24 ?? 44 89 44 24 ?? 57 41 56");
|
||||
|
||||
v_DrawAllOverlays = p_DrawAllOverlays.RCast<void (*)(bool)>(); /*40 55 48 83 EC 30 48 8B 05 ?? ?? ?? ?? 0F B6 E9*/
|
||||
v_DestroyOverlay = p_DestroyOverlay.RCast<void (*)(OverlayBase_t*)>(); /*40 53 48 83 EC 20 48 8B D9 48 8D 0D ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 63 03 */
|
||||
v_RenderBox = p_RenderBox.RCast<void* (*)(const matrix3x4_t&, const Vector3D&, const Vector3D&, Color, bool)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 44 89 4C 24 ??*/
|
||||
v_RenderWireframeSphere = p_RenderWireframeSphere.RCast<void* (*)(const Vector3D&, float, int, int, Color, bool)>(); /*40 56 41 54 41 55 48 81 EC ?? ?? ?? ??*/
|
||||
v_RenderLine = p_RenderLine.RCast<void* (*)(const Vector3D&, const Vector3D&, Color, bool)>(); /*48 89 74 24 ?? 44 89 44 24 ?? 57 41 56*/
|
||||
g_GameDll.FindPatternSIMD("40 55 48 83 EC 30 48 8B 05 ?? ?? ?? ?? 0F B6 E9").GetPtr(v_DrawAllOverlays);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 44 89 4C 24 ??").GetPtr(v_RenderBox);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B D9 48 8D 0D ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 63 03").GetPtr(v_DestroyOverlay);
|
||||
g_GameDll.FindPatternSIMD("40 56 41 54 41 55 48 81 EC ?? ?? ?? ??").GetPtr(v_RenderWireframeSphere);
|
||||
g_GameDll.FindPatternSIMD("48 89 74 24 ?? 44 89 44 24 ?? 57 41 56").GetPtr(v_RenderLine);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
s_pOverlays = p_DrawAllOverlays.Offset(0x10).FindPatternSelf("48 8B 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<OverlayBase_t**>();
|
||||
s_OverlayMutex = p_DrawAllOverlays.Offset(0x10).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<LPCRITICAL_SECTION>();
|
||||
s_pOverlays = CMemory(v_DrawAllOverlays).Offset(0x10).FindPatternSelf("48 8B 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<OverlayBase_t**>();
|
||||
s_OverlayMutex = CMemory(v_DrawAllOverlays).Offset(0x10).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<LPCRITICAL_SECTION>();
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
g_nRenderTickCount = p_DrawAllOverlays.Offset(0x80).FindPatternSelf("3B 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
g_nOverlayTickCount = p_DrawAllOverlays.Offset(0x70).FindPatternSelf("3B 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
g_nRenderTickCount = p_DrawAllOverlays.Offset(0x50).FindPatternSelf("3B 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
g_nOverlayTickCount = p_DrawAllOverlays.Offset(0x70).FindPatternSelf("3B 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
#endif
|
||||
g_nRenderTickCount = CMemory(v_DrawAllOverlays).Offset(0x50).FindPatternSelf("3B 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
g_nOverlayTickCount = CMemory(v_DrawAllOverlays).Offset(0x70).FindPatternSelf("3B 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6,13 +6,3 @@
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/enginetrace.h"
|
||||
|
||||
void CEngineTrace_Attach()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CEngineTrace_Detach()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -22,20 +22,16 @@ class CEngineTraceClient : public CEngineTrace
|
||||
inline CEngineTraceClient* g_pEngineTraceClient = nullptr;
|
||||
#endif // DEDICATED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void CEngineTrace_Attach();
|
||||
void CEngineTrace_Detach();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VEngineTrace : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
LogVarAdr("g_pEngineTraceServer", reinterpret_cast<uintptr_t>(g_pEngineTraceServer));
|
||||
LogVarAdr("g_pEngineTraceServer", g_pEngineTraceServer);
|
||||
#endif // CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
LogVarAdr("g_pEngineTraceClient", reinterpret_cast<uintptr_t>(g_pEngineTraceClient));
|
||||
LogVarAdr("g_pEngineTraceClient", g_pEngineTraceClient);
|
||||
#endif // DEDICATED
|
||||
}
|
||||
virtual void GetFun(void) const { }
|
||||
@ -47,7 +43,6 @@ class VEngineTrace : public IDetour
|
||||
g_pEngineTraceServer = reinterpret_cast<CEngineTraceServer*>(&g_pEngineTraceServerVFTable); // Must be done for virtual calls.
|
||||
#endif // CLIENT_DLL
|
||||
}
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
93
r5dev/engine/framelimit.cpp
Normal file
93
r5dev/engine/framelimit.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: High-precision frame rate limiter
|
||||
//
|
||||
//===========================================================================//
|
||||
#include <dwmapi.h>
|
||||
#include "tier0/platform_internal.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "sys_mainwind.h"
|
||||
#include "framelimit.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFrameLimit::CFrameLimit(void)
|
||||
{
|
||||
m_MilliSeconds = 0.0;
|
||||
m_FramesPerSecond = 0.0;
|
||||
|
||||
m_Start.QuadPart = 0;
|
||||
m_Next.QuadPart = 0;
|
||||
m_Time.QuadPart = 0;
|
||||
|
||||
m_Frames = 0;
|
||||
m_bRestart = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: initializer
|
||||
// Input : targetFps -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFrameLimit::Reset(double targetFps)
|
||||
{
|
||||
m_MilliSeconds = 1000.0 / targetFps;
|
||||
m_FramesPerSecond = targetFps;
|
||||
|
||||
QueryPerformanceCounter(&m_Start);
|
||||
m_Next.QuadPart = 0ULL;
|
||||
m_Time.QuadPart = 0ULL;
|
||||
|
||||
//m_Last.QuadPart = m_Start.QuadPart - (LONGLONG)((m_MilliSeconds / 1000.0) * g_pPerformanceFrequency->QuadPart);
|
||||
m_Next.QuadPart = m_Start.QuadPart + (LONGLONG)((m_MilliSeconds / 1000.0) * g_pPerformanceFrequency->QuadPart);
|
||||
|
||||
m_Frames = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: runs the frame limiter logic
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFrameLimit::Run(const double targetFps, const double sleepThreshold, const double maxTolerance)
|
||||
{
|
||||
if (m_FramesPerSecond != targetFps)
|
||||
Reset(targetFps);
|
||||
|
||||
m_Frames++;
|
||||
QueryPerformanceCounter(&m_Time);
|
||||
|
||||
// Actual frametime before we forced a delay
|
||||
//m_EffectiveMilliSeconds = 1000.0 * ((double)(m_Time.QuadPart - m_Last.QuadPart) / (double)g_pPerformanceFrequency->QuadPart);
|
||||
|
||||
if ((double)(m_Time.QuadPart - m_Next.QuadPart) / (double)g_pPerformanceFrequency->QuadPart / (m_MilliSeconds / 1000.0) > (maxTolerance * m_FramesPerSecond))
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Frame time too long (expected: %3.01fx); restarting...\n",
|
||||
__FUNCTION__, (double)(m_Time.QuadPart - m_Next.QuadPart) / (double)g_pPerformanceFrequency->QuadPart / (m_MilliSeconds / 1000.0) / m_FramesPerSecond );
|
||||
m_bRestart = true;
|
||||
}
|
||||
|
||||
if (m_bRestart)
|
||||
{
|
||||
m_Frames = 0;
|
||||
m_Start.QuadPart = m_Time.QuadPart + (LONGLONG)((m_MilliSeconds / 1000.0) * (double)g_pPerformanceFrequency->QuadPart);
|
||||
m_bRestart = false;
|
||||
//Reset (targetFps);
|
||||
//return;
|
||||
}
|
||||
|
||||
m_Next.QuadPart = (LONGLONG)((m_Start.QuadPart + (double)m_Frames * (m_MilliSeconds / 1000.0) * (double)g_pPerformanceFrequency->QuadPart));
|
||||
|
||||
if (m_Next.QuadPart > 0ULL)
|
||||
{
|
||||
while (m_Time.QuadPart < m_Next.QuadPart)
|
||||
{
|
||||
if ((double)(m_Next.QuadPart - m_Time.QuadPart) > (sleepThreshold * (double)g_pPerformanceFrequency->QuadPart))
|
||||
{
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
QueryPerformanceCounter(&m_Time);
|
||||
}
|
||||
}
|
||||
|
||||
//m_Last.QuadPart = m_Time.QuadPart;
|
||||
}
|
26
r5dev/engine/framelimit.h
Normal file
26
r5dev/engine/framelimit.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef FRAMELIMIT_H
|
||||
#define FRAMELIMIT_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RenderThread frame limiter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFrameLimit
|
||||
{
|
||||
public:
|
||||
CFrameLimit(void);
|
||||
|
||||
void Reset(const double target);
|
||||
void Run(const double targetFps, const double sleepThreshold, const double maxTolerance);
|
||||
|
||||
private:
|
||||
double m_MilliSeconds;
|
||||
double m_FramesPerSecond;
|
||||
|
||||
LARGE_INTEGER m_Start;
|
||||
LARGE_INTEGER m_Next;
|
||||
LARGE_INTEGER m_Time;
|
||||
uint32_t m_Frames;
|
||||
bool m_bRestart;
|
||||
};
|
||||
|
||||
#endif // FRAMELIMIT_H
|
13
r5dev/engine/gl_drawlights.cpp
Normal file
13
r5dev/engine/gl_drawlights.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "gl_drawlights.h"
|
||||
|
||||
|
||||
void DrawLightSprites(void* unkType)
|
||||
{
|
||||
v_DrawLightSprites(unkType);
|
||||
}
|
||||
|
||||
void VGL_DrawLights::Detour(const bool bAttach) const
|
||||
{
|
||||
// Enable if needed.
|
||||
//DetourSetup(&v_DrawLightSprites, &DrawLightSprites, bAttach);
|
||||
}
|
20
r5dev/engine/gl_drawlights.h
Normal file
20
r5dev/engine/gl_drawlights.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
inline void(*v_DrawLightSprites)(void*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VGL_DrawLights : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("DrawLightSprites", v_DrawLightSprites);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 55 57 48 8D 68 A1 48 81 EC ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ??").GetPtr(v_DrawLightSprites);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
/* ==== MATSYSIFACE ===================================================================================================================================================== */
|
||||
inline CMemory p_InitMaterialSystem;
|
||||
inline void*(*v_InitMaterialSystem)(void);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -9,20 +8,14 @@ class VGL_MatSysIFace : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("InitMaterialSystem", p_InitMaterialSystem.GetPtr());
|
||||
LogFunAdr("InitMaterialSystem", v_InitMaterialSystem);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_InitMaterialSystem = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 8D 1D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ??");
|
||||
#else
|
||||
p_InitMaterialSystem = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 0D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ??");
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1)
|
||||
v_InitMaterialSystem = p_InitMaterialSystem.RCast<void* (*)(void)>();
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 0D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ??").GetPtr(v_InitMaterialSystem);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -9,20 +9,57 @@
|
||||
#ifndef GL_MODEL_PRIVATE_H
|
||||
#define GL_MODEL_PRIVATE_H
|
||||
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "common/qlimits.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "public/model_types.h"
|
||||
#include "public/bspfile.h"
|
||||
|
||||
#ifndef DEDICATED
|
||||
#include "game/client/enginesprite.h"
|
||||
#endif // !DEDICATED
|
||||
typedef int ModelFileNameHandle_t; // 4 bytes in r5, void* originally.
|
||||
|
||||
struct worldbrushdata_t
|
||||
{
|
||||
char unk[64];
|
||||
Vector3D* vertpositions;
|
||||
int numvertices;
|
||||
char unk_4C[4];
|
||||
Vector3D* vertnormals;
|
||||
int numvertnormals;
|
||||
int numtexdata;
|
||||
dtexdata_t* texdata;
|
||||
char* surfacenames;
|
||||
char unk_60[4];
|
||||
int nummeshes;
|
||||
char unk_78[72];
|
||||
int nummaterialsorts;
|
||||
char unk_C4[4];
|
||||
char* lmapTypes;
|
||||
int* lmapSizes;
|
||||
dlightmapheader_t* lmapHeaders;
|
||||
char* rtlData;
|
||||
char* rtlPageData;
|
||||
int numRtlPages;
|
||||
int numLightmapHeaders;
|
||||
bool externalLightmaps;
|
||||
int numlightprobeindices;
|
||||
int* lightprobeindices;
|
||||
int numlightprobes;
|
||||
dlightprobe_t* lightprobes;
|
||||
char* lightproberefs;
|
||||
char* lightprobetrees;
|
||||
char* lightprobeparentinfos;
|
||||
char unk_130[16];
|
||||
char* worldlights;
|
||||
int numworldlights;
|
||||
};
|
||||
|
||||
struct brushdata_t // !! UNCONFIRMED !!
|
||||
{
|
||||
void* pShared; // worldbrushdata_t
|
||||
worldbrushdata_t* pShared; // worldbrushdata_t
|
||||
int firstmodelsurface;
|
||||
int nummodelsurfaces;
|
||||
|
||||
|
@ -24,8 +24,7 @@ class VGL_RMain : public IDetour
|
||||
virtual void GetFun(void) const { }
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -6,11 +6,24 @@
|
||||
//===========================================================================//
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "geforce/reflex.h"
|
||||
#include "engine/gl_rsurf.h"
|
||||
#include <materialsystem/cmaterialsystem.h>
|
||||
|
||||
static ConVar r_drawWorldMeshes("r_drawWorldMeshes", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes.");
|
||||
static ConVar r_drawWorldMeshesDepthOnly("r_drawWorldMeshesDepthOnly", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes (depth only).");
|
||||
static ConVar r_drawWorldMeshesDepthAtTheEnd("r_drawWorldMeshesDepthAtTheEnd", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes (depth at the end).");
|
||||
|
||||
void* R_DrawDepthOfField(const float scalar)
|
||||
{
|
||||
GFX_SetLatencyMarker(D3D11Device(), RENDERSUBMIT_START, MaterialSystem()->GetCurrentFrameCount());
|
||||
return V_DrawDepthOfField(scalar);
|
||||
}
|
||||
|
||||
void* R_DrawWorldMeshes(void* baseEntity, void* renderContext, DrawWorldLists_t worldLists)
|
||||
{
|
||||
if (r_drawWorldMeshes->GetBool())
|
||||
if (r_drawWorldMeshes.GetBool())
|
||||
return V_DrawWorldMeshes(baseEntity, renderContext, worldLists);
|
||||
else
|
||||
return nullptr;
|
||||
@ -18,7 +31,7 @@ void* R_DrawWorldMeshes(void* baseEntity, void* renderContext, DrawWorldLists_t
|
||||
|
||||
void* R_DrawWorldMeshesDepthOnly(void* renderContext, DrawWorldLists_t worldLists)
|
||||
{
|
||||
if (r_drawWorldMeshesDepthOnly->GetBool())
|
||||
if (r_drawWorldMeshesDepthOnly.GetBool())
|
||||
return V_DrawWorldMeshesDepthOnly(renderContext, worldLists);
|
||||
else
|
||||
return nullptr;
|
||||
@ -26,22 +39,16 @@ void* R_DrawWorldMeshesDepthOnly(void* renderContext, DrawWorldLists_t worldList
|
||||
|
||||
void* R_DrawWorldMeshesDepthAtTheEnd(void* ptr1, void* ptr2, void* ptr3, DrawWorldLists_t worldLists)
|
||||
{
|
||||
if (r_drawWorldMeshesDepthAtTheEnd->GetBool())
|
||||
if (r_drawWorldMeshesDepthAtTheEnd.GetBool())
|
||||
return V_DrawWorldMeshesDepthAtTheEnd(ptr1, ptr2, ptr3, worldLists);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VGL_RSurf::Attach() const
|
||||
void VGL_RSurf::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&V_DrawWorldMeshes, &R_DrawWorldMeshes);
|
||||
DetourAttach(&V_DrawWorldMeshesDepthOnly, &R_DrawWorldMeshesDepthOnly);
|
||||
DetourAttach(&V_DrawWorldMeshesDepthAtTheEnd, &R_DrawWorldMeshesDepthAtTheEnd);
|
||||
}
|
||||
|
||||
void VGL_RSurf::Detach() const
|
||||
{
|
||||
DetourDetach(&V_DrawWorldMeshes, &R_DrawWorldMeshes);
|
||||
DetourDetach(&V_DrawWorldMeshesDepthOnly, &R_DrawWorldMeshesDepthOnly);
|
||||
DetourDetach(&V_DrawWorldMeshesDepthAtTheEnd, &R_DrawWorldMeshesDepthAtTheEnd);
|
||||
DetourSetup(&V_DrawDepthOfField, &R_DrawDepthOfField, bAttach);
|
||||
DetourSetup(&V_DrawWorldMeshes, &R_DrawWorldMeshes, bAttach);
|
||||
DetourSetup(&V_DrawWorldMeshesDepthOnly, &R_DrawWorldMeshesDepthOnly, bAttach);
|
||||
DetourSetup(&V_DrawWorldMeshesDepthAtTheEnd, &R_DrawWorldMeshesDepthAtTheEnd, bAttach);
|
||||
}
|
@ -1,13 +1,9 @@
|
||||
#pragma once
|
||||
#include "public/ivrenderview.h"
|
||||
|
||||
inline CMemory P_DrawWorldMeshes;
|
||||
inline void*(*V_DrawDepthOfField)(const float scalar);
|
||||
inline void*(*V_DrawWorldMeshes)(void* baseEntity, void* renderContext, DrawWorldLists_t worldLists);
|
||||
|
||||
inline CMemory P_DrawWorldMeshesDepthOnly;
|
||||
inline void*(*V_DrawWorldMeshesDepthOnly)(void* renderContext, DrawWorldLists_t worldLists);
|
||||
|
||||
inline CMemory P_DrawWorldMeshesDepthAtTheEnd;
|
||||
inline void*(*V_DrawWorldMeshesDepthAtTheEnd)(void* ptr1, void* ptr2, void* ptr3, DrawWorldLists_t worldLists);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -15,27 +11,20 @@ class VGL_RSurf : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("R_DrawWorldMeshes", P_DrawWorldMeshes.GetPtr());
|
||||
LogFunAdr("R_DrawWorldMeshesDepthOnly", P_DrawWorldMeshesDepthOnly.GetPtr());
|
||||
LogFunAdr("R_DrawWorldMeshesDepthAtTheEnd", P_DrawWorldMeshesDepthAtTheEnd.GetPtr());
|
||||
LogFunAdr("R_DrawDepthOfField", V_DrawDepthOfField);
|
||||
LogFunAdr("R_DrawWorldMeshes", V_DrawWorldMeshes);
|
||||
LogFunAdr("R_DrawWorldMeshesDepthOnly", V_DrawWorldMeshesDepthOnly);
|
||||
LogFunAdr("R_DrawWorldMeshesDepthAtTheEnd", V_DrawWorldMeshesDepthAtTheEnd);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
P_DrawWorldMeshes = g_GameDll.FindPatternSIMD("48 8B C4 48 89 48 08 53 48 83 EC 70");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
P_DrawWorldMeshes = g_GameDll.FindPatternSIMD("48 8B C4 48 89 48 08 53 57 41 55");
|
||||
#endif
|
||||
P_DrawWorldMeshesDepthOnly = g_GameDll.FindPatternSIMD("40 56 57 B8 ?? ?? ?? ??");
|
||||
P_DrawWorldMeshesDepthAtTheEnd = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9");
|
||||
|
||||
V_DrawWorldMeshes = P_DrawWorldMeshes.RCast<void* (*)(void*, void*, DrawWorldLists_t)>(); /*48 8B C4 48 89 48 08 53 57 41 55*/
|
||||
V_DrawWorldMeshesDepthOnly = P_DrawWorldMeshesDepthOnly.RCast<void* (*)(void*, DrawWorldLists_t)>(); /*40 56 57 B8 ?? ?? ?? ??*/
|
||||
V_DrawWorldMeshesDepthAtTheEnd = P_DrawWorldMeshesDepthAtTheEnd.RCast<void* (*)(void*, void*, void*, DrawWorldLists_t)>(); /*48 89 5C 24 ?? 48 89 74 24 ? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9*/
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 48 0F 28 E8").GetPtr(V_DrawDepthOfField);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 89 48 08 53 57 41 55").GetPtr(V_DrawWorldMeshes);
|
||||
g_GameDll.FindPatternSIMD("40 56 57 B8 ?? ?? ?? ??").GetPtr(V_DrawWorldMeshesDepthOnly);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9").GetPtr(V_DrawWorldMeshesDepthAtTheEnd);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline CMemory SCR_BeginLoadingPlaque;
|
||||
inline __int64(*v_SCR_BeginLoadingPlaque)(void* a1);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline bool* scr_drawloading = nullptr;
|
||||
@ -14,32 +14,20 @@ class VGL_Screen : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("SCR_BeginLoadingPlaque", SCR_BeginLoadingPlaque.GetPtr());
|
||||
LogVarAdr("scr_drawloading", reinterpret_cast<uintptr_t>(scr_drawloading));
|
||||
LogVarAdr("scr_engineevent_loadingstarted", reinterpret_cast<uintptr_t>(scr_engineevent_loadingstarted));
|
||||
LogFunAdr("SCR_BeginLoadingPlaque", v_SCR_BeginLoadingPlaque);
|
||||
LogVarAdr("scr_drawloading", scr_drawloading);
|
||||
LogVarAdr("scr_engineevent_loadingstarted", scr_engineevent_loadingstarted);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
SCR_BeginLoadingPlaque = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 0F 29 74 24 ?? 48 8B F9");
|
||||
// 0x14022A4A0 // 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 0F 29 74 24 ? 48 8B F9 //
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
SCR_BeginLoadingPlaque = g_GameDll.FindPatternSIMD("48 83 EC 38 0F 29 74 24 ?? 48 89 5C 24 ??");
|
||||
// 0x14022A4A0 // 48 83 EC 38 0F 29 74 24 ? 48 89 5C 24 ? //
|
||||
#endif
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 38 0F 29 74 24 ?? 48 89 5C 24 ??").GetPtr(v_SCR_BeginLoadingPlaque);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
scr_drawloading = g_GameDll.FindPatternSIMD("0F B6 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 83 EC 28").ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
scr_engineevent_loadingstarted = SCR_BeginLoadingPlaque.Offset(0x130).FindPatternSelf("C6 05 ?? ?? ?? ?? 01", CMemory::Direction::DOWN).ResolveRelativeAddress(0x2, 0x7).RCast<bool*>();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
scr_engineevent_loadingstarted = SCR_BeginLoadingPlaque.Offset(0x60).FindPatternSelf("C6 05 ?? ?? ?? ?? 01", CMemory::Direction::DOWN).ResolveRelativeAddress(0x2, 0x7).RCast<bool*>();
|
||||
#endif
|
||||
|
||||
scr_engineevent_loadingstarted = CMemory(v_SCR_BeginLoadingPlaque).Offset(0x60).FindPatternSelf("C6 05 ?? ?? ?? ?? 01", CMemory::Direction::DOWN).ResolveRelativeAddress(0x2, 0x7).RCast<bool*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -9,9 +9,49 @@
|
||||
#include "tier0/frametask.h"
|
||||
#include "engine/host.h"
|
||||
#ifndef DEDICATED
|
||||
#include "windows/id3dx.h"
|
||||
#include "geforce/reflex.h"
|
||||
#include "vgui/vgui_debugpanel.h"
|
||||
#include <materialsystem/cmaterialsystem.h>
|
||||
#endif // !DEDICATED
|
||||
|
||||
CCommonHostState* g_pCommonHostState = nullptr;
|
||||
|
||||
void CCommonHostState::SetWorldModel(model_t* pModel)
|
||||
{
|
||||
if (worldmodel == pModel)
|
||||
return;
|
||||
|
||||
worldmodel = pModel;
|
||||
if (pModel)
|
||||
{
|
||||
worldbrush = pModel->brush.pShared;
|
||||
}
|
||||
else
|
||||
{
|
||||
worldbrush = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_CountRealTimePackets
|
||||
|
||||
Counts the number of
|
||||
packets in non-prescaled
|
||||
clock frames (does not
|
||||
count for bots or Terminal
|
||||
Services environments)
|
||||
==================
|
||||
*/
|
||||
void Host_CountRealTimePackets()
|
||||
{
|
||||
v_Host_CountRealTimePackets();
|
||||
#ifndef DEDICATED
|
||||
GFX_SetLatencyMarker(D3D11Device(), SIMULATION_START, MaterialSystem()->GetCurrentFrameCount());
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
_Host_RunFrame
|
||||
@ -21,24 +61,24 @@ Runs all active servers
|
||||
*/
|
||||
void _Host_RunFrame(void* unused, float time)
|
||||
{
|
||||
for (IFrameTask* const& task : g_FrameTasks)
|
||||
for (IFrameTask* const& task : g_TaskQueueList)
|
||||
{
|
||||
task->RunFrame();
|
||||
}
|
||||
|
||||
g_FrameTasks.erase(std::remove_if(g_FrameTasks.begin(), g_FrameTasks.end(), [](const IFrameTask* task)
|
||||
g_TaskQueueList.erase(std::remove_if(g_TaskQueueList.begin(), g_TaskQueueList.end(), [](const IFrameTask* task)
|
||||
{
|
||||
return task->IsFinished();
|
||||
}), g_FrameTasks.end());
|
||||
}), g_TaskQueueList.end());
|
||||
|
||||
#ifndef DEDICATED
|
||||
g_pOverlay->ShouldDraw(time);
|
||||
g_TextOverlay.ShouldDraw(time);
|
||||
#endif // !DEDICATED
|
||||
|
||||
return v_Host_RunFrame(unused, time);
|
||||
}
|
||||
|
||||
void _Host_Error(char* error, ...)
|
||||
void _Host_Error(const char* error, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
{/////////////////////////////
|
||||
@ -56,20 +96,12 @@ void _Host_Error(char* error, ...)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VHost::Attach() const
|
||||
void VHost::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_Host_RunFrame, &_Host_RunFrame);
|
||||
DetourSetup(&v_Host_RunFrame, &_Host_RunFrame, bAttach);
|
||||
DetourSetup(&v_Host_CountRealTimePackets, &Host_CountRealTimePackets, bAttach);
|
||||
|
||||
#ifndef DEDICATED // Dedicated already logs this!
|
||||
DetourAttach((LPVOID*)&v_Host_Error, &_Host_Error);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
void VHost::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_Host_RunFrame, &_Host_RunFrame);
|
||||
|
||||
#ifndef DEDICATED // Dedicated already logs this!
|
||||
DetourDetach((LPVOID*)&v_Host_Error, &_Host_Error);
|
||||
DetourSetup(&v_Host_Error, &_Host_Error, bAttach);
|
||||
#endif // !DEDICATED
|
||||
}
|
@ -1,86 +1,93 @@
|
||||
#pragma once
|
||||
#include "engine/gl_model_private.h"
|
||||
|
||||
inline CMemory p_Host_RunFrame;
|
||||
inline void(*v_Host_RunFrame)(void* unused, float time);
|
||||
|
||||
//inline CMemory p_Host_RunFrame_Render; // DEDICATED PATCH!
|
||||
//inline void(*v_Host_RunFrame_Render)(void);
|
||||
|
||||
inline CMemory p_Host_ShouldRun;
|
||||
inline void(*v_Host_RunFrame_Render)(void);
|
||||
inline void(*v_Host_CountRealTimePackets)(void);
|
||||
inline bool(*v_Host_ShouldRun)();
|
||||
|
||||
inline CMemory p_Host_Error;
|
||||
inline void(*v_Host_Error)(const char* error, ...);
|
||||
|
||||
//inline CMemory p_VCR_EnterPausedState; // DEDICATED PATCH!
|
||||
//inline void(*v_VCR_EnterPausedState)(void);
|
||||
|
||||
inline bool* g_bAbortServerSet = nullptr;
|
||||
inline float* interval_per_tick = nullptr;
|
||||
|
||||
inline jmp_buf* host_abortserver = nullptr;
|
||||
inline bool* host_initialized = nullptr;
|
||||
inline float* host_frametime_unbounded = nullptr;
|
||||
inline float* host_frametime_stddeviation = nullptr;
|
||||
|
||||
class CCommonHostState
|
||||
{
|
||||
public:
|
||||
CCommonHostState()
|
||||
: worldmodel(NULL)
|
||||
, worldbrush(NULL)
|
||||
, interval_per_tick(0.0f)
|
||||
, max_splitscreen_players(1)
|
||||
, max_splitscreen_players_clientdll(1)
|
||||
{}
|
||||
|
||||
// cl_entitites[0].model
|
||||
model_t* worldmodel;
|
||||
struct worldbrushdata_t* worldbrush;
|
||||
// Tick interval for game
|
||||
float interval_per_tick;
|
||||
// 1, unless a game supports split screen, then probably 2 or 4 (4 is the max allowable)
|
||||
int max_splitscreen_players;
|
||||
// This is the # the client .dll thinks is the max, it might be > max_splitscreen_players in -tools mode, etc.
|
||||
int max_splitscreen_players_clientdll;
|
||||
void SetWorldModel(model_t* pModel);
|
||||
};
|
||||
|
||||
extern CCommonHostState* g_pCommonHostState;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VHost : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("_Host_RunFrame", p_Host_RunFrame.GetPtr());
|
||||
//LogFunAdr("_Host_RunFrame_Render", p_Host_RunFrame_Render.GetPtr());
|
||||
LogFunAdr("Host_ShouldRun", p_Host_ShouldRun.GetPtr());
|
||||
LogFunAdr("Host_Error", p_Host_Error.GetPtr());
|
||||
//LogFunAdr("VCR_EnterPausedState", p_VCR_EnterPausedState.GetPtr());
|
||||
LogVarAdr("g_bAbortServerSet", reinterpret_cast<uintptr_t>(g_bAbortServerSet));
|
||||
LogVarAdr("interval_per_tick", reinterpret_cast<uintptr_t>(interval_per_tick));
|
||||
LogVarAdr("host_abortserver", reinterpret_cast<uintptr_t>(host_abortserver));
|
||||
LogVarAdr("host_initialized", reinterpret_cast<uintptr_t>(host_initialized));
|
||||
LogVarAdr("host_frametime_unbounded", reinterpret_cast<uintptr_t>(host_frametime_unbounded));
|
||||
LogVarAdr("host_frametime_stddeviation", reinterpret_cast<uintptr_t>(host_frametime_stddeviation));
|
||||
LogFunAdr("_Host_RunFrame", v_Host_RunFrame);
|
||||
LogFunAdr("_Host_RunFrame_Render", v_Host_RunFrame_Render);
|
||||
LogFunAdr("Host_CountRealTimePackets", v_Host_CountRealTimePackets);
|
||||
LogFunAdr("Host_ShouldRun", v_Host_ShouldRun);
|
||||
LogFunAdr("Host_Error", v_Host_Error);
|
||||
//LogFunAdr("VCR_EnterPausedState", v_VCR_EnterPausedState);
|
||||
LogVarAdr("g_CommonHostState", g_pCommonHostState);
|
||||
LogVarAdr("g_bAbortServerSet", g_bAbortServerSet);
|
||||
LogVarAdr("host_abortserver", host_abortserver);
|
||||
LogVarAdr("host_initialized", host_initialized);
|
||||
LogVarAdr("host_frametime_unbounded", host_frametime_unbounded);
|
||||
LogVarAdr("host_frametime_stddeviation", host_frametime_stddeviation);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_Host_RunFrame = g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 18 48 89 70 20 F3 0F 11 48 ??");
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
//p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 33 FF");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
//p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 34");
|
||||
#endif
|
||||
p_Host_ShouldRun = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 05 ?? ?? ?? ?? 83 78 6C 00 75 07 B0 01");
|
||||
p_Host_Error = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 48 89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 53 57 48 81 EC ?? ?? ?? ??");
|
||||
//p_VCR_EnterPausedState = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 65 48 8B 04 25 ?? ?? ?? ?? BB ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ??");
|
||||
|
||||
v_Host_RunFrame = p_Host_RunFrame.RCast<void(*)(void*, float)>();
|
||||
//v_Host_RunFrame_Render = p_Host_Error.RCast<void(*)(void)>();
|
||||
v_Host_ShouldRun = p_Host_ShouldRun.RCast<bool(*)()>();
|
||||
v_Host_Error = p_Host_Error.RCast<void(*)(const char*, ...)>();
|
||||
//v_VCR_EnterPausedState = p_VCR_EnterPausedState.RCast<void(*)(void)>();
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 18 48 89 70 20 F3 0F 11 48 ??").GetPtr(v_Host_RunFrame);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 34").GetPtr(v_Host_RunFrame_Render);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 65 48 8B 04 25 ?? ?? ?? ?? 33 DB").GetPtr(v_Host_CountRealTimePackets);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 05 ?? ?? ?? ?? 83 78 6C 00 75 07 B0 01").GetPtr(v_Host_ShouldRun);
|
||||
g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 48 89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 53 57 48 81 EC ?? ?? ?? ??").GetPtr(v_Host_Error);
|
||||
//g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 65 48 8B 04 25 ?? ?? ?? ?? BB ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ??").GetPtr(v_VCR_EnterPausedState);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
interval_per_tick = g_GameDll.FindPatternSIMD("4C 8B DC 4D 89 4B 20 55 56 41 54").FindPatternSelf("F3 0F 5E", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
g_bAbortServerSet = p_Host_Error.FindPattern("40 38 3D", CMemory::Direction::DOWN, 512, 2).ResolveRelativeAddress(3, 7).RCast<bool*>();
|
||||
host_abortserver = p_Host_Error.FindPattern("48 8D 0D", CMemory::Direction::DOWN, 512, 3).ResolveRelativeAddress(3, 7).RCast<jmp_buf*>();
|
||||
g_pCommonHostState = g_GameDll.FindPatternSIMD("48 83 EC 28 84 C9 75 0B")
|
||||
.FindPatternSelf("48 8B 15").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CCommonHostState*>();
|
||||
|
||||
static const int n_host_frametime_unbounded_search_offset = 0x380;
|
||||
static const int n_host_frametime_stddeviation_search_offset = 0x1200;
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
g_bAbortServerSet = p_Host_Error.FindPattern("40 38 3D", CMemory::Direction::DOWN, 512, 4).ResolveRelativeAddress(3, 7).RCast<bool*>();
|
||||
host_abortserver = p_Host_Error.FindPattern("48 8D 0D", CMemory::Direction::DOWN, 512, 5).ResolveRelativeAddress(3, 7).RCast<jmp_buf*>();
|
||||
const CMemory hostErrorBase(v_Host_Error);
|
||||
|
||||
static const int n_host_initialized_search_offset = 0x500; // TODO: S1!!!
|
||||
g_bAbortServerSet = hostErrorBase.FindPattern("40 38 3D", CMemory::Direction::DOWN, 512, 4).ResolveRelativeAddress(3, 7).RCast<bool*>();
|
||||
host_abortserver = hostErrorBase.FindPattern("48 8D 0D", CMemory::Direction::DOWN, 512, 5).ResolveRelativeAddress(3, 7).RCast<jmp_buf*>();
|
||||
|
||||
static const int n_host_initialized_search_offset = 0x500;
|
||||
static const int n_host_frametime_unbounded_search_offset = 0x330;
|
||||
static const int n_host_frametime_stddeviation_search_offset = 0xFAA;
|
||||
#endif
|
||||
host_initialized = p_Host_RunFrame.Offset(n_host_initialized_search_offset).FindPatternSelf("44 38").ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
|
||||
host_frametime_unbounded = p_Host_RunFrame.Offset(n_host_frametime_unbounded_search_offset).FindPatternSelf("F3 0F 11").ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
host_frametime_stddeviation = p_Host_RunFrame.Offset(n_host_frametime_stddeviation_search_offset).FindPatternSelf("F3 0F 11").ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
|
||||
const CMemory hostRunFrameBase(v_Host_RunFrame);
|
||||
|
||||
host_initialized = hostRunFrameBase.Offset(n_host_initialized_search_offset).FindPatternSelf("44 38").ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
|
||||
host_frametime_unbounded = hostRunFrameBase.Offset(n_host_frametime_unbounded_search_offset).FindPatternSelf("F3 0F 11").ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
host_frametime_stddeviation = hostRunFrameBase.Offset(n_host_frametime_stddeviation_search_offset).FindPatternSelf("F3 0F 11").ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -62,7 +62,6 @@ void Host_Status_PrintClient(CClient* client, bool bShowAddress, void (*print) (
|
||||
//print("\n");
|
||||
}
|
||||
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
/*
|
||||
==================
|
||||
DFS_InitializeFeatureFlagDefinitions
|
||||
@ -78,25 +77,13 @@ bool DFS_InitializeFeatureFlagDefinitions(const char* pszFeatureFlags)
|
||||
|
||||
return v_DFS_InitializeFeatureFlagDefinitions(pszFeatureFlags);
|
||||
}
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VHostCmd::Attach() const
|
||||
void VHostCmd::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&v_Host_Shutdown, &Host_Shutdown);
|
||||
DetourAttach(&v_Host_Status_PrintClient, &Host_Status_PrintClient);
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
DetourAttach(&v_DFS_InitializeFeatureFlagDefinitions, &DFS_InitializeFeatureFlagDefinitions);
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
}
|
||||
|
||||
void VHostCmd::Detach() const
|
||||
{
|
||||
DetourDetach(&v_Host_Shutdown, &Host_Shutdown);
|
||||
DetourDetach(&v_Host_Status_PrintClient, &Host_Status_PrintClient);
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
DetourDetach(&v_DFS_InitializeFeatureFlagDefinitions, &DFS_InitializeFeatureFlagDefinitions);
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
DetourSetup(&v_Host_Shutdown, &Host_Shutdown, bAttach);
|
||||
DetourSetup(&v_Host_Status_PrintClient, &Host_Status_PrintClient, bAttach);
|
||||
DetourSetup(&v_DFS_InitializeFeatureFlagDefinitions, &DFS_InitializeFeatureFlagDefinitions, bAttach);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -18,31 +18,17 @@ struct EngineParms_t
|
||||
extern EngineParms_t* g_pEngineParms;
|
||||
|
||||
/* ==== HOST ============================================================================================================================================================ */
|
||||
inline CMemory p_Host_Init;
|
||||
inline void*(*v_Host_Init)(bool* bDedicated);
|
||||
|
||||
inline CMemory p_Host_Shutdown;
|
||||
inline void(*v_Host_Init)();
|
||||
inline void(*v_Host_Init_DuringVideo)(bool* bDedicated);
|
||||
inline void(*v_Host_Init_PostVideo)(bool* bDedicated);
|
||||
inline void(*v_Host_Shutdown)();
|
||||
|
||||
inline CMemory p_Host_NewGame;
|
||||
inline bool(*v_Host_NewGame)(char* pszMapName, char* pszMapGroup, bool bLoadGame, char bBackground, LARGE_INTEGER PerformanceCount);
|
||||
|
||||
inline CMemory p_Host_Disconnect;
|
||||
inline void(*v_Host_Disconnect)(bool bShowMainMenu);
|
||||
|
||||
inline CMemory p_Host_ChangeLevel;
|
||||
inline bool(*v_Host_ChangeLevel)(bool bLoadFromSavedGame, const char* pszMapName, const char* pszMapGroup);
|
||||
|
||||
inline CMemory p_Host_Status_PrintClient;
|
||||
inline void (*v_Host_Status_PrintClient)(CClient* client, bool bShowAddress, void (*print) (const char* fmt, ...));
|
||||
|
||||
inline CMemory p_SetLaunchOptions;
|
||||
inline int(*v_SetLaunchOptions)(const CCommand& args);
|
||||
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
inline CMemory p_DFS_InitializeFeatureFlagDefinitions;
|
||||
inline bool(*v_DFS_InitializeFeatureFlagDefinitions)(const char* pszFeatureFlags);
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
|
||||
extern EngineParms_t* g_pEngineParms;
|
||||
|
||||
@ -51,57 +37,39 @@ class VHostCmd : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("Host_Init", p_Host_Init.GetPtr());
|
||||
LogFunAdr("Host_Shutdown", p_Host_Shutdown.GetPtr());
|
||||
LogFunAdr("Host_Disconnect", p_Host_Disconnect.GetPtr());
|
||||
LogFunAdr("Host_NewGame", p_Host_NewGame.GetPtr());
|
||||
LogFunAdr("Host_ChangeLevel", p_Host_ChangeLevel.GetPtr());
|
||||
LogFunAdr("Host_Status_PrintClient", p_Host_Status_PrintClient.GetPtr());
|
||||
LogFunAdr("SetLaunchOptions", p_SetLaunchOptions.GetPtr());
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
LogFunAdr("DFS_InitializeFeatureFlagDefinitions", p_DFS_InitializeFeatureFlagDefinitions.GetPtr());
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
LogVarAdr("g_pEngineParms", reinterpret_cast<uintptr_t>(g_pEngineParms));
|
||||
LogFunAdr("Host_Init", v_Host_Init);
|
||||
LogFunAdr("Host_Init_DuringVideo", v_Host_Init_DuringVideo);
|
||||
LogFunAdr("Host_Init_PostVideo", v_Host_Init_PostVideo);
|
||||
LogFunAdr("Host_Shutdown", v_Host_Shutdown);
|
||||
LogFunAdr("Host_Disconnect", v_Host_Disconnect);
|
||||
LogFunAdr("Host_NewGame", v_Host_NewGame);
|
||||
LogFunAdr("Host_ChangeLevel", v_Host_ChangeLevel);
|
||||
LogFunAdr("Host_Status_PrintClient", v_Host_Status_PrintClient);
|
||||
LogFunAdr("SetLaunchOptions", v_SetLaunchOptions);
|
||||
|
||||
LogFunAdr("DFS_InitializeFeatureFlagDefinitions", v_DFS_InitializeFeatureFlagDefinitions);
|
||||
LogVarAdr("g_pEngineParms", g_pEngineParms);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_Host_Init = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9 FF 15 ?? ?? ?? ??");
|
||||
p_Host_NewGame = g_GameDll.FindPatternSIMD("48 8B C4 56 41 54 41 57 48 81 EC ?? ?? ?? ?? F2 0F 10 05 ?? ?? ?? ??");
|
||||
p_Host_Disconnect = g_GameDll.FindPatternSIMD("48 83 EC 38 48 89 7C 24 ?? 0F B6 F9");
|
||||
p_Host_ChangeLevel = g_GameDll.FindPatternSIMD("40 53 56 41 56 48 81 EC ?? ?? ?? ?? 49 8B D8");
|
||||
p_SetLaunchOptions = g_GameDll.FindPatternSIMD("48 89 6C 24 ?? 57 48 83 EC 20 48 8B E9 48 8B 0D ?? ?? ?? ??");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_Host_Init = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9");
|
||||
p_Host_NewGame = g_GameDll.FindPatternSIMD("48 8B C4 ?? 41 54 41 55 48 81 EC 70 04 ?? ?? F2 0F 10 05 ?? ?? ?? 0B");
|
||||
p_Host_Disconnect = g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 0F B6 D9");
|
||||
p_Host_ChangeLevel = g_GameDll.FindPatternSIMD("40 56 57 41 56 48 81 EC ?? ?? ?? ??");
|
||||
p_SetLaunchOptions = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 48 8B E9 48 85 DB");
|
||||
#endif
|
||||
p_Host_Shutdown = g_GameDll.FindPatternSIMD("48 8B C4 48 83 EC ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ?? 8B 15 ?? ?? ?? ??");
|
||||
p_Host_Status_PrintClient = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 60 48 8B A9 ?? ?? ?? ??");
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
p_DFS_InitializeFeatureFlagDefinitions = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 40 38 3D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B CE").FollowNearCallSelf();
|
||||
v_DFS_InitializeFeatureFlagDefinitions = p_DFS_InitializeFeatureFlagDefinitions.RCast<bool (*)(const char*)>(); /*48 8B C4 55 53 48 8D 68 E8*/
|
||||
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
|
||||
v_Host_Init = p_Host_Init.RCast<void* (*)(bool*)>(); /*48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9*/
|
||||
v_Host_Shutdown = p_Host_Shutdown.RCast<void (*)()>();
|
||||
v_Host_NewGame = p_Host_NewGame.RCast<bool (*)(char*, char*, bool, char, LARGE_INTEGER)>(); /*48 8B C4 ?? 41 54 41 55 48 81 EC 70 04 00 00 F2 0F 10 05 ?? ?? ?? 0B*/
|
||||
v_Host_Disconnect = p_Host_Disconnect.RCast<void (*)(bool)>();
|
||||
v_Host_ChangeLevel = p_Host_ChangeLevel.RCast<bool (*)(bool, const char*, const char*)>(); /*40 56 57 41 56 48 81 EC ?? ?? ?? ??*/
|
||||
v_Host_Status_PrintClient = p_Host_Status_PrintClient.RCast<void (*)(CClient*, bool, void (*) (const char*, ...))>();
|
||||
v_SetLaunchOptions = p_SetLaunchOptions.RCast<int (*)(const CCommand&)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 48 8B E9 48 85 DB*/
|
||||
g_GameDll.FindPatternSIMD("88 4C 24 08 53 55 56 57 48 83 EC 68").GetPtr(v_Host_Init);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9").GetPtr(v_Host_Init_DuringVideo);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 ?? 41 54 41 55 48 81 EC 70 04 ?? ?? F2 0F 10 05 ?? ?? ?? 0B").GetPtr(v_Host_NewGame);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 0F B6 D9").GetPtr(v_Host_Disconnect);
|
||||
g_GameDll.FindPatternSIMD("40 56 57 41 56 48 81 EC ?? ?? ?? ??").GetPtr(v_Host_ChangeLevel);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 41 56 48 81 EC ?? ?? ?? ?? 45 33 F6").GetPtr(v_Host_Init_PostVideo);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 83 EC ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ?? 8B 15 ?? ?? ?? ??").GetPtr(v_Host_Shutdown);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 60 48 8B A9 ?? ?? ?? ??").GetPtr(v_Host_Status_PrintClient);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 48 8B E9 48 85 DB").GetPtr(v_SetLaunchOptions);
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 40 38 3D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B CE").FollowNearCallSelf().GetPtr(v_DFS_InitializeFeatureFlagDefinitions);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
g_pEngineParms = p_CModAppSystemGroup_Main.FindPattern("48 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7).RCast<EngineParms_t*>();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
g_pEngineParms = p_CModAppSystemGroup_Main.FindPattern("4C 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7).RCast<EngineParms_t*>();
|
||||
#endif
|
||||
g_pEngineParms = CMemory(CModAppSystemGroup__Main).FindPattern("48 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7).RCast<EngineParms_t*>();
|
||||
g_pEngineParms = CMemory(CModAppSystemGroup__Main).FindPattern("4C 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7).RCast<EngineParms_t*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -10,10 +10,10 @@
|
||||
#include "tier0/jobthread.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "tier0/fasttimer.h"
|
||||
#include "tier0/frametask.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "tier1/NetAdr.h"
|
||||
#include "tier2/socketcreator.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "datacache/mdlcache.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/sv_rcon.h"
|
||||
@ -35,17 +35,19 @@
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/server.h"
|
||||
#include "rtech/liveapi/liveapi.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "rtech/rtech_game.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "rtech/stryder/stryder.h"
|
||||
#include "rtech/playlists/playlists.h"
|
||||
#ifndef DEDICATED
|
||||
#include "vgui/vgui_baseui_interface.h"
|
||||
#include "client/vengineclient_impl.h"
|
||||
#include "gameui/imgui_system.h"
|
||||
#endif // DEDICATED
|
||||
#include "networksystem/pylon.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "networksystem/bansystem.h"
|
||||
#include "networksystem/hostmanager.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#include "networksystem/listmanager.h"
|
||||
#include "public/edict.h"
|
||||
@ -55,44 +57,84 @@
|
||||
#include "game/shared/vscript_shared.h"
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
static ConVar sv_pylonVisibility("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", "0 = Offline, 1 = Hidden, 2 = Public.");
|
||||
static ConVar sv_pylonRefreshRate("sv_pylonRefreshRate", "5.0", FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds).");
|
||||
|
||||
static ConVar sv_autoReloadRate("sv_autoReloadRate", "0", FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null).");
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
#ifdef DEDICATED
|
||||
static ConVar hostdesc("hostdesc", "", FCVAR_RELEASE, "Host game server description.");
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Send keep alive request to Pylon Master Server.
|
||||
// Input : &netGameServer -
|
||||
// Output : Returns true on success, false otherwise.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool HostState_KeepAlive(const NetGameServer_t& netGameServer)
|
||||
static void HostState_KeepAlive()
|
||||
{
|
||||
if (!g_pServer->IsActive() || !sv_pylonVisibility->GetBool()) // Check for active game.
|
||||
if (!g_pServer->IsActive() || !sv_pylonVisibility.GetBool()) // Check for active game.
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
const NetGameServer_t gameServer
|
||||
{
|
||||
hostname->GetString(),
|
||||
hostdesc.GetString(),
|
||||
sv_pylonVisibility.GetInt() == ServerVisibility_e::HIDDEN,
|
||||
g_pHostState->m_levelName,
|
||||
v_Playlists_GetCurrent(),
|
||||
hostip->GetString(),
|
||||
hostport->GetInt(),
|
||||
g_pNetKey->GetBase64NetKey(),
|
||||
*g_nServerRemoteChecksum,
|
||||
SDK_VERSION,
|
||||
g_pServer->GetNumClients(),
|
||||
g_ServerGlobalVariables->m_nMaxClients,
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()
|
||||
).count()
|
||||
};
|
||||
|
||||
std::thread request([&, gameServer]
|
||||
{
|
||||
string errorMsg;
|
||||
string hostToken;
|
||||
string hostIp;
|
||||
|
||||
const bool result = g_pMasterServer->PostServerHost(errorMsg, hostToken, netGameServer);
|
||||
const bool result = g_MasterServer.PostServerHost(errorMsg, hostToken, hostIp, gameServer);
|
||||
|
||||
// Apply the data the next frame
|
||||
g_TaskQueue.Dispatch([result, errorMsg, hostToken, hostIp]
|
||||
{
|
||||
if (!result)
|
||||
{
|
||||
if (!errorMsg.empty() && g_pMasterServer->GetCurrentError().compare(errorMsg) != NULL)
|
||||
if (!errorMsg.empty() && g_ServerHostManager.GetCurrentError().compare(errorMsg) != NULL)
|
||||
{
|
||||
g_pMasterServer->SetCurrentError(errorMsg);
|
||||
g_ServerHostManager.SetCurrentError(errorMsg);
|
||||
Error(eDLL_T::SERVER, NO_ERROR, "%s\n", errorMsg.c_str());
|
||||
}
|
||||
}
|
||||
else // Attempt to log the token, if there is one.
|
||||
{
|
||||
if (!hostToken.empty() && g_pMasterServer->GetCurrentToken().compare(hostToken) != NULL)
|
||||
if (!hostToken.empty() && g_ServerHostManager.GetCurrentToken().compare(hostToken) != NULL)
|
||||
{
|
||||
g_pMasterServer->SetCurrentToken(hostToken);
|
||||
DevMsg(eDLL_T::SERVER, "Published server with token: %s'%s%s%s'\n",
|
||||
g_ServerHostManager.SetCurrentToken(hostToken);
|
||||
Msg(eDLL_T::SERVER, "Published server with token: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB,
|
||||
hostToken.c_str(), g_svReset);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
if (hostIp.length() != 0)
|
||||
g_ServerHostManager.SetHostIP(hostIp);
|
||||
|
||||
}, 0);
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
);
|
||||
|
||||
request.detach();
|
||||
}
|
||||
#endif // DEDICATED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: state machine's main processing loop
|
||||
@ -115,8 +157,6 @@ void CHostState::FrameUpdate(CHostState* pHostState, double flCurrentTime, float
|
||||
RCONClient()->RunFrame();
|
||||
#endif // !DEDICATED
|
||||
|
||||
HostStates_t oldState{};
|
||||
|
||||
// Disable "warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable"
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4611)
|
||||
@ -131,11 +171,11 @@ void CHostState::FrameUpdate(CHostState* pHostState, double flCurrentTime, float
|
||||
#ifndef CLIENT_DLL
|
||||
*g_bAbortServerSet = true;
|
||||
#endif // !CLIENT_DLL
|
||||
do
|
||||
while (true)
|
||||
{
|
||||
Cbuf_Execute();
|
||||
oldState = g_pHostState->m_iCurrentState;
|
||||
|
||||
const HostStates_t oldState = g_pHostState->m_iCurrentState;
|
||||
switch (g_pHostState->m_iCurrentState)
|
||||
{
|
||||
case HostStates_t::HS_NEW_GAME:
|
||||
@ -168,32 +208,32 @@ void CHostState::FrameUpdate(CHostState* pHostState, double flCurrentTime, float
|
||||
bResetIdleName = true;
|
||||
}
|
||||
|
||||
CHostState_State_Run(&g_pHostState->m_iCurrentState, flCurrentTime, flFrameTime);
|
||||
CHostState__State_Run(&g_pHostState->m_iCurrentState, flCurrentTime, flFrameTime);
|
||||
break;
|
||||
}
|
||||
case HostStates_t::HS_GAME_SHUTDOWN:
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Shutdown host game\n", __FUNCTION__);
|
||||
CHostState_State_GameShutDown(g_pHostState);
|
||||
Msg(eDLL_T::ENGINE, "%s: Shutdown host game\n", __FUNCTION__);
|
||||
CHostState__State_GameShutDown(g_pHostState);
|
||||
break;
|
||||
}
|
||||
case HostStates_t::HS_RESTART:
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Restarting state machine\n", __FUNCTION__);
|
||||
Msg(eDLL_T::ENGINE, "%s: Restarting state machine\n", __FUNCTION__);
|
||||
#ifndef DEDICATED
|
||||
CL_EndMovie();
|
||||
v_CL_EndMovie();
|
||||
#endif // !DEDICATED
|
||||
Stryder_SendOfflineRequest(); // We have hostnames nulled anyway.
|
||||
v_Stryder_SendOfflineRequest(); // We have hostnames nulled anyway.
|
||||
g_pEngine->SetNextState(IEngine::DLL_RESTART);
|
||||
break;
|
||||
}
|
||||
case HostStates_t::HS_SHUTDOWN:
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Shutdown state machine\n", __FUNCTION__);
|
||||
Msg(eDLL_T::ENGINE, "%s: Shutdown state machine\n", __FUNCTION__);
|
||||
#ifndef DEDICATED
|
||||
CL_EndMovie();
|
||||
v_CL_EndMovie();
|
||||
#endif // !DEDICATED
|
||||
Stryder_SendOfflineRequest(); // We have hostnames nulled anyway.
|
||||
v_Stryder_SendOfflineRequest(); // We have hostnames nulled anyway.
|
||||
g_pEngine->SetNextState(IEngine::DLL_CLOSE);
|
||||
break;
|
||||
}
|
||||
@ -203,10 +243,15 @@ void CHostState::FrameUpdate(CHostState* pHostState, double flCurrentTime, float
|
||||
}
|
||||
}
|
||||
|
||||
} while (
|
||||
(oldState != HostStates_t::HS_RUN || g_pHostState->m_iNextState == HostStates_t::HS_LOAD_GAME && single_frame_shutdown_for_reload->GetBool())
|
||||
&& oldState != HostStates_t::HS_SHUTDOWN
|
||||
&& oldState != HostStates_t::HS_RESTART);
|
||||
// only do a single pass at HS_RUN per frame. All other states loop until they reach HS_RUN
|
||||
if (oldState == HostStates_t::HS_RUN && (g_pHostState->m_iNextState != HostStates_t::HS_LOAD_GAME || !single_frame_shutdown_for_reload->GetBool()))
|
||||
break;
|
||||
|
||||
// shutting down
|
||||
if (oldState == HostStates_t::HS_SHUTDOWN ||
|
||||
oldState == HostStates_t::HS_RESTART)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +264,7 @@ void CHostState::Init(void)
|
||||
{
|
||||
if (m_iNextState == HostStates_t::HS_GAME_SHUTDOWN)
|
||||
{
|
||||
CHostState_State_GameShutDown(this);
|
||||
CHostState__State_GameShutDown(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -250,7 +295,7 @@ void CHostState::Setup(void)
|
||||
{
|
||||
g_pHostState->LoadConfig();
|
||||
#ifndef CLIENT_DLL
|
||||
g_pBanSystem->Load();
|
||||
g_BanSystem.LoadList();
|
||||
#endif // !CLIENT_DLL
|
||||
ConVar_PurgeHostNames();
|
||||
|
||||
@ -261,7 +306,11 @@ void CHostState::Setup(void)
|
||||
RCONClient()->Init();
|
||||
#endif // !DEDICATED
|
||||
|
||||
if (net_useRandomKey->GetBool())
|
||||
#ifndef CLIENT_DLL
|
||||
LiveAPISystem()->Init();
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
if (net_useRandomKey.GetBool())
|
||||
{
|
||||
NET_GenerateKey();
|
||||
}
|
||||
@ -301,50 +350,33 @@ void CHostState::Think(void) const
|
||||
#endif // DEDICATED
|
||||
bInitialized = true;
|
||||
}
|
||||
if (sv_autoReloadRate->GetBool())
|
||||
if (sv_autoReloadRate.GetBool())
|
||||
{
|
||||
if (g_ServerGlobalVariables->m_flCurTime > sv_autoReloadRate->GetDouble())
|
||||
if (g_ServerGlobalVariables->m_flCurTime > sv_autoReloadRate.GetFloat())
|
||||
{
|
||||
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "reload\n", cmd_source_t::kCommandSrcCode);
|
||||
}
|
||||
}
|
||||
if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshRate->GetDouble())
|
||||
if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshRate.GetFloat())
|
||||
{
|
||||
SetConsoleTitleA(Format("%s - %d/%d Players (%s on %s)",
|
||||
SetConsoleTitleA(Format("%s - %d/%d Players (%s on %s) - %d%% Server CPU (%.3f msec on frame %d)",
|
||||
hostname->GetString(), g_pServer->GetNumClients(),
|
||||
g_ServerGlobalVariables->m_nMaxClients, KeyValues_GetCurrentPlaylist(), m_levelName).c_str());
|
||||
g_ServerGlobalVariables->m_nMaxClients, v_Playlists_GetCurrent(), m_levelName,
|
||||
static_cast<int>(g_pServer->GetCPUUsage() * 100.0f), (g_pEngine->GetFrameTime() * 1000.0f),
|
||||
g_pServer->GetTick()).c_str());
|
||||
|
||||
statsTimer.Start();
|
||||
}
|
||||
if (sv_globalBanlist->GetBool() &&
|
||||
banListTimer.GetDurationInProgress().GetSeconds() > sv_banlistRefreshRate->GetDouble())
|
||||
if (sv_globalBanlist.GetBool() &&
|
||||
banListTimer.GetDurationInProgress().GetSeconds() > sv_banlistRefreshRate.GetFloat())
|
||||
{
|
||||
SV_CheckForBan();
|
||||
SV_CheckClientsForBan();
|
||||
banListTimer.Start();
|
||||
}
|
||||
#ifdef DEDICATED
|
||||
if (pylonTimer.GetDurationInProgress().GetSeconds() > sv_pylonRefreshRate->GetDouble())
|
||||
if (pylonTimer.GetDurationInProgress().GetSeconds() > sv_pylonRefreshRate.GetFloat())
|
||||
{
|
||||
const NetGameServer_t netGameServer
|
||||
{
|
||||
hostname->GetString(),
|
||||
hostdesc->GetString(),
|
||||
sv_pylonVisibility->GetInt() == EServerVisibility_t::HIDDEN,
|
||||
g_pHostState->m_levelName,
|
||||
KeyValues_GetCurrentPlaylist(),
|
||||
hostip->GetString(),
|
||||
hostport->GetString(),
|
||||
g_pNetKey->GetBase64NetKey(),
|
||||
std::to_string(*g_nServerRemoteChecksum),
|
||||
SDK_VERSION,
|
||||
std::to_string(g_pServer->GetNumClients()),
|
||||
std::to_string(g_ServerGlobalVariables->m_nMaxClients),
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()
|
||||
).count()
|
||||
};
|
||||
|
||||
std::thread(&HostState_KeepAlive, netGameServer).detach();
|
||||
HostState_KeepAlive();
|
||||
pylonTimer.Start();
|
||||
}
|
||||
#endif // DEDICATED
|
||||
@ -388,6 +420,24 @@ void CHostState::LoadConfig(void) const
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: set state machine
|
||||
// Input : newState -
|
||||
// clearNext -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHostState::SetState(const HostStates_t newState)
|
||||
{
|
||||
m_iCurrentState = newState;
|
||||
|
||||
// If our next state isn't a shutdown, or its a forced shutdown then set
|
||||
// next state to run.
|
||||
if (m_iNextState != HostStates_t::HS_SHUTDOWN ||
|
||||
!host_hasIrreversibleShutdown->GetBool())
|
||||
{
|
||||
m_iNextState = newState;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: shutdown active game
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -408,13 +458,13 @@ void CHostState::GameShutDown(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHostState::State_NewGame(void)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Loading level: '%s'\n", __FUNCTION__, g_pHostState->m_levelName);
|
||||
Msg(eDLL_T::ENGINE, "%s: Loading level: '%s'\n", __FUNCTION__, g_pHostState->m_levelName);
|
||||
|
||||
LARGE_INTEGER time{};
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
bool bSplitScreenConnect = m_bSplitScreenConnect;
|
||||
m_bSplitScreenConnect = 0;
|
||||
const bool bSplitScreenConnect = m_bSplitScreenConnect;
|
||||
m_bSplitScreenConnect = false;
|
||||
|
||||
if (!g_pServerGameClients) // Init Game if it ain't valid.
|
||||
{
|
||||
@ -434,13 +484,7 @@ void CHostState::State_NewGame(void)
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run.
|
||||
|
||||
// If our next state isn't a shutdown or its a forced shutdown then set next state to run.
|
||||
if (m_iNextState != HostStates_t::HS_SHUTDOWN || !host_hasIrreversibleShutdown->GetBool())
|
||||
{
|
||||
m_iNextState = HostStates_t::HS_RUN;
|
||||
}
|
||||
SetState(HostStates_t::HS_RUN);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -448,7 +492,7 @@ void CHostState::State_NewGame(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHostState::State_ChangeLevelSP(void)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Changing singleplayer level to: '%s'\n", __FUNCTION__, m_levelName);
|
||||
Msg(eDLL_T::ENGINE, "%s: Changing singleplayer level to: '%s'\n", __FUNCTION__, m_levelName);
|
||||
m_flShortFrameTime = 1.5; // Set frame time.
|
||||
|
||||
if (CModelLoader__Map_IsValid(g_pModelLoader, m_levelName)) // Check if map is valid and if we can start a new game.
|
||||
@ -460,13 +504,8 @@ void CHostState::State_ChangeLevelSP(void)
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "%s: Unable to find level: '%s'\n", __FUNCTION__, m_levelName);
|
||||
}
|
||||
|
||||
m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run.
|
||||
|
||||
// If our next state isn't a shutdown or its a forced shutdown then set next state to run.
|
||||
if (m_iNextState != HostStates_t::HS_SHUTDOWN || !host_hasIrreversibleShutdown->GetBool())
|
||||
{
|
||||
m_iNextState = HostStates_t::HS_RUN;
|
||||
}
|
||||
// Set current state to run.
|
||||
SetState(HostStates_t::HS_RUN);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -474,7 +513,7 @@ void CHostState::State_ChangeLevelSP(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHostState::State_ChangeLevelMP(void)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%s: Changing multiplayer level to: '%s'\n", __FUNCTION__, m_levelName);
|
||||
Msg(eDLL_T::ENGINE, "%s: Changing multiplayer level to: '%s'\n", __FUNCTION__, m_levelName);
|
||||
m_flShortFrameTime = 0.5; // Set frame time.
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
@ -492,13 +531,8 @@ void CHostState::State_ChangeLevelMP(void)
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "%s: Unable to find level: '%s'\n", __FUNCTION__, m_levelName);
|
||||
}
|
||||
|
||||
m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run.
|
||||
|
||||
// If our next state isn't a shutdown or its a forced shutdown then set next state to run.
|
||||
if (m_iNextState != HostStates_t::HS_SHUTDOWN || !host_hasIrreversibleShutdown->GetBool())
|
||||
{
|
||||
m_iNextState = HostStates_t::HS_RUN;
|
||||
}
|
||||
// Set current state to run.
|
||||
SetState(HostStates_t::HS_RUN);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -510,13 +544,9 @@ void CHostState::ResetLevelName(void)
|
||||
Q_snprintf(const_cast<char*>(m_levelName), sizeof(m_levelName), "%s", szNoMap);
|
||||
}
|
||||
|
||||
void VHostState::Attach(void) const
|
||||
void VHostState::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach(&CHostState_FrameUpdate, &CHostState::FrameUpdate);
|
||||
}
|
||||
void VHostState::Detach(void) const
|
||||
{
|
||||
DetourDetach(&CHostState_FrameUpdate, &CHostState::FrameUpdate);
|
||||
DetourSetup(&CHostState__FrameUpdate, &CHostState::FrameUpdate, bAttach);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -23,9 +23,10 @@ public:
|
||||
void Setup(void);
|
||||
void Think(void) const;
|
||||
|
||||
void SetState(const HostStates_t newState);
|
||||
void GameShutDown(void);
|
||||
void State_NewGame(void);
|
||||
|
||||
void State_NewGame(void);
|
||||
void State_ChangeLevelSP(void);
|
||||
void State_ChangeLevelMP(void);
|
||||
|
||||
@ -50,16 +51,9 @@ public:
|
||||
};
|
||||
|
||||
/* ==== CHOSTSTATE ====================================================================================================================================================== */
|
||||
inline CMemory p_CHostState_FrameUpdate;
|
||||
inline void(*CHostState_FrameUpdate)(CHostState* pHostState, double flCurrentTime, float flFrameTime);
|
||||
|
||||
inline CMemory p_CHostState_State_Run;
|
||||
inline void(*CHostState_State_Run)(HostStates_t* pState, double flCurrentTime, float flFrameTime);
|
||||
|
||||
inline CMemory p_CHostState_State_GameShutDown;
|
||||
inline void(*CHostState_State_GameShutDown)(CHostState* thisptr);
|
||||
|
||||
inline CMemory p_HostState_ChangeLevelMP;
|
||||
inline void(*CHostState__FrameUpdate)(CHostState* pHostState, double flCurrentTime, float flFrameTime);
|
||||
inline void(*CHostState__State_Run)(HostStates_t* pState, double flCurrentTime, float flFrameTime);
|
||||
inline void(*CHostState__State_GameShutDown)(CHostState* thisptr);
|
||||
inline void(*v_HostState_ChangeLevelMP)(char const* pNewLevel, char const* pLandmarkName);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -70,36 +64,24 @@ class VHostState : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CHostState::FrameUpdate", p_CHostState_FrameUpdate.GetPtr());
|
||||
LogFunAdr("CHostState::State_Run", p_CHostState_State_Run.GetPtr());
|
||||
LogFunAdr("CHostState::State_GameShutDown", p_CHostState_State_GameShutDown.GetPtr());
|
||||
LogFunAdr("HostState_ChangeLevelMP", p_HostState_ChangeLevelMP.GetPtr());
|
||||
LogVarAdr("g_pHostState", reinterpret_cast<uintptr_t>(g_pHostState));
|
||||
LogFunAdr("CHostState::FrameUpdate", CHostState__FrameUpdate);
|
||||
LogFunAdr("CHostState::State_Run", CHostState__State_Run);
|
||||
LogFunAdr("CHostState::State_GameShutDown", CHostState__State_GameShutDown);
|
||||
LogFunAdr("HostState_ChangeLevelMP", v_HostState_ChangeLevelMP);
|
||||
LogVarAdr("g_pHostState", g_pHostState);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_CHostState_FrameUpdate = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 20 F3 0F 11 54 24 18");
|
||||
p_CHostState_State_Run = g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 0F 29 70 C8 45 33 E4");
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CHostState_State_GameShutDown = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 56 48 83 EC 20 8B 05 ?? ?? ?? ?? 48 8B F1");
|
||||
#elif defined (GAMEDLL_S2)
|
||||
p_CHostState_State_GameShutDown = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 8B 05 ?? ?? ?? ?? 33 FF 48 8B F1");
|
||||
#elif defined (GAMEDLL_S3)
|
||||
p_CHostState_State_GameShutDown = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ??");
|
||||
#endif
|
||||
p_HostState_ChangeLevelMP = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 48 8B F2 8B 0D ?? ?? ?? ??");
|
||||
|
||||
CHostState_FrameUpdate = p_CHostState_FrameUpdate.RCast<void(*)(CHostState*, double, float)>(); /*48 89 5C 24 08 48 89 6C 24 20 F3 0F 11 54 24 18*/
|
||||
CHostState_State_Run = p_CHostState_State_Run.RCast<void(*)(HostStates_t*, double, float)>(); /*48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 0F 29 70 C8 45 33 E4*/
|
||||
CHostState_State_GameShutDown = p_CHostState_State_GameShutDown.RCast<void(*)(CHostState* thisptr)>(); /*48 89 5C 24 ?? 57 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ??*/
|
||||
v_HostState_ChangeLevelMP = p_HostState_ChangeLevelMP.RCast<void(*)(char const*, char const*)>(); /*48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B F9 48 8B F2 8B 0D ? ? ? ?*/
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 20 F3 0F 11 54 24 18").GetPtr(CHostState__FrameUpdate);
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 0F 29 70 C8 45 33 E4").GetPtr(CHostState__State_Run);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ??").GetPtr(CHostState__State_GameShutDown);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 48 8B F2 8B 0D ?? ?? ?? ??").GetPtr(v_HostState_ChangeLevelMP);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_pHostState = p_CHostState_FrameUpdate.FindPattern("48 8D ?? ?? ?? ?? 01", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CHostState*>();
|
||||
g_pHostState = CMemory(CHostState__FrameUpdate).FindPattern("48 8D ?? ?? ?? ?? 01", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CHostState*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
36
r5dev/engine/keys.cpp
Normal file
36
r5dev/engine/keys.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "keys.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "geforce/reflex.h"
|
||||
#include <materialsystem/cmaterialsystem.h>
|
||||
|
||||
KeyInfo_t* g_pKeyInfo = nullptr;
|
||||
ButtonCode_t* g_pKeyEventTicks = nullptr;
|
||||
short* g_nKeyEventCount = nullptr;
|
||||
|
||||
|
||||
bool Input_Event(const InputEvent_t& inputEvent, const int noKeyUpCheck)
|
||||
{
|
||||
bool runTriggerMarker = inputEvent.m_nData == ButtonCode_t::MOUSE_LEFT;
|
||||
const KeyInfo_t& keyInfo = g_pKeyInfo[inputEvent.m_nData];
|
||||
|
||||
if (noKeyUpCheck)
|
||||
{
|
||||
const int v = (inputEvent.m_nType & 0xFFFFFFFD) == 0;
|
||||
|
||||
if (keyInfo.m_nKeyDownTarget == v)
|
||||
runTriggerMarker = false;
|
||||
}
|
||||
|
||||
if (runTriggerMarker && (inputEvent.m_nType != IE_ButtonReleased || keyInfo.m_bTrapKeyUp))
|
||||
{
|
||||
GFX_SetLatencyMarker(D3D11Device(), TRIGGER_FLASH, MaterialSystem()->GetCurrentFrameCount());
|
||||
}
|
||||
|
||||
return v_Input_Event(inputEvent, noKeyUpCheck);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VKeys::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourSetup(&v_Input_Event, &Input_Event, bAttach);
|
||||
}
|
81
r5dev/engine/keys.h
Normal file
81
r5dev/engine/keys.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef ENGINE_KEYS_H
|
||||
#define ENGINE_KEYS_H
|
||||
#include "inputsystem/ButtonCode.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Keypress event
|
||||
//-----------------------------------------------------------------------------
|
||||
struct KeyEvent_t
|
||||
{
|
||||
const char* m_pCommand;
|
||||
int m_nTick;
|
||||
bool m_bDown;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Current keypress state
|
||||
//-----------------------------------------------------------------------------
|
||||
struct KeyInfo_t
|
||||
{
|
||||
enum
|
||||
{
|
||||
KEY_TAPPED_BIND = 0,
|
||||
KEY_HELD_BIND,
|
||||
|
||||
KEY_BIND_COUNT
|
||||
};
|
||||
|
||||
const char* m_pKeyBinding[KEY_BIND_COUNT];
|
||||
int m_nKeyUpTarget;
|
||||
int m_nKeyDownTarget;
|
||||
|
||||
uint32_t m_nEventTick; // When was the event issued?
|
||||
int unknown;
|
||||
short m_nEventNumber; // The event number.
|
||||
|
||||
bool m_bKeyDown;
|
||||
bool m_bEventIsButtonKey; // Is the event a button key (< ButtonCode_t::KEY_LAST)
|
||||
bool m_bTrapKeyUp;
|
||||
bool m_bBoundSecondKey; // Is the key bound to the second row?
|
||||
|
||||
short paddingMaybe;
|
||||
};
|
||||
|
||||
inline bool (*v_Input_Event)(const InputEvent_t& inputEvent, const int noKeyUpCheck);
|
||||
inline bool(*v_Key_Event)(const KeyEvent_t& keyEvent);
|
||||
|
||||
extern KeyInfo_t* g_pKeyInfo; // ARRAYSIZE = ButtonCode_t::BUTTON_CODE_LAST
|
||||
extern ButtonCode_t* g_pKeyEventTicks; // ARRAYSIZE = ButtonCode_t::BUTTON_CODE_LAST
|
||||
extern short* g_nKeyEventCount;
|
||||
|
||||
class VKeys : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("Input_Event", v_Input_Event);
|
||||
LogFunAdr("Key_Event", v_Key_Event);
|
||||
LogVarAdr("g_pKeyInfo", g_pKeyInfo);
|
||||
LogVarAdr("g_pKeyEventTicks", g_pKeyEventTicks);
|
||||
LogVarAdr("g_nKeyEventCount", g_nKeyEventCount);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 56").GetPtr(v_Input_Event);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 4C 63 41 08").GetPtr(v_Key_Event);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_pKeyInfo = g_GameDll.FindPatternSIMD("48 83 EC 28 33 D2 48 8D 0D ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 C0 C6 05 ?? ?? ?? ?? ??")
|
||||
.FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 40).ResolveRelativeAddressSelf(3, 7).RCast<KeyInfo_t*>();
|
||||
|
||||
CMemory l_EngineApi_PumpMessages = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 81 EC ?? ?? ?? ?? 45 33 C9");
|
||||
|
||||
// NOTE: g_nKeyEventCount's pattern is found earlier, thus searched for earlier to offset base for g_pKeyEventTicks.
|
||||
g_nKeyEventCount = l_EngineApi_PumpMessages.FindPatternSelf("0F B7 15").ResolveRelativeAddressSelf(3, 7).RCast<short*>();
|
||||
g_pKeyEventTicks = l_EngineApi_PumpMessages.FindPatternSelf("48 8D 35").ResolveRelativeAddressSelf(3, 7).RCast<ButtonCode_t*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
|
||||
#endif // ENGINE_KEYS_H
|
@ -26,12 +26,7 @@ bool UpdateCurrentVideoConfig(MaterialSystem_Config_t* pConfig)
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VMatSys_Interface::Attach() const
|
||||
void VMatSys_Interface::Detour(const bool bAttach) const
|
||||
{
|
||||
//DetourAttach(&v_UpdateCurrentVideoConfig, &UpdateCurrentVideoConfig);
|
||||
}
|
||||
|
||||
void VMatSys_Interface::Detach() const
|
||||
{
|
||||
//DetourDetach(&v_UpdateCurrentVideoConfig, &UpdateCurrentVideoConfig);
|
||||
//DetourSetup(&v_UpdateCurrentVideoConfig, &UpdateCurrentVideoConfig, bAttach);
|
||||
}
|
@ -2,17 +2,16 @@
|
||||
#define MATSYS_INTERFACE_H
|
||||
|
||||
#include "public/imaterialsystem.h"
|
||||
#include "public/inputsystem/ButtonCode.h"
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: GAME_CFG
|
||||
//-------------------------------------------------------------------------
|
||||
inline CMemory p_UpdateCurrentVideoConfig;
|
||||
inline CMemory p_UpdateMaterialSystemConfig;
|
||||
inline CMemory p_HandleConfigFile;
|
||||
inline CMemory p_ResetPreviousGameState;
|
||||
inline CMemory p_LoadPlayerConfig;
|
||||
|
||||
inline bool(*v_UpdateCurrentVideoConfig)(MaterialSystem_Config_t* pConfig);
|
||||
inline void(*v_UpdateMaterialSystemConfig)(void);
|
||||
inline bool(*v_UpdateCurrentVideoConfig)(MaterialSystem_Config_t* const pConfig);
|
||||
inline bool(*v_HandleConfigFile)(const int configType); //(saved games cfg) 0 = local, 1 = profile.
|
||||
inline void(*v_ResetPreviousGameState)(void);
|
||||
inline void(*v_LoadPlayerConfig)(ButtonCode_t buttonCode, void* unused);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -20,30 +19,23 @@ class VMatSys_Interface : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("UpdateMaterialSystemConfig", p_UpdateMaterialSystemConfig.GetPtr());
|
||||
LogFunAdr("UpdateCurrentVideoConfig", p_UpdateCurrentVideoConfig.GetPtr());
|
||||
LogFunAdr("HandleConfigFile", p_HandleConfigFile.GetPtr());
|
||||
LogFunAdr("ResetPreviousGameState", p_ResetPreviousGameState.GetPtr());
|
||||
LogFunAdr("LoadPlayerConfig", p_LoadPlayerConfig.GetPtr());
|
||||
LogFunAdr("UpdateMaterialSystemConfig", v_UpdateMaterialSystemConfig);
|
||||
LogFunAdr("UpdateCurrentVideoConfig", v_UpdateCurrentVideoConfig);
|
||||
LogFunAdr("HandleConfigFile", v_HandleConfigFile);
|
||||
LogFunAdr("ResetPreviousGameState", v_ResetPreviousGameState);
|
||||
LogFunAdr("LoadPlayerConfig", v_LoadPlayerConfig);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_UpdateMaterialSystemConfig = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 80 3D ?? ?? ?? ?? ?? 0F 84 ?? ?? ?? ??");
|
||||
p_UpdateCurrentVideoConfig = g_GameDll.FindPatternSIMD("40 55 ?? 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 4C 8B F1");
|
||||
p_HandleConfigFile = g_GameDll.FindPatternSIMD("40 56 48 81 EC ?? ?? ?? ?? 8B F1");
|
||||
p_ResetPreviousGameState = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 44 89 3D ?? ?? ?? ?? ?? 8B ?? 24 ??").ResolveRelativeAddressSelf(0x1, 0x5);
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
p_LoadPlayerConfig = g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 48 83 3D ?? ?? ?? ?? ?? 75 0C");
|
||||
#elif defined (GAMEDLL_S3)
|
||||
p_LoadPlayerConfig = g_GameDll.FindPatternSIMD("E9 ?? ?? ?? ?? CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 30 4D 8B D1").FollowNearCallSelf();
|
||||
#endif
|
||||
|
||||
v_UpdateCurrentVideoConfig = p_UpdateCurrentVideoConfig.RCast<bool (*)(MaterialSystem_Config_t*)>();
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 80 3D ?? ?? ?? ?? ?? 0F 84 ?? ?? ?? ??").GetPtr(v_UpdateMaterialSystemConfig);
|
||||
g_GameDll.FindPatternSIMD("40 55 ?? 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 4C 8B F1").GetPtr(v_UpdateCurrentVideoConfig);
|
||||
g_GameDll.FindPatternSIMD("40 56 48 81 EC ?? ?? ?? ?? 8B F1").GetPtr(v_HandleConfigFile);
|
||||
g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 44 89 3D ?? ?? ?? ?? ?? 8B ?? 24 ??").ResolveRelativeAddressSelf(0x1, 0x5).GetPtr(v_ResetPreviousGameState);
|
||||
g_GameDll.FindPatternSIMD("E9 ?? ?? ?? ?? CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 30 4D 8B D1").FollowNearCallSelf().GetPtr(v_LoadPlayerConfig);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -41,10 +41,10 @@ class VModelInfo : public IDetour
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
LogFunAdr("g_pModelInfoServer", reinterpret_cast<uintptr_t>(g_pModelInfoServer));
|
||||
LogFunAdr("g_pModelInfoServer", g_pModelInfoServer);
|
||||
#endif // CLIENT_DLL
|
||||
#ifndef DEDICATED
|
||||
LogFunAdr("g_pModelInfoClient", reinterpret_cast<uintptr_t>(g_pModelInfoClient));
|
||||
LogFunAdr("g_pModelInfoClient", g_pModelInfoClient);
|
||||
#endif // DEDICATED
|
||||
}
|
||||
virtual void GetFun(void) const { }
|
||||
@ -60,8 +60,7 @@ class VModelInfo : public IDetour
|
||||
#endif // DEDICATED
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Detour(const bool bAttach) const { }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -280,7 +280,7 @@ void CMapLoadHelper::Constructor(CMapLoadHelper* loader, int lumpToLoad)
|
||||
FileHandle_t hLumpFile = FileSystem()->Open(lumpPathBuf, "rb");
|
||||
if (hLumpFile != FILESYSTEM_INVALID_HANDLE)
|
||||
{
|
||||
//DevMsg(eDLL_T::ENGINE, "Loading lump %.4x from file. Buffer: %p\n", lumpToLoad, loader->m_pRawData);
|
||||
DevMsg(eDLL_T::ENGINE, "Loading lump %.4x from file. Buffer: %p\n", lumpToLoad, loader->m_pRawData);
|
||||
FileSystem()->ReadEx(loader->m_pRawData, lumpSize, lumpSize, hLumpFile);
|
||||
FileSystem()->Close(hLumpFile);
|
||||
|
||||
@ -345,20 +345,11 @@ void AddGameLump()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VModelLoader::Attach() const
|
||||
void VModelLoader::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&CModelLoader__LoadModel, &CModelLoader::LoadModel);
|
||||
DetourAttach((LPVOID*)&CModelLoader__Map_LoadModelGuts, &CModelLoader::Map_LoadModelGuts);
|
||||
DetourSetup(&CModelLoader__LoadModel, &CModelLoader::LoadModel, bAttach);
|
||||
DetourSetup(&CModelLoader__Map_LoadModelGuts, &CModelLoader::Map_LoadModelGuts, bAttach);
|
||||
|
||||
DetourAttach((LPVOID*)&CMapLoadHelper__CMapLoadHelper, &CMapLoadHelper::Constructor);
|
||||
DetourAttach((LPVOID*)&v_AddGameLump, &AddGameLump);
|
||||
}
|
||||
|
||||
void VModelLoader::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&CModelLoader__LoadModel, &CModelLoader::LoadModel);
|
||||
DetourDetach((LPVOID*)&CModelLoader__Map_LoadModelGuts, &CModelLoader::Map_LoadModelGuts);
|
||||
|
||||
DetourDetach((LPVOID*)&CMapLoadHelper__CMapLoadHelper, &CMapLoadHelper::Constructor);
|
||||
DetourDetach((LPVOID*)&v_AddGameLump, &AddGameLump);
|
||||
DetourSetup(&CMapLoadHelper__CMapLoadHelper, &CMapLoadHelper::Constructor, bAttach);
|
||||
DetourSetup(&v_AddGameLump, &AddGameLump, bAttach);
|
||||
}
|
||||
|
@ -71,38 +71,21 @@ public:
|
||||
char m_szLumpFilename[260];
|
||||
};
|
||||
|
||||
inline CMemory p_CModelLoader__FindModel;
|
||||
inline void*(*CModelLoader__FindModel)(CModelLoader* loader, const char* pszModelName);
|
||||
|
||||
inline CMemory p_CModelLoader__LoadModel;
|
||||
inline void(*CModelLoader__LoadModel)(CModelLoader* loader, model_t* model);
|
||||
|
||||
inline CMemory p_CModelLoader__UnloadModel;
|
||||
inline uint64_t(*CModelLoader__UnloadModel)(CModelLoader* loader, model_t* model);
|
||||
|
||||
inline CMemory p_CModelLoader__Studio_LoadModel;
|
||||
inline void*(*CModelLoader__Studio_LoadModel)(CModelLoader* loader);
|
||||
|
||||
inline CMemory p_CModelLoader__Map_LoadModelGuts;
|
||||
inline uint64_t(*CModelLoader__Map_LoadModelGuts)(CModelLoader* loader, model_t* model);
|
||||
|
||||
inline CMemory p_CModelLoader__Map_IsValid;
|
||||
inline bool(*CModelLoader__Map_IsValid)(CModelLoader* loader, const char* pszMapName);
|
||||
|
||||
inline CMemory p_CMapLoadHelper__CMapLoadHelper;
|
||||
inline void(*CMapLoadHelper__CMapLoadHelper)(CMapLoadHelper * helper, int lumpToLoad);
|
||||
|
||||
inline CMemory p_AddGameLump;
|
||||
inline void(*v_AddGameLump)(void);
|
||||
|
||||
inline CMemory p_Map_LoadModel;
|
||||
inline void(*v_Map_LoadModel)(void);
|
||||
|
||||
//inline CMemory p_GetSpriteInfo; // DEDICATED PATCH!
|
||||
//inline void*(*GetSpriteInfo)(const char* pName, bool bIsAVI, bool bIsBIK, int& nWidth, int& nHeight, int& nFrameCount, void* a7);
|
||||
|
||||
//inline CMemory p_BuildSpriteLoadName; // DEDICATED PATCH!
|
||||
//inline void*(*BuildSpriteLoadName)(const char* pName, char* pOut, int outLen, bool& bIsAVI, bool& bIsBIK);
|
||||
#ifndef DEDICATED
|
||||
inline void*(*v_GetSpriteInfo)(const char* pName, bool bIsAVI, bool bIsBIK, int& nWidth, int& nHeight, int& nFrameCount, void* a7);
|
||||
inline void*(*v_BuildSpriteLoadName)(const char* pName, char* pOut, int outLen, bool& bIsAVI, bool& bIsBIK);
|
||||
#endif // !DEDICATED
|
||||
|
||||
inline CModelLoader* g_pModelLoader;
|
||||
inline FileHandle_t* s_MapFileHandle;
|
||||
@ -114,72 +97,56 @@ class VModelLoader : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CModelLoader::FindModel", p_CModelLoader__FindModel.GetPtr());
|
||||
LogFunAdr("CModelLoader::LoadModel", p_CModelLoader__LoadModel.GetPtr());
|
||||
LogFunAdr("CModelLoader::UnloadModel", p_CModelLoader__UnloadModel.GetPtr());
|
||||
LogFunAdr("CModelLoader::Map_LoadModelGuts", p_CModelLoader__Map_LoadModelGuts.GetPtr());
|
||||
LogFunAdr("CModelLoader::Map_IsValid", p_CModelLoader__Map_IsValid.GetPtr());
|
||||
LogFunAdr("CModelLoader::Studio_LoadModel", p_CModelLoader__Studio_LoadModel.GetPtr());
|
||||
LogFunAdr("CMapLoadHelper::CMapLoadHelper", p_CMapLoadHelper__CMapLoadHelper.GetPtr());
|
||||
LogFunAdr("AddGameLump", p_AddGameLump.GetPtr());
|
||||
LogFunAdr("Map_LoadModel", p_Map_LoadModel.GetPtr());
|
||||
//LogFunAdr("GetSpriteInfo", p_GetSpriteInfo.GetPtr());
|
||||
//LogFunAdr("BuildSpriteLoadName", p_BuildSpriteLoadName.GetPtr());
|
||||
LogVarAdr("g_pModelLoader", reinterpret_cast<uintptr_t>(g_pModelLoader));
|
||||
LogVarAdr("s_MapFileHandle", reinterpret_cast<uintptr_t>(s_MapFileHandle));
|
||||
LogVarAdr("s_MapHeader", reinterpret_cast<uintptr_t>(s_MapHeader));
|
||||
LogVarAdr("s_szMapPathName", reinterpret_cast<uintptr_t>(s_szMapPathName));
|
||||
LogFunAdr("CModelLoader::FindModel", CModelLoader__FindModel);
|
||||
LogFunAdr("CModelLoader::LoadModel", CModelLoader__LoadModel);
|
||||
LogFunAdr("CModelLoader::UnloadModel", CModelLoader__UnloadModel);
|
||||
LogFunAdr("CModelLoader::Map_LoadModelGuts", CModelLoader__Map_LoadModelGuts);
|
||||
LogFunAdr("CModelLoader::Map_IsValid", CModelLoader__Map_IsValid);
|
||||
LogFunAdr("CModelLoader::Studio_LoadModel", CModelLoader__Studio_LoadModel);
|
||||
|
||||
LogFunAdr("CMapLoadHelper::CMapLoadHelper", CMapLoadHelper__CMapLoadHelper);
|
||||
|
||||
LogFunAdr("AddGameLump", v_AddGameLump);
|
||||
LogFunAdr("Map_LoadModel", v_Map_LoadModel);
|
||||
|
||||
#ifndef DEDICATED
|
||||
LogFunAdr("GetSpriteInfo", v_GetSpriteInfo);
|
||||
LogFunAdr("BuildSpriteLoadName", v_BuildSpriteLoadName);
|
||||
#endif // !DEDICATED
|
||||
|
||||
LogVarAdr("g_pModelLoader", g_pModelLoader);
|
||||
LogVarAdr("s_MapFileHandle", s_MapFileHandle);
|
||||
LogVarAdr("s_MapHeader", s_MapHeader);
|
||||
LogVarAdr("s_szMapPathName", s_szMapPathName);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CModelLoader__FindModel = g_GameDll.FindPatternSIMD("40 55 41 55 41 56 48 8D AC 24 ?? ?? ?? ??");
|
||||
p_CModelLoader__LoadModel = g_GameDll.FindPatternSIMD("40 53 57 41 56 48 81 EC ?? ?? ?? ?? 48 8B FA");
|
||||
p_CModelLoader__UnloadModel = g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 18 55 48 81 EC ?? ?? ?? ?? 48 8B DA");
|
||||
p_CModelLoader__Studio_LoadModel = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 54 41 56 48 8D AC 24 ?? ?? ?? ??");
|
||||
p_CModelLoader__Map_LoadModelGuts = g_GameDll.FindPatternSIMD("48 89 54 24 ?? 48 89 4C 24 ?? 55 53 41 54 41 55 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? FF 05 ?? ?? ?? ??"); // BSP.
|
||||
p_CModelLoader__Map_IsValid = g_GameDll.FindPatternSIMD("48 8B C4 53 48 81 EC ?? ?? ?? ?? 48 8B DA");
|
||||
//p_GetSpriteInfo = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 30 4C 8B AC 24 ?? ?? ?? ?? BE ?? ?? ?? ??");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CModelLoader__FindModel = g_GameDll.FindPatternSIMD("40 55 41 57 48 83 EC 48 80 3A 2A");
|
||||
p_CModelLoader__LoadModel = g_GameDll.FindPatternSIMD("40 53 57 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ??");
|
||||
p_CModelLoader__UnloadModel = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 33 ED");
|
||||
p_CModelLoader__Studio_LoadModel = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 54 41 57 48 81 EC ?? ?? ?? ??");
|
||||
p_CModelLoader__Map_LoadModelGuts = g_GameDll.FindPatternSIMD("48 89 54 24 ?? 48 89 4C 24 ?? 55 53 56 57 41 54 41 55 41 57"); // BSP.
|
||||
p_CModelLoader__Map_IsValid = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 48 8B DA 48 85 D2 0F 84 ?? ?? ?? ?? 80 3A ?? 0F 84 ?? ?? ?? ?? 4C 8B CA");
|
||||
//p_GetSpriteInfo = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 30 4C 8B BC 24 ?? ?? ?? ??");
|
||||
#endif
|
||||
//p_BuildSpriteLoadName = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC ?? ?? ?? ?? 4D 8B F1 48 8B F2");
|
||||
g_GameDll.FindPatternSIMD("40 55 41 57 48 83 EC 48 80 3A 2A").GetPtr(CModelLoader__FindModel);
|
||||
g_GameDll.FindPatternSIMD("40 53 57 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ??").GetPtr(CModelLoader__LoadModel);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 33 ED").GetPtr(CModelLoader__UnloadModel);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 54 41 57 48 81 EC ?? ?? ?? ??").GetPtr(CModelLoader__Studio_LoadModel);
|
||||
g_GameDll.FindPatternSIMD("48 89 54 24 ?? 48 89 4C 24 ?? 55 53 56 57 41 54 41 55 41 57").GetPtr(CModelLoader__Map_LoadModelGuts); // BSP.
|
||||
g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 48 8B DA 48 85 D2 0F 84 ?? ?? ?? ?? 80 3A ?? 0F 84 ?? ?? ?? ?? 4C 8B CA").GetPtr(CModelLoader__Map_IsValid);
|
||||
|
||||
p_CMapLoadHelper__CMapLoadHelper = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC 60");
|
||||
p_AddGameLump = g_GameDll.FindPatternSIMD("40 ?? 57 48 83 EC 48 33 ?? 48 8D");
|
||||
p_Map_LoadModel = g_GameDll.FindPatternSIMD("48 83 EC 28 8B 05 ?? ?? ?? ?? FF C8");
|
||||
#ifndef DEDICATED
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 30 4C 8B BC 24 ?? ?? ?? ??").GetPtr(v_GetSpriteInfo);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC ?? ?? ?? ?? 4D 8B F1 48 8B F2").GetPtr(v_BuildSpriteLoadName);
|
||||
#endif // !DEDICATED
|
||||
|
||||
CModelLoader__FindModel = p_CModelLoader__FindModel.RCast<void* (*)(CModelLoader*, const char*)>();
|
||||
CModelLoader__LoadModel = p_CModelLoader__LoadModel.RCast<void(*)(CModelLoader*, model_t*)>();
|
||||
CModelLoader__UnloadModel = p_CModelLoader__UnloadModel.RCast<uint64_t(*)(CModelLoader*, model_t*)>();
|
||||
CModelLoader__Studio_LoadModel = p_CModelLoader__Studio_LoadModel.RCast<void* (*)(CModelLoader*)>();
|
||||
CModelLoader__Map_LoadModelGuts = p_CModelLoader__Map_LoadModelGuts.RCast<uint64_t(*)(CModelLoader*, model_t* mod)>();
|
||||
CModelLoader__Map_IsValid = p_CModelLoader__Map_IsValid.RCast<bool(*)(CModelLoader*, const char*)>();
|
||||
|
||||
CMapLoadHelper__CMapLoadHelper = p_CMapLoadHelper__CMapLoadHelper.RCast<void(*)(CMapLoadHelper*, int)>();
|
||||
v_AddGameLump = p_AddGameLump.RCast<void(*)(void)>();
|
||||
v_Map_LoadModel = p_Map_LoadModel.RCast<void(*)(void)>();
|
||||
|
||||
//GetSpriteInfo = p_GetSpriteInfo.RCast<void* (*)(const char*, bool, bool, int&, int&, int&, void*)>();
|
||||
//BuildSpriteLoadName = p_BuildSpriteLoadName.RCast<void* (*)(const char*, char*, int, bool&, bool&)>();
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC 60").GetPtr(CMapLoadHelper__CMapLoadHelper);
|
||||
g_GameDll.FindPatternSIMD("40 ?? 57 48 83 EC 48 33 ?? 48 8D").GetPtr(v_AddGameLump);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 28 8B 05 ?? ?? ?? ?? FF C8").GetPtr(v_Map_LoadModel);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_pModelLoader = g_GameDll.FindPatternSIMD(
|
||||
"48 89 4C 24 ?? 53 55 56 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ??").FindPatternSelf("48 ?? 0D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(3, 7).RCast<CModelLoader*>();
|
||||
|
||||
s_MapFileHandle = p_Map_LoadModel.FindPattern("48 8B").ResolveRelativeAddressSelf(0x3, 0x7).RCast<FileHandle_t*>();
|
||||
s_MapHeader = p_Map_LoadModel.FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<BSPHeader_t*>();
|
||||
s_szMapPathName = p_CMapLoadHelper__CMapLoadHelper.FindPattern("4C 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>();
|
||||
s_MapFileHandle = CMemory(v_Map_LoadModel).FindPattern("48 8B").ResolveRelativeAddressSelf(0x3, 0x7).RCast<FileHandle_t*>();
|
||||
s_MapHeader = CMemory(v_Map_LoadModel).FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<BSPHeader_t*>();
|
||||
s_szMapPathName = CMemory(CMapLoadHelper__CMapLoadHelper).FindPattern("4C 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "engine/net.h"
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
#include "tier1/cvar.h"
|
||||
#include "mathlib/color.h"
|
||||
#include "net.h"
|
||||
@ -15,9 +15,45 @@
|
||||
#include "server/server.h"
|
||||
#include "client/client.h"
|
||||
#endif // !CLIENT_DLL
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
|
||||
#ifndef _TOOLS
|
||||
static void NET_SetKey_f(const CCommand& args)
|
||||
{
|
||||
if (args.ArgC() < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NET_SetKey(args.Arg(1));
|
||||
}
|
||||
static void NET_GenerateKey_f()
|
||||
{
|
||||
NET_GenerateKey();
|
||||
}
|
||||
|
||||
void NET_UseRandomKeyChanged_f(IConVar* pConVar, const char* pOldString)
|
||||
{
|
||||
if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName()))
|
||||
{
|
||||
if (strcmp(pOldString, pConVarRef->GetString()) == NULL)
|
||||
return; // Same value.
|
||||
|
||||
if (pConVarRef->GetBool())
|
||||
NET_GenerateKey();
|
||||
else
|
||||
NET_SetKey(DEFAULT_NET_ENCRYPTION_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
ConVar net_useRandomKey("net_useRandomKey", "1", FCVAR_RELEASE, "Use random AES encryption key for game packets.", false, 0.f, false, 0.f, &NET_UseRandomKeyChanged_f, nullptr);
|
||||
|
||||
static ConVar net_tracePayload("net_tracePayload", "0", FCVAR_DEVELOPMENTONLY, "Log the payload of the send/recv datagram to a file on the disk.");
|
||||
static ConVar net_encryptionEnable("net_encryptionEnable", "1", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Use AES encryption on game packets.");
|
||||
|
||||
static ConCommand net_setkey("net_setkey", NET_SetKey_f, "Sets user specified base64 net key", FCVAR_RELEASE);
|
||||
static ConCommand net_generatekey("net_generatekey", NET_GenerateKey_f, "Generates and sets a random base64 net key", FCVAR_RELEASE);
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: hook and log the receive datagram
|
||||
// Input : iSocket -
|
||||
@ -27,13 +63,16 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NET_ReceiveDatagram(int iSocket, netpacket_s* pInpacket, bool bEncrypted)
|
||||
{
|
||||
bool result = v_NET_ReceiveDatagram(iSocket, pInpacket, net_encryptionEnable->GetBool());
|
||||
if (result && net_tracePayload->GetBool())
|
||||
const bool decryptPacket = (bEncrypted && net_encryptionEnable.GetBool());
|
||||
const bool result = v_NET_ReceiveDatagram(iSocket, pInpacket, decryptPacket);
|
||||
|
||||
if (result && net_tracePayload.GetBool())
|
||||
{
|
||||
// Log received packet data.
|
||||
HexDump("[+] NET_ReceiveDatagram ", "net_trace",
|
||||
pInpacket->pData, size_t(pInpacket->wiresize));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -48,15 +87,66 @@ bool NET_ReceiveDatagram(int iSocket, netpacket_s* pInpacket, bool bEncrypted)
|
||||
//-----------------------------------------------------------------------------
|
||||
int NET_SendDatagram(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool bEncrypt)
|
||||
{
|
||||
int result = v_NET_SendDatagram(s, pPayload, iLenght, pAdr, net_encryptionEnable->GetBool());
|
||||
if (result && net_tracePayload->GetBool())
|
||||
const bool encryptPacket = (bEncrypt && net_encryptionEnable.GetBool());
|
||||
const int result = v_NET_SendDatagram(s, pPayload, iLenght, pAdr, encryptPacket);
|
||||
|
||||
if (result && net_tracePayload.GetBool())
|
||||
{
|
||||
// Log transmitted packet data.
|
||||
HexDump("[+] NET_SendDatagram ", "net_trace", pPayload, size_t(iLenght));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: compresses the input buffer into the output buffer
|
||||
// Input : *dest -
|
||||
// *destLen -
|
||||
// *source -
|
||||
// sourceLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NET_BufferToBufferCompress(uint8_t* const dest, size_t* const destLen, uint8_t* const source, const size_t sourceLen)
|
||||
{
|
||||
CLZSS lzss;
|
||||
uint32_t compLen = (uint32_t)sourceLen;
|
||||
|
||||
if (!lzss.CompressNoAlloc(source, (uint32_t)sourceLen, dest, &compLen))
|
||||
{
|
||||
memcpy(dest, source, sourceLen);
|
||||
|
||||
*destLen = sourceLen;
|
||||
return false;
|
||||
}
|
||||
|
||||
*destLen = compLen;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: decompresses the input buffer into the output buffer
|
||||
// Input : *source -
|
||||
// &sourceLen -
|
||||
// *dest -
|
||||
// destLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int NET_BufferToBufferDecompress(uint8_t* const source, size_t& sourceLen, uint8_t* const dest, const size_t destLen)
|
||||
{
|
||||
Assert(source);
|
||||
Assert(sourceLen);
|
||||
|
||||
CLZSS lzss;
|
||||
|
||||
if (lzss.IsCompressed(source))
|
||||
{
|
||||
return lzss.SafeUncompress(source, dest, (unsigned int)destLen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: safely decompresses the input buffer into the output buffer
|
||||
// Input : *lzss -
|
||||
@ -65,7 +155,7 @@ int NET_SendDatagram(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool
|
||||
// unBufSize -
|
||||
// Output : total decompressed bytes
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int NET_Decompress(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)
|
||||
unsigned int NET_BufferToBufferDecompress_LZSS(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)
|
||||
{
|
||||
return lzss->SafeUncompress(pInput, pOutput, unBufSize);
|
||||
}
|
||||
@ -92,7 +182,7 @@ void NET_SetKey(const string& svNetKey)
|
||||
{
|
||||
v_NET_SetKey(g_pNetKey, svTokenizedKey.c_str());
|
||||
|
||||
DevMsg(eDLL_T::ENGINE, "Installed NetKey: %s'%s%s%s'\n",
|
||||
Msg(eDLL_T::ENGINE, "Installed NetKey: %s'%s%s%s'\n",
|
||||
g_svReset, g_svGreyB, g_pNetKey->GetBase64NetKey(), g_svReset);
|
||||
}
|
||||
else
|
||||
@ -106,9 +196,9 @@ void NET_SetKey(const string& svNetKey)
|
||||
//-----------------------------------------------------------------------------
|
||||
void NET_GenerateKey()
|
||||
{
|
||||
if (!net_useRandomKey->GetBool())
|
||||
if (!net_useRandomKey.GetBool())
|
||||
{
|
||||
net_useRandomKey->SetValue(1);
|
||||
net_useRandomKey.SetValue(1);
|
||||
return; // Change callback will handle this.
|
||||
}
|
||||
|
||||
@ -154,7 +244,7 @@ void NET_PrintFunc(const char* fmt, ...)
|
||||
result.push_back('\n');
|
||||
}
|
||||
|
||||
DevMsg(context, "%s", result.c_str());
|
||||
Msg(context, "%s", result.c_str());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -175,10 +265,22 @@ void NET_RemoveChannel(CClient* pClient, int nIndex, const char* szReason, uint8
|
||||
|
||||
pClient->GetNetChan()->Shutdown(szReason, bBadRep, bRemoveNow); // Shutdown NetChannel.
|
||||
pClient->Clear(); // Reset CClient slot.
|
||||
g_ServerPlayer[nIndex].Reset(); // Reset ServerPlayer slot.
|
||||
#endif // !CLIENT_DLL
|
||||
}
|
||||
#endif // !NETCONSOLE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: reads the net message type from buffer
|
||||
// Input : &outType -
|
||||
// &buffer -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NET_ReadMessageType(int* outType, bf_read* buffer)
|
||||
{
|
||||
*outType = buffer->ReadUBitLong(NETMSG_TYPE_BITS);
|
||||
return !buffer->IsOverflowed();
|
||||
}
|
||||
|
||||
#endif // !_TOOLS
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the WSA error code
|
||||
@ -282,24 +384,17 @@ const char* NET_ErrorString(int iCode)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VNet::Attach() const
|
||||
void VNet::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((LPVOID*)&v_NET_Config, &NET_Config);
|
||||
DetourAttach((LPVOID*)&v_NET_ReceiveDatagram, &NET_ReceiveDatagram);
|
||||
DetourAttach((LPVOID*)&v_NET_SendDatagram, &NET_SendDatagram);
|
||||
DetourAttach((LPVOID*)&v_NET_Decompress, &NET_Decompress);
|
||||
DetourAttach((LPVOID*)&v_NET_PrintFunc, &NET_PrintFunc);
|
||||
}
|
||||
DetourSetup(&v_NET_Config, &NET_Config, bAttach);
|
||||
DetourSetup(&v_NET_ReceiveDatagram, &NET_ReceiveDatagram, bAttach);
|
||||
DetourSetup(&v_NET_SendDatagram, &NET_SendDatagram, bAttach);
|
||||
|
||||
void VNet::Detach() const
|
||||
{
|
||||
DetourDetach((LPVOID*)&v_NET_Config, &NET_Config);
|
||||
DetourDetach((LPVOID*)&v_NET_ReceiveDatagram, &NET_ReceiveDatagram);
|
||||
DetourDetach((LPVOID*)&v_NET_SendDatagram, &NET_SendDatagram);
|
||||
DetourDetach((LPVOID*)&v_NET_Decompress, &NET_Decompress);
|
||||
DetourDetach((LPVOID*)&v_NET_PrintFunc, &NET_PrintFunc);
|
||||
DetourSetup(&v_NET_BufferToBufferCompress, &NET_BufferToBufferCompress, bAttach);
|
||||
DetourSetup(&v_NET_BufferToBufferDecompress_LZSS, &NET_BufferToBufferDecompress_LZSS, bAttach);
|
||||
DetourSetup(&v_NET_PrintFunc, &NET_PrintFunc, bAttach);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -307,4 +402,4 @@ netadr_t* g_pNetAdr = nullptr;
|
||||
netkey_t* g_pNetKey = nullptr;
|
||||
|
||||
double* g_pNetTime = nullptr;
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NETCONSOLE
|
||||
#ifndef _TOOLS
|
||||
#include "engine/net_chan.h"
|
||||
#include "tier1/lzss.h"
|
||||
#define MAX_STREAMS 2
|
||||
@ -19,26 +19,20 @@ constexpr unsigned int AES_128_B64_ENCODED_SIZE = 24;
|
||||
constexpr const char* DEFAULT_NET_ENCRYPTION_KEY = "WDNWLmJYQ2ZlM0VoTid3Yg==";
|
||||
|
||||
/* ==== CNETCHAN ======================================================================================================================================================== */
|
||||
inline CMemory p_NET_Init;
|
||||
inline void*(*v_NET_Init)(bool bDeveloper);
|
||||
|
||||
inline CMemory p_NET_SetKey;
|
||||
inline void(*v_NET_SetKey)(netkey_t* pKey, const char* szHash);
|
||||
|
||||
inline CMemory p_NET_Config;
|
||||
inline void(*v_NET_Config)(void);
|
||||
|
||||
inline CMemory p_NET_ReceiveDatagram;
|
||||
inline bool(*v_NET_ReceiveDatagram)(int iSocket, netpacket_s* pInpacket, bool bRaw);
|
||||
inline int(*v_NET_GetPacket)(int iSocket, uint8_t* pScratch, bool bEncrypted);
|
||||
inline int(*v_NET_SendPacket)(CNetChan* pChan, int iSocket, const netadr_t& toAdr, const uint8_t* pData, unsigned int nLen, void* unused0, bool bCompress, void* unused1, bool bEncrypt);
|
||||
|
||||
inline CMemory p_NET_SendDatagram;
|
||||
inline bool(*v_NET_ReceiveDatagram)(int iSocket, netpacket_s* pInpacket, bool bRaw);
|
||||
inline int(*v_NET_SendDatagram)(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool bEncrypted);
|
||||
|
||||
inline CMemory p_NET_Decompress;
|
||||
inline int(*v_NET_Decompress)(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
|
||||
inline bool(*v_NET_BufferToBufferCompress)(uint8_t* const dest, size_t* const destLen, uint8_t* const source, const size_t sourceLen);
|
||||
inline unsigned int(*v_NET_BufferToBufferDecompress_LZSS)(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
|
||||
|
||||
inline CMemory p_NET_PrintFunc;
|
||||
inline void(*v_NET_PrintFunc)(const char* fmt);
|
||||
inline void(*v_NET_PrintFunc)(const char* fmt, ...);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool NET_ReceiveDatagram(int iSocket, netpacket_s* pInpacket, bool bRaw);
|
||||
@ -48,61 +42,72 @@ void NET_GenerateKey();
|
||||
void NET_PrintFunc(const char* fmt, ...);
|
||||
void NET_RemoveChannel(CClient* pClient, int nIndex, const char* szReason, uint8_t bBadRep, bool bRemoveNow);
|
||||
|
||||
bool NET_BufferToBufferCompress(uint8_t* const dest, size_t* const destLen, uint8_t* const source, const size_t sourceLen);
|
||||
unsigned int NET_BufferToBufferDecompress(uint8_t* pInput, size_t& coBufsize, uint8_t* pOutput, const size_t unBufSize);
|
||||
|
||||
unsigned int NET_BufferToBufferDecompress_LZSS(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
|
||||
|
||||
bool NET_ReadMessageType(int* outType, bf_read* buffer);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
extern netadr_t* g_pNetAdr;
|
||||
extern netkey_t* g_pNetKey;
|
||||
|
||||
extern double* g_pNetTime;
|
||||
|
||||
extern ConVar net_useRandomKey;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VNet : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("NET_Init", p_NET_Init.GetPtr());
|
||||
LogFunAdr("NET_Config", p_NET_Config.GetPtr());
|
||||
LogFunAdr("NET_SetKey", p_NET_SetKey.GetPtr());
|
||||
LogFunAdr("NET_ReceiveDatagram", p_NET_ReceiveDatagram.GetPtr());
|
||||
LogFunAdr("NET_SendDatagram", p_NET_SendDatagram.GetPtr());
|
||||
LogFunAdr("NET_Decompress", p_NET_Decompress.GetPtr());
|
||||
LogFunAdr("NET_PrintFunc", p_NET_PrintFunc.GetPtr());
|
||||
LogVarAdr("g_NetAdr", reinterpret_cast<uintptr_t>(g_pNetAdr));
|
||||
LogVarAdr("g_NetKey", reinterpret_cast<uintptr_t>(g_pNetKey));
|
||||
LogVarAdr("g_NetTime", reinterpret_cast<uintptr_t>(g_pNetTime));
|
||||
LogFunAdr("NET_Init", v_NET_Init);
|
||||
LogFunAdr("NET_Config", v_NET_Config);
|
||||
LogFunAdr("NET_SetKey", v_NET_SetKey);
|
||||
|
||||
LogFunAdr("NET_GetPacket", v_NET_GetPacket);
|
||||
LogFunAdr("NET_SendPacket", v_NET_SendPacket);
|
||||
|
||||
LogFunAdr("NET_ReceiveDatagram", v_NET_ReceiveDatagram);
|
||||
LogFunAdr("NET_SendDatagram", v_NET_SendDatagram);
|
||||
|
||||
LogFunAdr("NET_BufferToBufferCompress", v_NET_BufferToBufferCompress);
|
||||
LogFunAdr("NET_BufferToBufferDecompress_LZSS", v_NET_BufferToBufferDecompress_LZSS);
|
||||
|
||||
LogFunAdr("NET_PrintFunc", v_NET_PrintFunc);
|
||||
LogVarAdr("g_NetAdr", g_pNetAdr);
|
||||
LogVarAdr("g_NetKey", g_pNetKey);
|
||||
LogVarAdr("g_NetTime", g_pNetTime);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
p_NET_Init = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC C0 01 ??");
|
||||
#elif defined (GAMEDLL_S3)
|
||||
p_NET_Init = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC F0 01 ??");
|
||||
#endif
|
||||
p_NET_Config = g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 0F 57 C0");
|
||||
p_NET_SetKey = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F9 41 B8");
|
||||
p_NET_ReceiveDatagram = g_GameDll.FindPatternSIMD("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB");
|
||||
p_NET_SendDatagram = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 ?? ??");
|
||||
p_NET_Decompress = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 45 33 F6");
|
||||
p_NET_PrintFunc = g_GameDll.FindPatternSIMD("48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48");
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC F0 01 ??").GetPtr(v_NET_Init);
|
||||
g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 0F 57 C0").GetPtr(v_NET_Config);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F9 41 B8").GetPtr(v_NET_SetKey);
|
||||
|
||||
v_NET_Init = p_NET_Init.RCast<void* (*)(bool)>(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC F0 01 00*/
|
||||
v_NET_Config = p_NET_Config.RCast<void (*)(void)>();
|
||||
v_NET_SetKey = p_NET_SetKey.RCast<void (*)(netkey_t*, const char*)>(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F9 41 B8*/
|
||||
v_NET_ReceiveDatagram = p_NET_ReceiveDatagram.RCast<bool (*)(int, netpacket_s*, bool)>(); /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/
|
||||
v_NET_SendDatagram = p_NET_SendDatagram.RCast<int (*)(SOCKET, void*, int, netadr_t*, bool)>(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 00 00*/
|
||||
v_NET_Decompress = p_NET_Decompress.RCast<int (*)(CLZSS*, unsigned char*, unsigned char*, unsigned int)>();
|
||||
v_NET_PrintFunc = p_NET_PrintFunc.RCast<void(*)(const char*)>(); /*48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48*/
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 8B C4 44 88 40 18 48 89 50 10 41 55").GetPtr(v_NET_GetPacket);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 55 57 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 4C 63 F2").GetPtr(v_NET_SendPacket);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr(v_NET_ReceiveDatagram);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 ?? ??").GetPtr(v_NET_SendDatagram);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 50 48 8B 05 ?? ?? ?? ?? 49 8B E9").GetPtr(v_NET_BufferToBufferCompress);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 45 33 F6").GetPtr(v_NET_BufferToBufferDecompress_LZSS);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48").GetPtr(v_NET_PrintFunc);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_pNetAdr = g_GameDll.FindPatternSIMD("C7 05 ?? ?? ?? ?? ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 66 89 05 ?? ?? ?? ?? 88 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 33 C0").ResolveRelativeAddressSelf(0x2, 0xA).RCast<netadr_t*>();
|
||||
g_pNetKey = g_GameDll.FindString("client:NetEncryption_NewKey").FindPatternSelf("48 8D ?? ?? ?? ?? ?? 48 3B", CMemory::Direction::UP, 300).ResolveRelativeAddressSelf(0x3, 0x7).RCast<netkey_t*>();
|
||||
g_pNetTime = p_NET_Init.Offset(0xA).FindPatternSelf("F2 0F").ResolveRelativeAddressSelf(0x4, 0x8).RCast<double*>();
|
||||
g_pNetTime = CMemory(v_NET_Init).Offset(0xA).FindPatternSelf("F2 0F").ResolveRelativeAddressSelf(0x4, 0x8).RCast<double*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#endif // !NETCONSOLE
|
||||
#endif // !_TOOLS
|
||||
|
||||
const char* NET_ErrorString(int iCode);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier0/frametask.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "common/callback.h"
|
||||
#include "engine/net.h"
|
||||
#include "engine/net_chan.h"
|
||||
@ -17,22 +17,28 @@
|
||||
#include "server/vengineserver_impl.h"
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Console variables
|
||||
//-----------------------------------------------------------------------------
|
||||
static ConVar net_processTimeBudget("net_processTimeBudget", "200", FCVAR_RELEASE, "Net message process time budget in milliseconds (removing netchannel if exceeded).", true, 0.f, false, 0.f, "0 = disabled");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the netchannel network loss
|
||||
// Purpose: gets the netchannel resend rate
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float CNetChan::GetNetworkLoss() const
|
||||
float CNetChan::GetResendRate() const
|
||||
{
|
||||
float v1 = *&m_DataFlow[1].frames[0].one;
|
||||
if (!v1 && !m_nSequencesSkipped_MAYBE)
|
||||
const int64_t totalupdates = this->m_DataFlow[FLOW_INCOMING].totalupdates;
|
||||
|
||||
if (!totalupdates && !this->m_nSequencesSkipped_MAYBE)
|
||||
return 0.0f;
|
||||
|
||||
float v4 = (v1 + m_nSequencesSkipped_MAYBE);
|
||||
if (v1 + m_nSequencesSkipped_MAYBE < 0)
|
||||
v4 = v4 + float(2 ^ 64);
|
||||
float lossRate = (float)(totalupdates + m_nSequencesSkipped_MAYBE);
|
||||
|
||||
return m_nSequencesSkipped_MAYBE / v4;
|
||||
if (totalupdates + m_nSequencesSkipped_MAYBE < 0.0f)
|
||||
lossRate += float(2 ^ 64);
|
||||
|
||||
return m_nSequencesSkipped_MAYBE / lossRate;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -64,6 +70,287 @@ double CNetChan::GetTimeConnected(void) const
|
||||
return (t > 0.0) ? t : 0.0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the number of bits written in selected stream
|
||||
//-----------------------------------------------------------------------------
|
||||
int CNetChan::GetNumBitsWritten(const bool bReliable)
|
||||
{
|
||||
bf_write* pStream = &m_StreamUnreliable;
|
||||
|
||||
if (bReliable)
|
||||
{
|
||||
pStream = &m_StreamReliable;
|
||||
}
|
||||
|
||||
return pStream->GetNumBitsWritten();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the number of bits written in selected stream
|
||||
//-----------------------------------------------------------------------------
|
||||
int CNetChan::GetNumBitsLeft(const bool bReliable)
|
||||
{
|
||||
bf_write* pStream = &m_StreamUnreliable;
|
||||
|
||||
if (bReliable)
|
||||
{
|
||||
pStream = &m_StreamReliable;
|
||||
}
|
||||
|
||||
return pStream->GetNumBitsLeft();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: flows a new packet
|
||||
// Input : *pChan -
|
||||
// outSeqNr -
|
||||
// acknr -
|
||||
// inSeqNr -
|
||||
// nChoked -
|
||||
// nDropped -
|
||||
// nSize -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetChan::_FlowNewPacket(CNetChan* pChan, int flow, int outSeqNr, int inSeqNr, int nChoked, int nDropped, int nSize)
|
||||
{
|
||||
float netTime; // xmm4_8 (was double)
|
||||
int v8; // r13d
|
||||
int v9; // r14d
|
||||
int v12; // r12d
|
||||
int currentindex; // eax
|
||||
int nextIndex; // r15d
|
||||
int v17; // r8d
|
||||
int v18; // ebp
|
||||
unsigned int v19; // eax
|
||||
int v20; // r9 (was char)
|
||||
int v21; // r8d
|
||||
__int64 v22; // r14
|
||||
float time; // xmm0_4
|
||||
__int64 v24; // rdx
|
||||
__int64 v25; // rcx
|
||||
__int64 v26; // rdx
|
||||
__int64 v27; // rcx
|
||||
__int64 v28; // rdx
|
||||
__int64 v29; // rcx
|
||||
int v30; // edx
|
||||
int v31; // r8 (was char)
|
||||
float v32; // xmm0_4
|
||||
__int64 v33; // r9
|
||||
__int64 v34; // rax
|
||||
__int64 v35; // rdx
|
||||
int v36; // r8d
|
||||
float v37; // xmm3_4
|
||||
__int64 result; // rax
|
||||
float v39; // xmm1_4
|
||||
float v40; // xmm0_4
|
||||
float v41; // xmm1_4
|
||||
netframe_header_t* v42; // rdx
|
||||
float v43; // xmm0_4
|
||||
float v44; // xmm2_4
|
||||
float v45; // xmm0_4
|
||||
|
||||
netTime = (float)*g_pNetTime;
|
||||
v8 = flow;
|
||||
v9 = inSeqNr;
|
||||
netflow_t* pFlow = &pChan->m_DataFlow[flow];
|
||||
v12 = outSeqNr;
|
||||
|
||||
netframe_header_t* pFrameHeader = nullptr;
|
||||
netframe_t* pFrame = nullptr;
|
||||
|
||||
currentindex = pFlow->currentindex;
|
||||
if (outSeqNr > currentindex)
|
||||
{
|
||||
nextIndex = currentindex + 1;
|
||||
if (currentindex + 1 <= outSeqNr)
|
||||
{
|
||||
// This variable makes sure the loops below do not execute more
|
||||
// than NET_FRAMES_BACKUP times. This has to be done as the
|
||||
// headers and frame arrays in the netflow_t structure is as
|
||||
// large as NET_FRAMES_BACKUP. Any execution past it is futile
|
||||
// and only wastes CPU time. Sending an outSeqNr that is higher
|
||||
// than the current index by something like a million or more will
|
||||
// hang the engine for several milliseconds to several seconds.
|
||||
int numPacketFrames = 0;
|
||||
|
||||
v17 = outSeqNr - nextIndex;
|
||||
|
||||
if (v17 + 1 >= 4)
|
||||
{
|
||||
v18 = nChoked + nDropped;
|
||||
v19 = ((unsigned int)(v12 - nextIndex - 3) >> 2) + 1;
|
||||
v20 = nextIndex + 2;
|
||||
v21 = v17 - 2;
|
||||
v22 = v19;
|
||||
time = (float)*g_pNetTime;
|
||||
nextIndex += 4 * v19;
|
||||
|
||||
do
|
||||
{
|
||||
v24 = (v20 - 2) & NET_FRAMES_MASK;
|
||||
v25 = v24;
|
||||
pFlow->frame_headers[v25].time = time;
|
||||
pFlow->frame_headers[v25].valid = 0;
|
||||
pFlow->frame_headers[v25].size = 0;
|
||||
pFlow->frame_headers[v25].latency = -1.0;
|
||||
pFlow->frames[v24].avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency;
|
||||
pFlow->frame_headers[v25].choked = 0;
|
||||
pFlow->frames[v24].dropped = 0;
|
||||
if (v21 + 2 < v18)
|
||||
{
|
||||
if (v21 + 2 >= nChoked)
|
||||
pFlow->frames[v24].dropped = 1;
|
||||
else
|
||||
pFlow->frame_headers[(v20 - 2) & NET_FRAMES_MASK].choked = 1;
|
||||
}
|
||||
v26 = (v20 - 1) & NET_FRAMES_MASK;
|
||||
v27 = v26;
|
||||
pFlow->frame_headers[v27].time = time;
|
||||
pFlow->frame_headers[v27].valid = 0;
|
||||
pFlow->frame_headers[v27].size = 0;
|
||||
pFlow->frame_headers[v27].latency = -1.0;
|
||||
pFlow->frames[v26].avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency;
|
||||
pFlow->frame_headers[v27].choked = 0;
|
||||
pFlow->frames[v26].dropped = 0;
|
||||
if (v21 + 1 < v18)
|
||||
{
|
||||
if (v21 + 1 >= nChoked)
|
||||
pFlow->frames[v26].dropped = 1;
|
||||
else
|
||||
pFlow->frame_headers[(v20 - 1) & NET_FRAMES_MASK].choked = 1;
|
||||
}
|
||||
v28 = v20 & NET_FRAMES_MASK;
|
||||
v29 = v28;
|
||||
pFlow->frame_headers[v29].time = time;
|
||||
pFlow->frame_headers[v29].valid = 0;
|
||||
pFlow->frame_headers[v29].size = 0;
|
||||
pFlow->frame_headers[v29].latency = -1.0;
|
||||
pFlow->frames[v28].avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency;
|
||||
pFlow->frame_headers[v29].choked = 0;
|
||||
pFlow->frames[v28].dropped = 0;
|
||||
if (v21 < v18)
|
||||
{
|
||||
if (v21 >= nChoked)
|
||||
pFlow->frames[v28].dropped = 1;
|
||||
else
|
||||
pFlow->frame_headers[v20 & NET_FRAMES_MASK].choked = 1;
|
||||
}
|
||||
pFrame = &pFlow->frames[(v20 + 1) & NET_FRAMES_MASK];
|
||||
pFrameHeader = &pFlow->frame_headers[(v20 + 1) & NET_FRAMES_MASK];
|
||||
pFrameHeader->time = time;
|
||||
pFrameHeader->valid = 0;
|
||||
pFrameHeader->size = 0;
|
||||
pFrameHeader->latency = -1.0;
|
||||
pFrame->avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency;
|
||||
pFrameHeader->choked = 0;
|
||||
pFrame->dropped = 0;
|
||||
if (v21 - 1 < v18)
|
||||
{
|
||||
if (v21 - 1 >= nChoked)
|
||||
pFrame->dropped = 1;
|
||||
else
|
||||
pFrameHeader->choked = 1;
|
||||
}
|
||||
|
||||
// Incremented by four since this loop does four frames
|
||||
// per iteration.
|
||||
numPacketFrames += 4;
|
||||
v21 -= 4;
|
||||
v20 += 4;
|
||||
--v22;
|
||||
} while (v22 && numPacketFrames < NET_FRAMES_BACKUP);
|
||||
v12 = outSeqNr;
|
||||
v8 = flow;
|
||||
v9 = inSeqNr;
|
||||
}
|
||||
|
||||
// Check if we did not reach NET_FRAMES_BACKUP, else we will
|
||||
// execute the 129'th iteration as well. Also check if the next
|
||||
// index doesn't exceed the outSeqNr.
|
||||
if (numPacketFrames < NET_FRAMES_BACKUP && nextIndex <= v12)
|
||||
{
|
||||
v30 = v12 - nextIndex;
|
||||
v31 = nextIndex;
|
||||
v33 = v12 - nextIndex + 1;
|
||||
do
|
||||
{
|
||||
pFrame = &pFlow->frames[v31 & NET_FRAMES_MASK];
|
||||
pFrameHeader = &pFlow->frame_headers[v31 & NET_FRAMES_MASK];
|
||||
v32 = netTime;
|
||||
pFrameHeader->time = v32;
|
||||
pFrameHeader->valid = 0;
|
||||
pFrameHeader->size = 0;
|
||||
pFrameHeader->latency = -1.0;
|
||||
pFrame->avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency;
|
||||
pFrameHeader->choked = 0;
|
||||
pFrame->dropped = 0;
|
||||
if (v30 < nChoked + nDropped)
|
||||
{
|
||||
if (v30 >= nChoked)
|
||||
pFrame->dropped = 1;
|
||||
else
|
||||
pFrameHeader->choked = 1;
|
||||
}
|
||||
--v30;
|
||||
++v31;
|
||||
--v33;
|
||||
++numPacketFrames;
|
||||
} while (v33 && numPacketFrames < NET_FRAMES_BACKUP);
|
||||
v9 = inSeqNr;
|
||||
}
|
||||
}
|
||||
pFrame->dropped = nDropped;
|
||||
pFrameHeader->choked = (short)nChoked;
|
||||
pFrameHeader->size = nSize;
|
||||
pFrameHeader->valid = 1;
|
||||
pFrame->avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency;
|
||||
}
|
||||
++pFlow->totalpackets;
|
||||
pFlow->currentindex = v12;
|
||||
v34 = 544i64;
|
||||
|
||||
if (!v8)
|
||||
v34 = 3688i64;
|
||||
|
||||
pFlow->current_frame = pFrame;
|
||||
v35 = 548i64;
|
||||
v36 = *(_DWORD*)(&pChan->m_bProcessingMessages + v34);
|
||||
if (v9 > v36 - NET_FRAMES_BACKUP)
|
||||
{
|
||||
if (!v8)
|
||||
v35 = 3692i64;
|
||||
result = (__int64)pChan + 16 * (v9 & NET_FRAMES_MASK);
|
||||
v42 = (netframe_header_t*)(result + v35);
|
||||
if (v42->valid && v42->latency == -1.0)
|
||||
{
|
||||
v43 = 0.0;
|
||||
v44 = fmax(0.0f, netTime - v42->time);
|
||||
v42->latency = v44;
|
||||
if (v44 >= 0.0)
|
||||
v43 = v44;
|
||||
else
|
||||
v42->latency = 0.0;
|
||||
v45 = v43 + pFlow->latency;
|
||||
++pFlow->totalupdates;
|
||||
pFlow->latency = v45;
|
||||
pFlow->maxlatency = fmaxf(pFlow->maxlatency, v42->latency);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!v8)
|
||||
v35 = 3692i64;
|
||||
|
||||
v37 = *(float*)(&pChan->m_bProcessingMessages + 16 * (v36 & NET_FRAMES_MASK) + v35);
|
||||
result = v35 + 16i64 * (((_BYTE)v36 + 1) & NET_FRAMES_MASK);
|
||||
v39 = v37 - *(float*)(&pChan->m_bProcessingMessages + result);
|
||||
++pFlow->totalupdates;
|
||||
v40 = (float)((float)(v39 / 127.0) * (float)(v36 - v9)) + netTime - v37;
|
||||
v41 = fmaxf(pFlow->maxlatency, v40);
|
||||
pFlow->latency = v40 + pFlow->latency;
|
||||
pFlow->maxlatency = v41;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: shutdown netchannel
|
||||
// Input : *this -
|
||||
@ -73,7 +360,7 @@ double CNetChan::GetTimeConnected(void) const
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetChan::_Shutdown(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow)
|
||||
{
|
||||
v_NetChan_Shutdown(pChan, szReason, bBadRep, bRemoveNow);
|
||||
CNetChan__Shutdown(pChan, szReason, bBadRep, bRemoveNow);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -82,35 +369,35 @@ void CNetChan::_Shutdown(CNetChan* pChan, const char* szReason, uint8_t bBadRep,
|
||||
// *pMsg -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::_ProcessMessages(CNetChan* pChan, bf_read* pMsg)
|
||||
bool CNetChan::_ProcessMessages(CNetChan* pChan, bf_read* pBuf)
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if (!ThreadInServerFrameThread() || !net_processTimeBudget->GetInt())
|
||||
return v_NetChan_ProcessMessages(pChan, pMsg);
|
||||
if (!net_processTimeBudget.GetInt() || !ThreadInServerFrameThread())
|
||||
return pChan->ProcessMessages(pBuf);
|
||||
|
||||
const double flStartTime = Plat_FloatTime();
|
||||
const bool bResult = v_NetChan_ProcessMessages(pChan, pMsg);
|
||||
const bool bResult = pChan->ProcessMessages(pBuf);
|
||||
|
||||
if (!pChan->m_MessageHandler) // NetChannel removed?
|
||||
return bResult;
|
||||
|
||||
CClient* pClient = reinterpret_cast<CClient*>(pChan->m_MessageHandler);
|
||||
ServerPlayer_t* pSlot = &g_ServerPlayer[pClient->GetUserID()];
|
||||
CClient* const pClient = reinterpret_cast<CClient*>(pChan->m_MessageHandler);
|
||||
CClientExtended* const pExtended = pClient->GetClientExtended();
|
||||
|
||||
if (flStartTime - pSlot->m_flLastNetProcessTime >= 1.0 ||
|
||||
pSlot->m_flLastNetProcessTime == -1.0)
|
||||
// Reset every second.
|
||||
if ((flStartTime - pExtended->GetNetProcessingTimeBase()) > 1.0)
|
||||
{
|
||||
pSlot->m_flLastNetProcessTime = flStartTime;
|
||||
pSlot->m_flCurrentNetProcessTime = 0.0;
|
||||
pExtended->SetNetProcessingTimeBase(flStartTime);
|
||||
pExtended->SetNetProcessingTimeMsecs(0.0, 0.0);
|
||||
}
|
||||
pSlot->m_flCurrentNetProcessTime +=
|
||||
(Plat_FloatTime() * 1000) - (flStartTime * 1000);
|
||||
|
||||
if (pSlot->m_flCurrentNetProcessTime >
|
||||
net_processTimeBudget->GetDouble())
|
||||
const double flCurrentTime = Plat_FloatTime();
|
||||
pExtended->SetNetProcessingTimeMsecs(flStartTime, flCurrentTime);
|
||||
|
||||
if (pExtended->GetNetProcessingTimeMsecs() > net_processTimeBudget.GetFloat())
|
||||
{
|
||||
Warning(eDLL_T::SERVER, "Removing netchannel '%s' ('%s' exceeded frame budget by '%3.1f'ms!)\n",
|
||||
pChan->GetName(), pChan->GetAddress(), (pSlot->m_flCurrentNetProcessTime - net_processTimeBudget->GetDouble()));
|
||||
Warning(eDLL_T::SERVER, "Removing netchannel '%s' ('%s' exceeded time budget by '%3.1f'ms!)\n",
|
||||
pChan->GetName(), pChan->GetAddress(), (pExtended->GetNetProcessingTimeMsecs() - net_processTimeBudget.GetFloat()));
|
||||
pClient->Disconnect(Reputation_t::REP_MARK_BAD, "#DISCONNECT_NETCHAN_OVERFLOW");
|
||||
|
||||
return false;
|
||||
@ -118,10 +405,157 @@ bool CNetChan::_ProcessMessages(CNetChan* pChan, bf_read* pMsg)
|
||||
|
||||
return bResult;
|
||||
#else // !CLIENT_DLL
|
||||
return v_NetChan_ProcessMessages(pChan, pMsg);
|
||||
return pChan->ProcessMessages(pBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: process message
|
||||
// Input : *buf -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::ProcessMessages(bf_read* buf)
|
||||
{
|
||||
m_bStopProcessing = false;
|
||||
|
||||
const char* showMsgName = net_showmsg->GetString();
|
||||
const char* blockMsgName = net_blockmsg->GetString();
|
||||
const int netPeak = net_showpeaks->GetInt();
|
||||
|
||||
if (*showMsgName == '0')
|
||||
{
|
||||
showMsgName = NULL; // dont do strcmp all the time
|
||||
}
|
||||
|
||||
if (*blockMsgName == '0')
|
||||
{
|
||||
blockMsgName = NULL; // dont do strcmp all the time
|
||||
}
|
||||
|
||||
if (netPeak > 0 && netPeak < buf->GetNumBytesLeft())
|
||||
{
|
||||
showMsgName = "1"; // show messages for this packet only
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
int cmd = net_NOP;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (buf->GetNumBitsLeft() < NETMSG_TYPE_BITS)
|
||||
return true; // Reached the end.
|
||||
|
||||
if (!NET_ReadMessageType(&cmd, buf) && buf->m_bOverflow)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, 0, "%s(%s): Incoming buffer overflow!\n", __FUNCTION__, GetAddress());
|
||||
m_MessageHandler->ConnectionCrashed("Buffer overflow in net message");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmd <= net_Disconnect)
|
||||
break; // Either a Disconnect or NOP packet; process it below.
|
||||
|
||||
INetMessage* netMsg = FindMessage(cmd);
|
||||
|
||||
if (!netMsg)
|
||||
{
|
||||
DevWarning(eDLL_T::ENGINE, "%s(%s): Received unknown net message (%i)!\n",
|
||||
__FUNCTION__, GetAddress(), cmd);
|
||||
Assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!netMsg->ReadFromBuffer(buf))
|
||||
{
|
||||
DevWarning(eDLL_T::ENGINE, "%s(%s): Failed reading message '%s'!\n",
|
||||
__FUNCTION__, GetAddress(), netMsg->GetName());
|
||||
Assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (showMsgName)
|
||||
{
|
||||
if ((*showMsgName == '1') || !Q_stricmp(showMsgName, netMsg->GetName()))
|
||||
{
|
||||
Msg(eDLL_T::ENGINE, "%s(%s): Received: %s\n",
|
||||
__FUNCTION__, GetAddress(), netMsg->ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (blockMsgName)
|
||||
{
|
||||
if ((*blockMsgName == '1') || !Q_stricmp(blockMsgName, netMsg->GetName()))
|
||||
{
|
||||
Msg(eDLL_T::ENGINE, "%s(%s): Blocked: %s\n",
|
||||
__FUNCTION__, GetAddress(), netMsg->ToString());
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Netmessage calls the Process function that was registered by
|
||||
// it's MessageHandler.
|
||||
m_bProcessingMessages = true;
|
||||
const bool bRet = netMsg->Process();
|
||||
m_bProcessingMessages = false;
|
||||
|
||||
// This means we were deleted during the processing of that message.
|
||||
if (m_bShouldDelete)
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
// This means our message buffer was freed or invalidated during
|
||||
// the processing of that message.
|
||||
if (m_bStopProcessing)
|
||||
return false;
|
||||
|
||||
if (!bRet)
|
||||
{
|
||||
DevWarning(eDLL_T::ENGINE, "%s(%s): Failed processing message '%s'!\n",
|
||||
__FUNCTION__, GetAddress(), netMsg->GetName());
|
||||
Assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsOverflowed())
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bProcessingMessages = true;
|
||||
|
||||
if (cmd == net_NOP) // NOP; continue to next packet.
|
||||
{
|
||||
m_bProcessingMessages = false;
|
||||
continue;
|
||||
}
|
||||
else if (cmd == net_Disconnect) // Disconnect request.
|
||||
{
|
||||
char reason[1024];
|
||||
buf->ReadString(reason, sizeof(reason), false);
|
||||
|
||||
m_MessageHandler->ConnectionClosing(reason, 1);
|
||||
m_bProcessingMessages = false;
|
||||
}
|
||||
|
||||
m_bProcessingMessages = false;
|
||||
|
||||
if (m_bShouldDelete)
|
||||
delete this;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CNetChan::ReadSubChannelData(bf_read& buf)
|
||||
{
|
||||
// TODO: rebuild this and hook
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send message
|
||||
// Input : &msg -
|
||||
@ -129,10 +563,10 @@ bool CNetChan::_ProcessMessages(CNetChan* pChan, bf_read* pMsg)
|
||||
// bVoice -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::SendNetMsg(INetMessage& msg, bool bForceReliable, bool bVoice)
|
||||
bool CNetChan::SendNetMsg(INetMessage& msg, const bool bForceReliable, const bool bVoice)
|
||||
{
|
||||
if (remote_address.GetType() == netadrtype_t::NA_NULL)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
bf_write* pStream = &m_StreamUnreliable;
|
||||
|
||||
@ -142,29 +576,127 @@ bool CNetChan::SendNetMsg(INetMessage& msg, bool bForceReliable, bool bVoice)
|
||||
if (bVoice)
|
||||
pStream = &m_StreamVoice;
|
||||
|
||||
if (pStream != &m_StreamUnreliable ||
|
||||
pStream->GetNumBytesLeft() >= NET_UNRELIABLE_STREAM_MINSIZE)
|
||||
{
|
||||
AcquireSRWLockExclusive(&LOCK);
|
||||
if (pStream == &m_StreamUnreliable && pStream->GetNumBytesLeft() < NET_UNRELIABLE_STREAM_MINSIZE)
|
||||
return true;
|
||||
|
||||
AcquireSRWLockExclusive(&m_Lock);
|
||||
|
||||
pStream->WriteUBitLong(msg.GetType(), NETMSG_TYPE_BITS);
|
||||
if (!pStream->IsOverflowed())
|
||||
msg.WriteToBuffer(pStream);
|
||||
const bool ret = msg.WriteToBuffer(pStream);
|
||||
|
||||
ReleaseSRWLockExclusive(&LOCK);
|
||||
ReleaseSRWLockExclusive(&m_Lock);
|
||||
|
||||
return !pStream->IsOverflowed() && ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send data
|
||||
// Input : &msg -
|
||||
// bReliable -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::SendData(bf_write& msg, const bool bReliable)
|
||||
{
|
||||
// Always queue any pending reliable data ahead of the fragmentation buffer
|
||||
|
||||
if (remote_address.GetType() == netadrtype_t::NA_NULL)
|
||||
return true;
|
||||
|
||||
if (msg.GetNumBitsWritten() <= 0)
|
||||
return true;
|
||||
|
||||
if (msg.IsOverflowed() && !bReliable)
|
||||
return true;
|
||||
|
||||
bf_write& buf = bReliable
|
||||
? m_StreamReliable
|
||||
: m_StreamUnreliable;
|
||||
|
||||
const int dataBits = msg.GetNumBitsWritten();
|
||||
const int bitsLeft = buf.GetNumBitsLeft();
|
||||
|
||||
if (dataBits > bitsLeft)
|
||||
{
|
||||
if (bReliable)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, 0, "%s(%s): Data too large for reliable buffer (%i > %i)!\n",
|
||||
__FUNCTION__, GetAddress(), msg.GetNumBytesWritten(), buf.GetNumBytesLeft());
|
||||
|
||||
m_MessageHandler->ChannelDisconnect("reliable buffer is full");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return buf.WriteBits(msg.GetData(), dataBits);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: finds a registered net message by type
|
||||
// Input : type -
|
||||
// Output : net message pointer on success, NULL otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
INetMessage* CNetChan::FindMessage(int type)
|
||||
{
|
||||
int numtypes = m_NetMessages.Count();
|
||||
|
||||
for (int i = 0; i < numtypes; i++)
|
||||
{
|
||||
if (m_NetMessages[i]->GetType() == type)
|
||||
return m_NetMessages[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: registers a net message
|
||||
// Input : *msg
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::RegisterMessage(INetMessage* msg)
|
||||
{
|
||||
Assert(msg);
|
||||
|
||||
if (FindMessage(msg->GetType()))
|
||||
{
|
||||
Assert(0); // Duplicate registration!
|
||||
return false;
|
||||
}
|
||||
|
||||
m_NetMessages.AddToTail(msg);
|
||||
msg->SetNetChannel(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: free's the receive data fragment list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetChan::FreeReceiveList()
|
||||
{
|
||||
m_ReceiveList.blockSize = NULL;
|
||||
m_ReceiveList.transferSize = NULL;
|
||||
if (m_ReceiveList.buffer)
|
||||
{
|
||||
delete m_ReceiveList.buffer;
|
||||
m_ReceiveList.buffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: check if there is still data in the reliable waiting buffers
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::HasPendingReliableData(void)
|
||||
{
|
||||
return (m_StreamReliable.GetNumBitsWritten() > 0)
|
||||
|| (m_WaitingList.Count() > 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void VNetChan::Attach() const
|
||||
void VNetChan::Detour(const bool bAttach) const
|
||||
{
|
||||
DetourAttach((PVOID*)&v_NetChan_Shutdown, &CNetChan::_Shutdown);
|
||||
DetourAttach((PVOID*)&v_NetChan_ProcessMessages, &CNetChan::_ProcessMessages);
|
||||
}
|
||||
void VNetChan::Detach() const
|
||||
{
|
||||
DetourDetach((PVOID*)&v_NetChan_Shutdown, &CNetChan::_Shutdown);
|
||||
DetourDetach((PVOID*)&v_NetChan_ProcessMessages, &CNetChan::_ProcessMessages);
|
||||
DetourSetup(&CNetChan__Shutdown, &CNetChan::_Shutdown, bAttach);
|
||||
DetourSetup(&CNetChan__FlowNewPacket, &CNetChan::_FlowNewPacket, bAttach);
|
||||
DetourSetup(&CNetChan__ProcessMessages, &CNetChan::_ProcessMessages, bAttach);
|
||||
}
|
||||
|
@ -28,18 +28,23 @@ class CClient;
|
||||
class CNetChan;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct netframe_t
|
||||
typedef struct netframe_header_s
|
||||
{
|
||||
float one;
|
||||
float two;
|
||||
float three;
|
||||
float four;
|
||||
float five;
|
||||
float six;
|
||||
};
|
||||
float time;
|
||||
int size;
|
||||
short choked;
|
||||
bool valid;
|
||||
float latency;
|
||||
} netframe_header_t;
|
||||
|
||||
typedef struct netframe_s
|
||||
{
|
||||
int dropped;
|
||||
float avg_latency;
|
||||
} netframe_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct netflow_t
|
||||
typedef struct netflow_s
|
||||
{
|
||||
float nextcompute;
|
||||
float avgbytespersec;
|
||||
@ -48,26 +53,30 @@ struct netflow_t
|
||||
float avgchoke;
|
||||
float avglatency;
|
||||
float latency;
|
||||
float maxlatency;
|
||||
int64_t totalpackets;
|
||||
int64_t totalbytes;
|
||||
int64_t totalupdates;
|
||||
int currentindex;
|
||||
netframe_header_t frame_headers[NET_FRAMES_BACKUP];
|
||||
netframe_t frames[NET_FRAMES_BACKUP];
|
||||
netframe_t current_frame;
|
||||
};
|
||||
netframe_t* current_frame;
|
||||
} netflow_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct dataFragments_t
|
||||
{
|
||||
char* data;
|
||||
int64_t block_size;
|
||||
bool m_bIsCompressed;
|
||||
char* buffer;
|
||||
int64_t blockSize;
|
||||
bool isCompressed;
|
||||
uint8_t gap11[7];
|
||||
int64_t m_nRawSize;
|
||||
bool m_bFirstFragment;
|
||||
bool m_bLastFragment;
|
||||
bool m_bIsOutbound;
|
||||
int64_t uncompressedSize;
|
||||
bool firstFragment;
|
||||
bool lastFragment;
|
||||
bool isOutbound;
|
||||
int transferID;
|
||||
int m_nTransferSize;
|
||||
int m_nCurrentOffset;
|
||||
int transferSize;
|
||||
int currentOffset;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -78,41 +87,39 @@ enum EBufType
|
||||
BUF_VOICE
|
||||
};
|
||||
|
||||
inline CMemory p_NetChan_Clear;
|
||||
inline void(*v_NetChan_Clear)(CNetChan* pChan, bool bStopProcessing);
|
||||
|
||||
inline CMemory p_NetChan_Shutdown;
|
||||
inline void(*v_NetChan_Shutdown)(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow);
|
||||
|
||||
inline CMemory p_NetChan_CanPacket;
|
||||
inline bool(*v_NetChan_CanPacket)(const CNetChan* pChan);
|
||||
|
||||
inline CMemory p_NetChan_SendDatagram;
|
||||
inline int(*v_NetChan_SendDatagram)(CNetChan* pChan, bf_write* pMsg);
|
||||
|
||||
inline CMemory p_NetChan_ProcessMessages;
|
||||
inline bool(*v_NetChan_ProcessMessages)(CNetChan* pChan, bf_read* pMsg);
|
||||
inline void(*CNetChan__Clear)(CNetChan* pChan, bool bStopProcessing);
|
||||
inline void(*CNetChan__Shutdown)(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow);
|
||||
inline bool(*CNetChan__CanPacket)(const CNetChan* pChan);
|
||||
inline void(*CNetChan__FlowNewPacket)(CNetChan* pChan, int flow, int outSeqNr, int inSeqNr, int nChoked, int nDropped, int nSize);
|
||||
inline int(*CNetChan__SendDatagram)(CNetChan* pChan, bf_write* pMsg);
|
||||
inline bool(*CNetChan__ProcessMessages)(CNetChan* pChan, bf_read* pMsg);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CNetChan
|
||||
{
|
||||
public:
|
||||
~CNetChan()
|
||||
{
|
||||
Shutdown("NetChannel removed.", 1, false);
|
||||
FreeReceiveList();
|
||||
}
|
||||
|
||||
inline const char* GetName(void) const { return m_Name; }
|
||||
inline const char* GetAddress(bool onlyBase = false) const { return remote_address.ToString(onlyBase); }
|
||||
inline int GetPort(void) const { return int(ntohs(remote_address.GetPort())); }
|
||||
inline int GetDataRate(void) const { return m_Rate; }
|
||||
inline int GetBufferSize(void) const { return NET_FRAMES_BACKUP; }
|
||||
|
||||
float GetNetworkLoss() const;
|
||||
float GetResendRate() const;
|
||||
|
||||
inline float GetLatency(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].latency; }
|
||||
inline float GetAvgChoke(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgchoke; }
|
||||
inline float GetAvgLatency(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avglatency; }
|
||||
inline float GetAvgLoss(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgloss; }
|
||||
inline float GetAvgPackets(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgpacketspersec; }
|
||||
inline float GetAvgData(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgbytespersec; }
|
||||
inline int64_t GetTotalData(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].totalbytes; }
|
||||
inline int64_t GetTotalPackets(int flow) const { Assert(flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].totalpackets; }
|
||||
inline float GetLatency(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].latency; }
|
||||
inline float GetAvgChoke(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgchoke; }
|
||||
inline float GetAvgLatency(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avglatency; }
|
||||
inline float GetAvgLoss(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgloss; }
|
||||
inline float GetAvgPackets(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgpacketspersec; }
|
||||
inline float GetAvgData(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgbytespersec; }
|
||||
inline int64_t GetTotalData(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].totalbytes; }
|
||||
inline int64_t GetTotalPackets(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].totalpackets; }
|
||||
|
||||
int GetSequenceNr(int flow) const;
|
||||
double GetTimeConnected(void) const;
|
||||
@ -121,19 +128,33 @@ public:
|
||||
inline int GetSocket(void) const { return m_Socket; }
|
||||
inline const bf_write& GetStreamVoice(void) const { return m_StreamVoice; }
|
||||
inline const netadr_t& GetRemoteAddress(void) const { return remote_address; }
|
||||
|
||||
int GetNumBitsWritten(const bool bReliable);
|
||||
int GetNumBitsLeft(const bool bReliable);
|
||||
inline bool IsOverflowed(void) const { return m_StreamReliable.IsOverflowed(); }
|
||||
|
||||
inline bool CanPacket(void) const { return v_NetChan_CanPacket(this); }
|
||||
inline int SendDatagram(bf_write* pDatagram) { return v_NetChan_SendDatagram(this, pDatagram); }
|
||||
bool SendNetMsg(INetMessage& msg, bool bForceReliable, bool bVoice);
|
||||
bool HasPendingReliableData(void);
|
||||
|
||||
inline void Clear(bool bStopProcessing) { v_NetChan_Clear(this, bStopProcessing); }
|
||||
inline void Shutdown(const char* szReason, uint8_t bBadRep, bool bRemoveNow)
|
||||
{ v_NetChan_Shutdown(this, szReason, bBadRep, bRemoveNow); }
|
||||
inline bool CanPacket(void) const { return CNetChan__CanPacket(this); }
|
||||
inline int SendDatagram(bf_write* pDatagram) { return CNetChan__SendDatagram(this, pDatagram); }
|
||||
bool SendNetMsg(INetMessage& msg, const bool bForceReliable, const bool bVoice);
|
||||
bool SendData(bf_write& msg, const bool bReliable);
|
||||
|
||||
INetMessage* FindMessage(int type);
|
||||
bool RegisterMessage(INetMessage* msg);
|
||||
|
||||
inline void Clear(bool bStopProcessing) { CNetChan__Clear(this, bStopProcessing); }
|
||||
inline void Shutdown(const char* szReason, uint8_t bBadRep, bool bRemoveNow) { CNetChan__Shutdown(this, szReason, bBadRep, bRemoveNow); }
|
||||
void FreeReceiveList();
|
||||
bool ProcessMessages(bf_read* pMsg);
|
||||
|
||||
bool ReadSubChannelData(bf_read& buf);
|
||||
|
||||
static void _Shutdown(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow);
|
||||
static bool _ProcessMessages(CNetChan* pChan, bf_read* pMsg);
|
||||
|
||||
static void _FlowNewPacket(CNetChan* pChan, int flow, int outSeqNr, int inSeqNr, int nChoked, int nDropped, int nSize);
|
||||
|
||||
void SetChoked();
|
||||
void SetRemoteFramerate(float flFrameTime, float flFrameTimeStdDeviation);
|
||||
inline void SetRemoteCPUStatistics(uint8_t nStats) { m_nServerCPU = nStats; }
|
||||
@ -143,19 +164,16 @@ public:
|
||||
bool m_bProcessingMessages;
|
||||
bool m_bShouldDelete;
|
||||
bool m_bStopProcessing;
|
||||
bool shutting_down;
|
||||
bool m_bShuttingDown;
|
||||
int m_nOutSequenceNr;
|
||||
int m_nInSequenceNr;
|
||||
int m_nOutSequenceNrAck;
|
||||
int m_nChokedPackets;
|
||||
int unknown_challenge_var;
|
||||
int m_nRealTimePackets; // Number of packets without pre-scaled frame times.
|
||||
|
||||
private:
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
char pad[8];
|
||||
#endif
|
||||
int m_nLastRecvFlags;
|
||||
RTL_SRWLOCK LOCK;
|
||||
RTL_SRWLOCK m_Lock;
|
||||
bf_write m_StreamReliable;
|
||||
CUtlMemory<byte> m_ReliableDataBuffer;
|
||||
bf_write m_StreamUnreliable;
|
||||
@ -181,11 +199,11 @@ private:
|
||||
uint32_t m_nSubOutSequenceNr;
|
||||
int m_nLastRecvNonce;
|
||||
bool m_bUseCompression;
|
||||
uint32_t dword168;
|
||||
uint32_t m_ChallengeNr;
|
||||
float m_Timeout;
|
||||
INetChannelHandler* m_MessageHandler;
|
||||
CUtlVector<INetMessage*> m_NetMessages;
|
||||
uint64_t qword198;
|
||||
void* m_UnusedInterfacePointer; // Previously: IDemoRecorder* m_DemoRecorder.
|
||||
int m_nQueuedPackets;
|
||||
float m_flRemoteFrameTime;
|
||||
float m_flRemoteFrameTimeStdDeviation;
|
||||
@ -195,7 +213,7 @@ private:
|
||||
int64_t m_StreamSendBuffer;
|
||||
bf_write m_StreamSend;
|
||||
uint8_t m_bInMatch_maybe;
|
||||
netflow_t m_DataFlow[2];
|
||||
netflow_t m_DataFlow[MAX_FLOWS];
|
||||
int m_nLifetimePacketsDropped;
|
||||
int m_nSessionPacketsDropped;
|
||||
int m_nSequencesSkipped_MAYBE;
|
||||
@ -205,11 +223,7 @@ private:
|
||||
char m_Name[NET_CHANNELNAME_MAXLEN];
|
||||
netadr_t remote_address;
|
||||
};
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
static_assert(sizeof(CNetChan) == 0x1AD0);
|
||||
#else
|
||||
static_assert(sizeof(CNetChan) == 0x1AC8);
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the remote frame times
|
||||
@ -237,33 +251,25 @@ class VNetChan : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CNetChan::Clear", p_NetChan_Clear.GetPtr());
|
||||
LogFunAdr("CNetChan::Shutdown", p_NetChan_Shutdown.GetPtr());
|
||||
LogFunAdr("CNetChan::CanPacket", p_NetChan_CanPacket.GetPtr());
|
||||
LogFunAdr("CNetChan::SendDatagram", p_NetChan_SendDatagram.GetPtr());
|
||||
LogFunAdr("CNetChan::ProcessMessages", p_NetChan_ProcessMessages.GetPtr());
|
||||
LogFunAdr("CNetChan::Clear", CNetChan__Clear);
|
||||
LogFunAdr("CNetChan::Shutdown", CNetChan__Shutdown);
|
||||
LogFunAdr("CNetChan::CanPacket", CNetChan__CanPacket);
|
||||
LogFunAdr("CNetChan::FlowNewPacket", CNetChan__FlowNewPacket);
|
||||
LogFunAdr("CNetChan::SendDatagram", CNetChan__SendDatagram);
|
||||
LogFunAdr("CNetChan::ProcessMessages", CNetChan__ProcessMessages);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_NetChan_Clear = g_GameDll.FindPatternSIMD("88 54 24 10 53 55 57");
|
||||
v_NetChan_Clear = p_NetChan_Clear.RCast<void (*)(CNetChan*, bool)>();
|
||||
|
||||
p_NetChan_Shutdown = g_GameDll.FindPatternSIMD("48 89 6C 24 18 56 57 41 56 48 83 EC 30 83 B9");
|
||||
v_NetChan_Shutdown = p_NetChan_Shutdown.RCast<void (*)(CNetChan*, const char*, uint8_t, bool)>();
|
||||
|
||||
p_NetChan_CanPacket = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B D9 75 15 48 8B 05 ?? ?? ?? ??");
|
||||
v_NetChan_CanPacket = p_NetChan_CanPacket.RCast<bool (*)(const CNetChan*)>();
|
||||
|
||||
p_NetChan_SendDatagram = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 56 41 57 48 83 EC 70");
|
||||
v_NetChan_SendDatagram = p_NetChan_SendDatagram.RCast<int (*)(CNetChan*, bf_write*)>();
|
||||
|
||||
p_NetChan_ProcessMessages = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B FA");
|
||||
v_NetChan_ProcessMessages = p_NetChan_ProcessMessages.RCast<bool (*)(CNetChan*, bf_read*)>();
|
||||
g_GameDll.FindPatternSIMD("88 54 24 10 53 55 57").GetPtr(CNetChan__Clear);
|
||||
g_GameDll.FindPatternSIMD("48 89 6C 24 18 56 57 41 56 48 83 EC 30 83 B9").GetPtr(CNetChan__Shutdown);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B D9 75 15 48 8B 05 ?? ?? ?? ??").GetPtr(CNetChan__CanPacket);
|
||||
g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 89 44 24 ?? 89 54 24 10 56").GetPtr(CNetChan__FlowNewPacket);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 56 41 57 48 83 EC 70").GetPtr(CNetChan__SendDatagram);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B FA").GetPtr(CNetChan__ProcessMessages);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -95,33 +95,29 @@ void CNetworkStringTableContainer::WriteUpdateMessage(CNetworkStringTableContain
|
||||
#ifndef CLIENT_DLL
|
||||
if (sv_stats->GetBool())
|
||||
{
|
||||
uint8_t nCPUPercentage = static_cast<uint8_t>(g_pServer->GetCPUUsage() * 100.0f);
|
||||
const uint8_t nCPUPercentage = static_cast<uint8_t>(g_pServer->GetCPUUsage() * 100.0f);
|
||||
SVC_ServerTick serverTick(g_pServer->GetTick(), *host_frametime_unbounded, *host_frametime_stddeviation, nCPUPercentage);
|
||||
|
||||
serverTick.m_nGroup = 0;
|
||||
serverTick.m_bReliable = true;
|
||||
serverTick.m_NetTick.m_nCommandTick = -1; // Statistics only, see 'CClientState::VProcessServerTick'.
|
||||
|
||||
// -1 means we update statistics only; see 'CClientState::VProcessServerTick()'.
|
||||
serverTick.m_NetTick.m_nCommandTick = -1;
|
||||
|
||||
pMsg->WriteUBitLong(serverTick.GetType(), NETMSG_TYPE_BITS);
|
||||
|
||||
if (!pMsg->IsOverflowed())
|
||||
{
|
||||
serverTick.WriteToBuffer(pMsg);
|
||||
}
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
v_CNetworkStringTableContainer__WriteUpdateMessage(thisp, pClient, nTickAck, pMsg);
|
||||
|
||||
Assert(!pMsg->IsOverflowed(), "Snapshot buffer overflowed before string table update!");
|
||||
CNetworkStringTableContainer__WriteUpdateMessage(thisp, pClient, nTickAck, pMsg);
|
||||
}
|
||||
|
||||
void VNetworkStringTableContainer::Attach() const
|
||||
void VNetworkStringTableContainer::Detour(const bool bAttach) const
|
||||
{
|
||||
#if !defined (CLIENT_DLL) && !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) // TODO: doesn't work properly for S0/S1 yet.
|
||||
DetourAttach(&v_CNetworkStringTableContainer__WriteUpdateMessage, &CNetworkStringTableContainer::WriteUpdateMessage);
|
||||
#endif // !CLIENT_DLL && !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
}
|
||||
|
||||
void VNetworkStringTableContainer::Detach() const
|
||||
{
|
||||
#if !defined (CLIENT_DLL) && !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) // TODO: doesn't work properly for S0/S1 yet.
|
||||
DetourDetach(&v_CNetworkStringTableContainer__WriteUpdateMessage, &CNetworkStringTableContainer::WriteUpdateMessage);
|
||||
#endif // !CLIENT_DLL && !GAMEDLL_S0 && !GAMEDLL_S1
|
||||
DetourSetup(&CNetworkStringTableContainer__WriteUpdateMessage, &CNetworkStringTableContainer::WriteUpdateMessage, bAttach);
|
||||
}
|
@ -9,19 +9,32 @@
|
||||
#define NETWORKSTRINGTABLE_H
|
||||
#include "tier0/fasttimer.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlhashtable.h"
|
||||
#include "tier1/bitbuf.h"
|
||||
#include "public/networkstringtabledefs.h"
|
||||
#include "client/client.h"
|
||||
|
||||
typedef int TABLEID;
|
||||
|
||||
class INetworkStringTable
|
||||
{
|
||||
INetworkStringTable* m_pVTable;
|
||||
};
|
||||
|
||||
class CNetworkStringTable : public INetworkStringTable
|
||||
{
|
||||
public:
|
||||
// Updating/Writing
|
||||
virtual bool WriteStringTable(bf_write& buf) = 0;
|
||||
virtual bool ReadStringTable(bf_read& buf) = 0;
|
||||
|
||||
virtual void ParseUpdate(bf_read& buf, int numStrings) = 0;
|
||||
|
||||
virtual pfnStringChanged GetCallback(void) = 0;
|
||||
|
||||
virtual int WriteUpdate(CClient* const client, bf_write& buf, int tickAck) = 0;
|
||||
virtual bool WriteBaselines(SVC_CreateStringTable& msg, char* msgBuffer, int msgBufferSize) = 0;
|
||||
|
||||
virtual void PurgeAllClientSide(void) = 0;
|
||||
virtual void EnableRollback(bool bState) = 0;
|
||||
|
||||
// TODO[ AMOS ]: there are a few more entries below in the vftable that
|
||||
// need to be mapped out, most of them set/get bit fields;
|
||||
// see [ r5apex_ds + 0x1329888 ]
|
||||
|
||||
TABLEID GetTableId(void) const;
|
||||
int GetMaxStrings(void) const;
|
||||
const char* GetTableName(void) const;
|
||||
@ -41,42 +54,39 @@ private:
|
||||
// !TODO
|
||||
};
|
||||
|
||||
class CNetworkStringTableContainer : public INetworkStringTable
|
||||
class CNetworkStringTableContainer : public INetworkStringTableContainer
|
||||
{
|
||||
public:
|
||||
static void WriteUpdateMessage(CNetworkStringTableContainer* thisp, CClient* client, unsigned int tick_ack, bf_write* msg);
|
||||
|
||||
// Guards so game .dll can't create tables at the wrong time
|
||||
inline void AllowCreation(bool state) { m_bAllowCreation = state; }
|
||||
|
||||
private:
|
||||
bool m_bAllowCreation; // create guard
|
||||
int m_nTickCount; // current tick
|
||||
bool m_bLocked; // currently locked?
|
||||
bool m_bEnableRollback; // enables rollback feature
|
||||
|
||||
CUtlVector < CNetworkStringTable* > m_Tables; // the string tables
|
||||
};
|
||||
|
||||
inline CMemory p_CNetworkStringTableContainer__WriteUpdateMessage;
|
||||
inline void (*v_CNetworkStringTableContainer__WriteUpdateMessage)(CNetworkStringTableContainer* thisp, CClient* client, unsigned int tick_ack, bf_write* msg);
|
||||
inline void (*CNetworkStringTableContainer__WriteUpdateMessage)(CNetworkStringTableContainer* thisp, CClient* client, unsigned int tick_ack, bf_write* msg);
|
||||
|
||||
class VNetworkStringTableContainer : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CNetworkStringTableContainer::WriteUpdateMessage", p_CNetworkStringTableContainer__WriteUpdateMessage.GetPtr());
|
||||
LogFunAdr("CNetworkStringTableContainer::WriteUpdateMessage", CNetworkStringTableContainer__WriteUpdateMessage);
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CNetworkStringTableContainer__WriteUpdateMessage = g_GameDll.FindPatternSIMD("48 89 74 24 ?? 55 57 41 54 41 55 41 56 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ??");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CNetworkStringTableContainer__WriteUpdateMessage = g_GameDll.FindPatternSIMD("48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 45 33 ED");
|
||||
#endif
|
||||
v_CNetworkStringTableContainer__WriteUpdateMessage =
|
||||
p_CNetworkStringTableContainer__WriteUpdateMessage.RCast<void (*)(CNetworkStringTableContainer*, CClient*, unsigned int, bf_write*)>();
|
||||
g_GameDll.FindPatternSIMD("48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 45 33 ED")
|
||||
.GetPtr(CNetworkStringTableContainer__WriteUpdateMessage);
|
||||
}
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
virtual void Detour(const bool bAttach) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -7,24 +7,5 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "engine/sdk_dll.h"
|
||||
#ifndef DEDICATED
|
||||
#include "gameui/IBrowser.h"
|
||||
#include "gameui/IConsole.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEngineSDK::FixedFrame()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
g_pBrowser->Think();
|
||||
g_pConsole->Think();
|
||||
#endif // !DEDICATED
|
||||
std::this_thread::sleep_for(IntervalToDuration(sdk_fixedframe_tickinterval->GetFloat()));
|
||||
}
|
||||
}
|
||||
|
||||
CEngineSDK* g_EngineSDK = new CEngineSDK();
|
||||
CEngineSDK g_EngineSDK;
|
||||
|
@ -4,9 +4,8 @@
|
||||
class CEngineSDK
|
||||
{
|
||||
public:
|
||||
void FixedFrame();
|
||||
};
|
||||
|
||||
extern CEngineSDK* g_EngineSDK;
|
||||
extern CEngineSDK g_EngineSDK;
|
||||
|
||||
#endif // SDK_DLL_H
|
||||
|
@ -4,24 +4,59 @@
|
||||
//
|
||||
//===========================================================================//
|
||||
#include "engine/client/client.h"
|
||||
#include "common/proto_oob.h"
|
||||
#include "datablock_sender.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
ServerDataBlockSender::~ServerDataBlockSender()
|
||||
{
|
||||
v_ServerDataBlockSender__Destructor(this);
|
||||
}
|
||||
static ConVar net_compressDataBlockLzAcceleration("net_compressDataBlockLzAcceleration", "1", FCVAR_DEVELOPMENTONLY, "The acceleration value for LZ4 data block compression");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sends the data block
|
||||
//-----------------------------------------------------------------------------
|
||||
void ServerDataBlockSender::SendDataBlock(short unk0, int unk1,
|
||||
short unk2, short unk3, const void* buffer, int length)
|
||||
void ServerDataBlockSender::SendDataBlock(const short transferId, const int transferSize,
|
||||
const short transferNr, const short blockNr, const uint8_t* const blockData, const int blockSize)
|
||||
{
|
||||
v_ServerDataBlockSender__SendDataBlock(this, unk0, unk1,
|
||||
unk2, unk3, buffer, length);
|
||||
const CClient* const cl = m_pClient;
|
||||
|
||||
if (!cl)
|
||||
{
|
||||
Assert(0, "ServerDataBlockSender::SendDataBlock() called without a valid client handle!");
|
||||
return;
|
||||
}
|
||||
|
||||
const CNetChan* const chan = cl->m_NetChannel;
|
||||
|
||||
if (!chan)
|
||||
{
|
||||
Assert(0, "ServerDataBlockSender::SendDataBlock() called without a valid net channel!");
|
||||
return;
|
||||
}
|
||||
|
||||
char dataBuf[DATABLOCK_FRAGMENT_PACKET_SIZE];
|
||||
bf_write buf(&dataBuf, sizeof(dataBuf));
|
||||
|
||||
// msg data (gets processed on client's out of band packet handler)
|
||||
buf.WriteLong(CONNECTIONLESS_HEADER);
|
||||
buf.WriteByte(S2C_DATABLOCK_FRAGMENT);
|
||||
|
||||
// transfer info
|
||||
buf.WriteByte(transferId);
|
||||
buf.WriteLong(transferSize);
|
||||
buf.WriteByte(transferNr);
|
||||
|
||||
// block info
|
||||
buf.WriteByte(blockNr);
|
||||
buf.WriteLong(blockSize);
|
||||
|
||||
// block data
|
||||
buf.WriteBytes(blockData, blockSize);
|
||||
|
||||
// send the data block packet
|
||||
v_NET_SendPacket(NULL,
|
||||
chan->GetSocket(),
|
||||
chan->GetRemoteAddress(),
|
||||
buf.GetData(),
|
||||
buf.GetNumBytesWritten(),
|
||||
NULL, false, NULL, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -29,26 +64,25 @@ void ServerDataBlockSender::SendDataBlock(short unk0, int unk1,
|
||||
//-----------------------------------------------------------------------------
|
||||
float ServerDataBlockSender::GetResendRate() const
|
||||
{
|
||||
float flRet = 0.0f;
|
||||
const CClient* const pClient = m_pClient;
|
||||
|
||||
if (!m_pClient)
|
||||
return flRet;
|
||||
if (!pClient)
|
||||
return 0.0f;
|
||||
|
||||
const CNetChan* const pChan = pClient->GetNetChan();
|
||||
|
||||
CNetChan* pChan = m_pClient->GetNetChan();
|
||||
if (!pChan)
|
||||
return flRet;
|
||||
return 0.0f;
|
||||
|
||||
if (!m_bStartedTransfer)
|
||||
{
|
||||
flRet = pChan->GetNetworkLoss();
|
||||
if (m_bStartedTransfer)
|
||||
return 0.0f;
|
||||
|
||||
if (flRet < net_datablock_networkLossForSlowSpeed->GetFloat())
|
||||
{
|
||||
const float netResendRate = pChan->GetResendRate();
|
||||
|
||||
if (netResendRate < net_datablock_networkLossForSlowSpeed->GetFloat())
|
||||
return m_flResendRate;
|
||||
}
|
||||
}
|
||||
|
||||
return flRet;
|
||||
return netResendRate;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -58,3 +92,57 @@ const char* ServerDataBlockSender::GetReceiverName() const
|
||||
{
|
||||
return m_pClient->m_szServerName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: write the whole data in the data block scratch buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
void ServerDataBlockSender::WriteDataBlock(const uint8_t* const sourceData, const int dataSize,
|
||||
const bool isMultiplayer, const char* const debugName)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_Lock);
|
||||
|
||||
ServerDataBlockHeader_s* const pHeader = reinterpret_cast<ServerDataBlockHeader_s*>(m_pScratchBuffer);
|
||||
bool copyRaw = true;
|
||||
|
||||
int actualDataSize = dataSize;
|
||||
|
||||
if (net_compressDataBlock->GetBool())
|
||||
{
|
||||
const int encodedSize = LZ4_compress_fast((const char*)sourceData, (char*)m_pScratchBuffer + sizeof(ServerDataBlockHeader_s),
|
||||
dataSize, SNAPSHOT_SCRATCH_BUFFER_SIZE, net_compressDataBlockLzAcceleration.GetInt());
|
||||
|
||||
// this shouldn't happen at all
|
||||
if (!encodedSize)
|
||||
{
|
||||
Assert(0);
|
||||
Error(eDLL_T::SERVER, 0, "LZ4 error compressing data block for client.\n");
|
||||
}
|
||||
|
||||
// make sure the encoded data is smaller than the raw data, in some cases
|
||||
// this might turn larger which means we should just send raw data
|
||||
else if (encodedSize < dataSize)
|
||||
{
|
||||
actualDataSize = encodedSize;
|
||||
|
||||
pHeader->isCompressed = true;
|
||||
copyRaw = false;
|
||||
}
|
||||
}
|
||||
|
||||
// in case no compression was performed, we send the raw data
|
||||
if (copyRaw)
|
||||
{
|
||||
// this should equal the dataSize at this point, even if compression failed
|
||||
Assert(actualDataSize == dataSize);
|
||||
|
||||
pHeader->isCompressed = false;
|
||||
memcpy(m_pScratchBuffer + sizeof(ServerDataBlockHeader_s), sourceData, actualDataSize);
|
||||
}
|
||||
|
||||
// NOTE: we copy data in the scratch buffer with an offset of
|
||||
// sizeof(ServerDataBlockHeader_s), the header gets send up as well so we
|
||||
// have to take this into account !!!
|
||||
StartBlockSender(actualDataSize + sizeof(ServerDataBlockHeader_s), isMultiplayer, debugName);
|
||||
|
||||
ReleaseSRWLockExclusive(&m_Lock);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user