mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-15 15:09:30 +00:00
1.5.4 (#7)
* toggle use_folders on
* Rename pipelines
* its a strcpy :(
* add miniz, add xorstream, add non-working ziploader
* start integrating libzip (WIP)
* use ExternalProject test (doesnt work maybe?!)
* further work in integrating libzippp [WIP]
can't build libzip yet (neither manually nor in the vs build), as it doesn't find zlib
* LibZip build script
* make libzip build too
todo: specify cmake find_library to check the paths we install to
* prepare everything in cmake
* fix rebuilding of libzip/zlib
* fix stupid double quotes
* libzippp works
* Setup libzippp archive loading
* Remove allocation of new data when adding file to TextureServer
* Enable CI on dev
* Create LICENSE (#5)
* add mbedtls
* fix cmake (forgot to substitute, woops)
* fix %lu warnings for printing addresses
* enable debug messages, some formatting
* remove mbedtls, fix libzip for /MD(d)
* some code changes
* fix cmake logic, str replace min cmake version in libzip-src/CMakeLists.txt to 3.15
* linker errors in release
* c++ify a little
* remove unnecessary duplicate c++23 definition
* Fixes to gMod_XorStream when calculating stream length
* Fix loading tpf contents with password
* Implemented complete parsing
* Cleanup file loading
* Change to NI
* Revert "Change to NI"
This reverts commit 19b511d907.
* update XorStreamReader to read whole file, then xor
* delete a lot of unused code
* loading logic
* rename console window
* 1.5.4
* remove pointless mutex
* wtf is this code
---------
Co-authored-by: Alex Macocian <amacocian@yahoo.com>
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
# This continuous integration pipeline is triggered anytime a user pushes code to the repo.
|
||||
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
|
||||
name: uMod CD Pipeline
|
||||
name: gMod CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -114,4 +112,3 @@ jobs:
|
||||
body_mrkdwn: ${{ env.Changelog }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# This continuous integration pipeline is triggered anytime a user pushes code to the repo.
|
||||
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
|
||||
name: uMod CI Pipeline
|
||||
name: gMod CI Pipeline
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@@ -89,4 +90,3 @@ jobs:
|
||||
run: cmake --build build --config Release
|
||||
env:
|
||||
DXSDK_DIR: ${{ env.DXSDK_DIR }}
|
||||
|
||||
+35
-11
@@ -1,27 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_GENERATOR_PLATFORM win32)
|
||||
|
||||
project(gMod)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
if(NOT(CMAKE_SIZEOF_VOID_P EQUAL 4))
|
||||
message(FATAL_ERROR "You are configuring a non 32-bit build, this is not supported. Run cmake with `-A Win32`")
|
||||
endif()
|
||||
|
||||
option(CLEAN "Cleans third party libraries and recompiles them" OFF)
|
||||
if(${CLEAN} MATCHES "ON")
|
||||
message("Removing directory: ${PROJECT_SOURCE_DIR}/bin/install")
|
||||
file(REMOVE_RECURSE ${PROJECT_SOURCE_DIR}/bin/install)
|
||||
endif()
|
||||
|
||||
set(VERSION_MAJOR 1)
|
||||
set(VERSION_MINOR 5)
|
||||
set(VERSION_PATCH 3)
|
||||
set(VERSION_PATCH 4)
|
||||
set(VERSION_TWEAK 0)
|
||||
|
||||
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in" "${VERSION_RC}" @ONLY)
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin/")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS OFF)
|
||||
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/bin/install)
|
||||
|
||||
add_compile_options(/MP /permissive-)
|
||||
|
||||
@@ -30,17 +36,20 @@ find_library(D3DX9_LIB NAMES d3dx9 PATHS $ENV{DXSDK_DIR}/lib/x86 NO_DEFAULT_PATH
|
||||
find_library(DXGUID_LIB NAMES dxguid PATHS $ENV{DXSDK_DIR}/lib/x86 NO_DEFAULT_PATH)
|
||||
|
||||
if(NOT D3D9_LIB)
|
||||
find_library(D3D9_LIB NAMES d3d9 PATHS ${CMAKE_SOURCE_DIR}/Lib)
|
||||
find_library(D3D9_LIB NAMES d3d9 PATHS ${CMAKE_SOURCE_DIR}/Lib)
|
||||
endif()
|
||||
|
||||
if(NOT D3DX9_LIB)
|
||||
find_library(D3DX9_LIB NAMES d3dx9 PATHS ${CMAKE_SOURCE_DIR}/Lib)
|
||||
find_library(D3DX9_LIB NAMES d3dx9 PATHS ${CMAKE_SOURCE_DIR}/Lib)
|
||||
endif()
|
||||
|
||||
if(NOT DXGUID_LIB)
|
||||
find_library(DXGUID_LIB NAMES dxguid PATHS ${CMAKE_SOURCE_DIR}/Lib)
|
||||
find_library(DXGUID_LIB NAMES dxguid PATHS ${CMAKE_SOURCE_DIR}/Lib)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
include(libzippp)
|
||||
|
||||
add_library(gMod SHARED)
|
||||
|
||||
file(GLOB SOURCES
|
||||
@@ -49,9 +58,24 @@ file(GLOB SOURCES
|
||||
${VERSION_RC}
|
||||
)
|
||||
|
||||
target_link_libraries(gMod PRIVATE ${D3D9_LIB} ${D3DX9_LIB} ${DXGUID_LIB})
|
||||
target_include_directories(gMod PRIVATE $ENV{DXSDK_DIR}/Include)
|
||||
target_include_directories(gMod PUBLIC "header")
|
||||
target_include_directories(gMod PUBLIC
|
||||
"header"
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
)
|
||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
|
||||
target_sources(gMod PRIVATE ${SOURCES})
|
||||
|
||||
target_link_libraries(gMod PRIVATE
|
||||
${D3D9_LIB}
|
||||
${D3DX9_LIB}
|
||||
${DXGUID_LIB}
|
||||
libzippp
|
||||
psapi
|
||||
)
|
||||
target_link_options(gMod PRIVATE
|
||||
"$<$<CONFIG:DEBUG>:/NODEFAULTLIB:LIBCMT>"
|
||||
)
|
||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
|
||||
target_sources(gMod PRIVATE ${SOURCES})
|
||||
target_compile_definitions(gMod PRIVATE
|
||||
@@ -61,4 +85,4 @@ target_compile_definitions(gMod PRIVATE
|
||||
"VC_EXTRALEAN"
|
||||
DIRECT_INJECTION
|
||||
LOG_MESSAGE
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,65 @@
|
||||
include_guard()
|
||||
include(FetchContent)
|
||||
include(zlib)
|
||||
|
||||
FetchContent_Declare(
|
||||
libzip
|
||||
GIT_REPOSITORY https://github.com/nih-at/libzip
|
||||
GIT_TAG v1.10.1)
|
||||
FetchContent_GetProperties(libzip)
|
||||
|
||||
if (libzip_POPULATED)
|
||||
message(STATUS "Skipping libzip download")
|
||||
return()
|
||||
endif()
|
||||
|
||||
FetchContent_Populate(libzip)
|
||||
if(EXISTS ${CMAKE_INSTALL_PREFIX}/lib/zip.lib)
|
||||
message(STATUS "Skipping libzip build")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(OPTIONS
|
||||
"-A" "Win32"
|
||||
"-DZLIB_LIBRARY:PATH=${CMAKE_INSTALL_PREFIX}/lib/zlibstatic.lib"
|
||||
"-DZLIB_INCLUDE_DIR:PATH=${CMAKE_INSTALL_PREFIX}/include"
|
||||
"-DENABLE_COMMONCRYPTO=OFF"
|
||||
"-DENABLE_GNUTLS=OFF"
|
||||
"-DENABLE_MBEDTLS=OFF"
|
||||
"-DENABLE_OPENSSL=OFF"
|
||||
"-DENABLE_WINDOWS_CRYPTO=ON"
|
||||
"-DENABLE_FDOPEN=OFF"
|
||||
"-DENABLE_BZIP2=OFF"
|
||||
"-DENABLE_LZMA=OFF"
|
||||
"-DENABLE_ZSTD=OFF"
|
||||
"-DBUILD_TOOLS=OFF"
|
||||
"-DBUILD_REGRESS=OFF"
|
||||
"-DBUILD_EXAMPLES=OFF"
|
||||
"-DBUILD_DOC=OFF"
|
||||
"-DLIBZIP_DO_INSTALL=ON"
|
||||
"-DBUILD_SHARED_LIBS=OFF"
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
"-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}"
|
||||
)
|
||||
|
||||
message("Building libzip with OPTIONS:\n${OPTIONS}")
|
||||
|
||||
# Patch CMakeLists.txt to require version 3.15 - otherwise cmake ignores MSVC_RUNTIME_LIBRARY
|
||||
file(READ ${libzip_SOURCE_DIR}/CMakeLists.txt FILE_CONTENT)
|
||||
string(REPLACE "VERSION 3.5.0" "VERSION 3.15.0" UPDATED_CONTENT "${FILE_CONTENT}")
|
||||
file(WRITE ${libzip_SOURCE_DIR}/CMakeLists.txt "${UPDATED_CONTENT}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} ${OPTIONS} .
|
||||
WORKING_DIRECTORY ${libzip_SOURCE_DIR}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --build . --config Release
|
||||
WORKING_DIRECTORY ${libzip_SOURCE_DIR}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --install . --config Release
|
||||
WORKING_DIRECTORY ${libzip_SOURCE_DIR}
|
||||
)
|
||||
|
||||
message(STATUS "Finished libzip build")
|
||||
@@ -0,0 +1,42 @@
|
||||
include_guard()
|
||||
include(FetchContent)
|
||||
include(libzip)
|
||||
|
||||
find_library(ZLIB_LIBRARY REQUIRED
|
||||
NAMES zlibstatic
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
find_library(LIBZIP_LIBRARY REQUIRED
|
||||
NAMES zip
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
|
||||
FetchContent_Declare(
|
||||
libzippp
|
||||
GIT_REPOSITORY https://github.com/ctabin/libzippp
|
||||
GIT_TAG libzippp-v7.0-1.10.1)
|
||||
FetchContent_GetProperties(libzippp)
|
||||
|
||||
if (NOT libzippp_POPULATED)
|
||||
FetchContent_Populate(libzippp)
|
||||
endif()
|
||||
|
||||
add_library(libzippp)
|
||||
|
||||
set(SOURCES
|
||||
"${libzippp_SOURCE_DIR}/src/libzippp.h"
|
||||
"${libzippp_SOURCE_DIR}/src/libzippp.cpp"
|
||||
)
|
||||
source_group(TREE ${libzippp_SOURCE_DIR} FILES ${SOURCES})
|
||||
target_sources(libzippp PRIVATE ${SOURCES})
|
||||
target_include_directories(libzippp PUBLIC "${libzippp_SOURCE_DIR}/src")
|
||||
target_include_directories(libzippp PRIVATE "${CMAKE_INSTALL_PREFIX}/include")
|
||||
target_compile_definitions(libzippp PUBLIC
|
||||
LIBZIPPP_WITH_ENCRYPTION
|
||||
)
|
||||
target_link_libraries(libzippp PRIVATE
|
||||
${LIBZIP_LIBRARY}
|
||||
${ZLIB_LIBRARY}
|
||||
)
|
||||
|
||||
set_target_properties(libzippp PROPERTIES FOLDER "Dependencies/")
|
||||
@@ -0,0 +1,47 @@
|
||||
include_guard()
|
||||
include(FetchContent)
|
||||
|
||||
# Fetch zlib using FetchContent
|
||||
FetchContent_Declare(
|
||||
zlib
|
||||
GIT_REPOSITORY https://github.com/madler/zlib
|
||||
GIT_TAG v1.3
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(zlib)
|
||||
|
||||
if(zlib_POPULATED)
|
||||
message(STATUS "Skipping zlib download")
|
||||
return()
|
||||
endif()
|
||||
|
||||
FetchContent_Populate(zlib)
|
||||
|
||||
if(EXISTS ${CMAKE_INSTALL_PREFIX}/lib/zlibstatic.lib)
|
||||
message(STATUS "Skipping zlib build")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(OPTIONS
|
||||
"-A" "Win32"
|
||||
"-DBUILD_SHARED_LIBS=OFF"
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
"-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}"
|
||||
)
|
||||
|
||||
message("Building zlib with OPTIONS:\n${OPTIONS}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} ${OPTIONS} .
|
||||
WORKING_DIRECTORY ${zlib_SOURCE_DIR}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --build . --config Release
|
||||
WORKING_DIRECTORY ${zlib_SOURCE_DIR}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --install . --config Release
|
||||
WORKING_DIRECTORY ${zlib_SOURCE_DIR}
|
||||
)
|
||||
|
||||
message(STATUS "Finished zlib build")
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
class XorStreamReader {
|
||||
public:
|
||||
XorStreamReader(const std::string& path)
|
||||
{
|
||||
file_stream = std::ifstream(path, std::ios::binary);
|
||||
if (!file_stream.seekg(0, std::ios::end).good() || !file_stream.seekg(0, std::ios::beg).good()) {
|
||||
throw std::invalid_argument("Provided stream needs to have SEEK set to True");
|
||||
}
|
||||
}
|
||||
|
||||
~XorStreamReader()
|
||||
{
|
||||
file_stream.close();
|
||||
}
|
||||
|
||||
std::vector<char> ReadToEnd()
|
||||
{
|
||||
file_stream.seekg(0, std::ios::end);
|
||||
line_length = file_stream.tellg();
|
||||
file_stream.seekg(0, std::ios::beg); // Go to the beginning of the stream
|
||||
|
||||
std::vector<char> data(line_length);
|
||||
file_stream.read(data.data(), line_length);
|
||||
for (auto i = 0; i < data.size(); i++) {
|
||||
data[i] = XOR(data[i], i);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
std::ifstream file_stream;
|
||||
long line_length;
|
||||
|
||||
[[nodiscard]] char XOR(const char b, const long position) const
|
||||
{
|
||||
if (position > line_length - 4) {
|
||||
return b ^ TPF_XOREven;
|
||||
}
|
||||
|
||||
return position % 2 == 0 ? b ^ TPF_XOREven : b ^ TPF_XOROdd;
|
||||
}
|
||||
|
||||
static constexpr char TPF_XOROdd = 0x3F;
|
||||
static constexpr char TPF_XOREven = static_cast<char>(0xA4);
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ranges>
|
||||
#include <libzippp.h>
|
||||
|
||||
struct TpfEntry {
|
||||
std::string name;
|
||||
std::string entry;
|
||||
uint32_t crc_hash;
|
||||
void* data;
|
||||
unsigned long long size;
|
||||
};
|
||||
|
||||
class gMod_FileLoader {
|
||||
std::string file_name;
|
||||
const std::string TPF_PASSWORD{
|
||||
0x73, 0x2A, 0x63, 0x7D, 0x5F, 0x0A, static_cast<char>(0xA6), static_cast<char>(0xBD),
|
||||
0x7D, 0x65, 0x7E, 0x67, 0x61, 0x2A, 0x7F, 0x7F,
|
||||
0x74, 0x61, 0x67, 0x5B, 0x60, 0x70, 0x45, 0x74,
|
||||
0x5C, 0x22, 0x74, 0x5D, 0x6E, 0x6A, 0x73, 0x41,
|
||||
0x77, 0x6E, 0x46, 0x47, 0x77, 0x49, 0x0C, 0x4B,
|
||||
0x46, 0x6F
|
||||
};
|
||||
std::vector<TpfEntry> entry_cache{};
|
||||
bool loaded = false;
|
||||
|
||||
public:
|
||||
gMod_FileLoader(const std::string& fileName);
|
||||
|
||||
std::vector<TpfEntry> Load();
|
||||
|
||||
private:
|
||||
std::vector<TpfEntry> GetContents();
|
||||
|
||||
std::vector<TpfEntry> GetTpfContents();
|
||||
|
||||
std::vector<TpfEntry> GetFileContents();
|
||||
|
||||
void LoadEntries(libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries);
|
||||
};
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "uMod_IDirect3DTexture9.h"
|
||||
extern unsigned int gl_ErrorState;
|
||||
|
||||
using TextureFileStruct = struct {
|
||||
struct TextureFileStruct {
|
||||
bool ForceReload; // to force a reload of the texture (if it is already modded)
|
||||
char* pData; // store texture file as file in memory
|
||||
unsigned int Size; // size of file
|
||||
@@ -35,9 +35,9 @@ public:
|
||||
|
||||
protected:
|
||||
static constexpr int FieldLength = 1024;
|
||||
long Number;
|
||||
int FieldCounter;
|
||||
TextureFileStruct*** Files;
|
||||
long Number = 0;
|
||||
int FieldCounter = 0;
|
||||
TextureFileStruct*** Files = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ private:
|
||||
template <class T>
|
||||
uMod_TextureHandler<T>::uMod_TextureHandler()
|
||||
{
|
||||
Message("uMod_TextureHandler(): %lu\n", this);
|
||||
Message("uMod_TextureHandler(): %p\n", this);
|
||||
Number = 0;
|
||||
FieldCounter = 0;
|
||||
|
||||
@@ -81,7 +81,7 @@ uMod_TextureHandler<T>::uMod_TextureHandler()
|
||||
template <class T>
|
||||
uMod_TextureHandler<T>::~uMod_TextureHandler()
|
||||
{
|
||||
Message("~uMod_TextureHandler(): %lu\n", this);
|
||||
Message("~uMod_TextureHandler(): %p\n", this);
|
||||
if (Textures != nullptr) {
|
||||
for (int i = 0; i < FieldCounter; i++) {
|
||||
delete [] Textures[i];
|
||||
@@ -93,7 +93,7 @@ uMod_TextureHandler<T>::~uMod_TextureHandler()
|
||||
template <class T>
|
||||
int uMod_TextureHandler<T>::Add(T* pTexture)
|
||||
{
|
||||
Message("uMod_TextureHandler::Add( %lu): %lu\n", pTexture, this);
|
||||
Message("uMod_TextureHandler::Add( %p): %p\n", pTexture, this);
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
@@ -147,7 +147,7 @@ int uMod_TextureHandler<T>::Add(T* pTexture)
|
||||
template <class T>
|
||||
int uMod_TextureHandler<T>::Remove(T* pTexture) //will be called, if a texture is completely released
|
||||
{
|
||||
Message("uMod_TextureHandler::Remove( %lu): %lu\n", pTexture, this);
|
||||
Message("uMod_TextureHandler::Remove(%p): %p\n", pTexture, this);
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
#ifdef LOG_MESSAGE
|
||||
extern FILE* gl_File;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define Message(...) { printf(__VA_ARGS__); }
|
||||
#else
|
||||
#define Message(...)
|
||||
#endif
|
||||
#ifdef HOOK_INJECTION
|
||||
#define OpenMessage(...) {if (fopen_s( &gl_File, "uMod_log.txt", "wt")) gl_File=NULL; else fprintf( gl_File, "HI R40: 0000000\n");}
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// define return values, a value less than zero indicates an error
|
||||
#define RETURN_OK 0
|
||||
#define RETURN_EXISTS -70
|
||||
|
||||
#define RETURN_FATAL_ERROR -1
|
||||
#define RETURN_NO_MEMORY -2
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "uMod_Main.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "uMod_Texture.h"
|
||||
|
||||
class uMod_File {
|
||||
public:
|
||||
uMod_File();
|
||||
uMod_File(std::string file);
|
||||
~uMod_File();
|
||||
|
||||
bool FileSupported();
|
||||
bool PackageFile();
|
||||
bool SingleFile();
|
||||
//int AddSingleFileToNode( uMod_TreeViewNode* node);
|
||||
int GetContentTemplate(const std::string& content);
|
||||
|
||||
/*
|
||||
int GetComment( wxString &tool_tip);
|
||||
int GetContent( AddTextureClass &tex, bool add);
|
||||
*/
|
||||
int GetContent();
|
||||
|
||||
int SetFile(const std::string file)
|
||||
{
|
||||
FileName = file;
|
||||
Loaded = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetFile() { return FileName; }
|
||||
std::vector<UModTexture> Textures;
|
||||
|
||||
private:
|
||||
int ReadFile();
|
||||
|
||||
int UnXOR();
|
||||
/*
|
||||
int GetCommentZip( wxString &tool_tip);
|
||||
int GetCommentTpf( wxString &tool_tip);
|
||||
*/
|
||||
int AddFile();
|
||||
int AddZip();
|
||||
int AddTpf();
|
||||
int AddContent(const char* pw);
|
||||
|
||||
std::string FileName;
|
||||
bool Loaded;
|
||||
bool XORed;
|
||||
char* FileInMemory;
|
||||
unsigned int MemoryLength;
|
||||
unsigned int FileLen;
|
||||
unsigned long long FileHash;
|
||||
};
|
||||
@@ -27,52 +27,6 @@ public:
|
||||
int RemoveTexture(uMod_IDirect3DVolumeTexture9* tex); //called from uMod_IDirect3DVolumeTexture9::Release()
|
||||
int RemoveTexture(uMod_IDirect3DCubeTexture9* tex); //called from uMod_IDirect3DCubeTexture9::Release()
|
||||
|
||||
int SaveAllTextures(bool val); //called from the Server
|
||||
int SaveSingleTexture(bool val); //called from the Server
|
||||
|
||||
int SetSaveDirectory(wchar_t* dir); //called from the Server
|
||||
int SetGameName(wchar_t* dir); //called from the Server
|
||||
|
||||
int SaveTexture(uMod_IDirect3DTexture9* pTexture); //called from uMod_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures)
|
||||
int SaveTexture(uMod_IDirect3DVolumeTexture9* pTexture); //called from uMod_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures)
|
||||
int SaveTexture(uMod_IDirect3DCubeTexture9* pTexture); //called from uMod_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures)
|
||||
|
||||
|
||||
|
||||
int SetKeyBack(int key)
|
||||
{
|
||||
if (key > 0) {
|
||||
KeyBack = key;
|
||||
}
|
||||
return RETURN_OK;
|
||||
} //called from the Server
|
||||
int SetKeySave(int key)
|
||||
{
|
||||
if (key > 0) {
|
||||
KeySave = key;
|
||||
}
|
||||
return RETURN_OK;
|
||||
} //called from the Server
|
||||
int SetKeyNext(int key)
|
||||
{
|
||||
if (key > 0) {
|
||||
KeyNext = key;
|
||||
}
|
||||
return RETURN_OK;
|
||||
} //called from the Server
|
||||
|
||||
int SetFontColour(DWORD r, DWORD g, DWORD b)
|
||||
{
|
||||
FontColour = D3DCOLOR_ARGB(255, r, g, b);
|
||||
return RETURN_OK;
|
||||
} //called from the Server
|
||||
int SetTextureColour(DWORD r, DWORD g, DWORD b)
|
||||
{
|
||||
TextureColour = D3DCOLOR_ARGB(255, r, g, b);
|
||||
return RETURN_OK;
|
||||
} //called from the Server
|
||||
|
||||
|
||||
int AddUpdate(TextureFileStruct* update, int number); //called from the Server, client object must delete update array
|
||||
int MergeUpdate(); //called from uMod_IDirect3DDevice9::BeginScene()
|
||||
|
||||
@@ -84,20 +38,12 @@ public:
|
||||
uMod_TextureHandler<uMod_IDirect3DVolumeTexture9> OriginalVolumeTextures; // stores the pointer to the uMod_IDirect3DVolumeTexture9 objects created by the game
|
||||
uMod_TextureHandler<uMod_IDirect3DCubeTexture9> OriginalCubeTextures; // stores the pointer to the uMod_IDirect3DCubeTexture9 objects created by the game
|
||||
|
||||
bool BoolSaveAllTextures;
|
||||
bool BoolSaveSingleTexture;
|
||||
int KeyBack;
|
||||
int KeySave;
|
||||
int KeyNext;
|
||||
|
||||
D3DCOLOR FontColour;
|
||||
D3DCOLOR TextureColour;
|
||||
|
||||
private:
|
||||
uMod_TextureServer* Server;
|
||||
IDirect3DDevice9* D3D9Device;
|
||||
wchar_t SavePath[MAX_PATH];
|
||||
wchar_t GameName[MAX_PATH];
|
||||
|
||||
TextureFileStruct* Update;
|
||||
int NumberOfUpdate;
|
||||
|
||||
@@ -24,58 +24,26 @@ public:
|
||||
int AddClient(uMod_TextureClient* client, TextureFileStruct** update, int* number); // called from a Client
|
||||
int RemoveClient(uMod_TextureClient* client); // called from a Client
|
||||
|
||||
int MainLoop(); // is executed in a server thread
|
||||
int Initialize(); // is executed in a server thread
|
||||
|
||||
|
||||
// following functions are only public for testing purpose !!
|
||||
// they should be private and only be called from the Mainloop
|
||||
|
||||
int AddFile(char* buffer, unsigned int size, MyTypeHash hash, bool force); // called from Mainloop(), if the content of the texture is sent
|
||||
int AddFile(wchar_t* file_name, MyTypeHash hash, bool force); // called from Mainloop(), if the name and the path to the file is sent
|
||||
int RemoveFile(MyTypeHash hash); // called from Mainloop()
|
||||
|
||||
int SaveAllTextures(bool val); // called from Mainloop()
|
||||
int SaveSingleTexture(bool val); // called from Mainloop()
|
||||
|
||||
int SetSaveDirectory(wchar_t* dir); // called from Mainloop()
|
||||
|
||||
|
||||
int SetKeyBack(int key); // called from Mainloop()
|
||||
int SetKeySave(int key); // called from Mainloop()
|
||||
int SetKeyNext(int key); // called from Mainloop()
|
||||
|
||||
int SetFontColour(DWORD colour); // called from Mainloop()
|
||||
int SetTextureColour(DWORD colour); // called from Mainloop()
|
||||
|
||||
private:
|
||||
bool BoolSaveAllTextures;
|
||||
bool BoolSaveSingleTexture;
|
||||
wchar_t SavePath[MAX_PATH];
|
||||
wchar_t GameName[MAX_PATH];
|
||||
char UModName[MAX_PATH];
|
||||
|
||||
void LoadModsFromFile(char* source);
|
||||
void LoadModsFromFile(const char* source);
|
||||
int PropagateUpdate(uMod_TextureClient* client = nullptr); // called from Mainloop() if texture are loaded or removed
|
||||
int PrepareUpdate(TextureFileStruct** update, int* number); // called from PropagateUpdate() and AddClient()
|
||||
// generate a copy of the current texture to be modded
|
||||
// the file content of the textures are not copied, the clients get the pointer to the file content
|
||||
// but the arrays allocate by this function, must be deleted by the client
|
||||
|
||||
int LockMutex();
|
||||
int UnlockMutex();
|
||||
HANDLE Mutex;
|
||||
|
||||
|
||||
int KeyBack;
|
||||
int KeySave;
|
||||
int KeyNext;
|
||||
|
||||
DWORD FontColour;
|
||||
DWORD TextureColour;
|
||||
|
||||
|
||||
PipeStruct Pipe;
|
||||
|
||||
uMod_TextureClient** Clients;
|
||||
int NumberOfClients;
|
||||
int LenghtOfClients;
|
||||
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef _unzip_H
|
||||
#define _unzip_H
|
||||
//#define TCHAR char
|
||||
// UNZIPPING functions -- for unzipping.
|
||||
// This file is a repackaged form of extracts from the zlib code available
|
||||
// at www.gzip.org/zlib, by Jean-Loup Gailly and Mark Adler. The original
|
||||
// copyright notice may be found in unzip.cpp. The repackaging was done
|
||||
// by Lucian Wischik to simplify and extend its use in Windows/C++. Also
|
||||
// encryption and unicode filenames have been added.
|
||||
|
||||
|
||||
#ifndef _zip_H
|
||||
DECLARE_HANDLE(HZIP);
|
||||
#endif
|
||||
// An HZIP identifies a zip file that has been opened
|
||||
|
||||
typedef DWORD ZRESULT;
|
||||
// return codes from any of the zip functions. Listed later.
|
||||
|
||||
typedef struct {
|
||||
int index; // index of this file within the zip
|
||||
TCHAR name[MAX_PATH]; // filename within the zip
|
||||
DWORD attr; // attributes, as in GetFileAttributes.
|
||||
FILETIME atime, ctime, mtime;// access, create, modify filetimes
|
||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||
} ZIPENTRY;
|
||||
|
||||
|
||||
HZIP OpenZip(const TCHAR* fn, const char* password);
|
||||
HZIP OpenZip(void* z, unsigned int len, const char* password);
|
||||
HZIP OpenZipHandle(HANDLE h, const char* password);
|
||||
// OpenZip - opens a zip file and returns a handle with which you can
|
||||
// subsequently examine its contents. You can open a zip file from:
|
||||
// from a pipe: OpenZipHandle(hpipe_read,0);
|
||||
// from a file (by handle): OpenZipHandle(hfile,0);
|
||||
// from a file (by name): OpenZip("c:\\test.zip","password");
|
||||
// from a memory block: OpenZip(bufstart, buflen,0);
|
||||
// If the file is opened through a pipe, then items may only be
|
||||
// accessed in increasing order, and an item may only be unzipped once,
|
||||
// although GetZipItem can be called immediately before and after unzipping
|
||||
// it. If it's opened in any other way, then full random access is possible.
|
||||
// Note: pipe input is not yet implemented.
|
||||
// Note: zip passwords are ascii, not unicode.
|
||||
// Note: for windows-ce, you cannot close the handle until after CloseZip.
|
||||
// but for real windows, the zip makes its own copy of your handle, so you
|
||||
// can close yours anytime.
|
||||
|
||||
ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY* ze);
|
||||
// GetZipItem - call this to get information about an item in the zip.
|
||||
// If index is -1 and the file wasn't opened through a pipe,
|
||||
// then it returns information about the whole zipfile
|
||||
// (and in particular ze.index returns the number of index items).
|
||||
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
// See below for notes on what happens when you unzip such an item.
|
||||
// Note: if you are opening the zip through a pipe, then random access
|
||||
// is not possible and GetZipItem(-1) fails and you can't discover the number
|
||||
// of items except by calling GetZipItem on each one of them in turn,
|
||||
// starting at 0, until eventually the call fails. Also, in the event that
|
||||
// you are opening through a pipe and the zip was itself created into a pipe,
|
||||
// then then comp_size and sometimes unc_size as well may not be known until
|
||||
// after the item has been unzipped.
|
||||
|
||||
ZRESULT FindZipItem(HZIP hz, const TCHAR* name, bool ic, int* index, ZIPENTRY* ze);
|
||||
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
|
||||
// It returns the index of the item, and returns information about it.
|
||||
// If nothing was found, then index is set to -1 and the function returns
|
||||
// an error code.
|
||||
|
||||
ZRESULT UnzipItem(HZIP hz, int index, const TCHAR* fn);
|
||||
ZRESULT UnzipItem(HZIP hz, int index, void* z, unsigned int len);
|
||||
ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
|
||||
// UnzipItem - given an index to an item, unzips it. You can unzip to:
|
||||
// to a pipe: UnzipItemHandle(hz,i, hpipe_write);
|
||||
// to a file (by handle): UnzipItemHandle(hz,i, hfile);
|
||||
// to a file (by name): UnzipItem(hz,i, ze.name);
|
||||
// to a memory block: UnzipItem(hz,i, buf,buflen);
|
||||
// In the final case, if the buffer isn't large enough to hold it all,
|
||||
// then the return code indicates that more is yet to come. If it was
|
||||
// large enough, and you want to know precisely how big, GetZipItem.
|
||||
// Note: zip files are normally stored with relative pathnames. If you
|
||||
// unzip with ZIP_FILENAME a relative pathname then the item gets created
|
||||
// relative to the current directory - it first ensures that all necessary
|
||||
// subdirectories have been created. Also, the item may itself be a directory.
|
||||
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
|
||||
// If you unzip it to a handle or a memory block, then nothing gets created
|
||||
// and it emits 0 bytes.
|
||||
ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR* dir);
|
||||
// if unzipping to a filename, and it's a relative filename, then it will be relative to here.
|
||||
// (defaults to current-directory).
|
||||
|
||||
|
||||
ZRESULT CloseZip(HZIP hz);
|
||||
// CloseZip - the zip handle must be closed with this function.
|
||||
|
||||
unsigned int FormatZipMessage(ZRESULT code, TCHAR* buf, unsigned int len);
|
||||
// FormatZipMessage - given an error code, formats it as a string.
|
||||
// It returns the length of the error message. If buf/len points
|
||||
// to a real buffer, then it also writes as much as possible into there.
|
||||
|
||||
|
||||
// These are the result codes:
|
||||
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
|
||||
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
|
||||
// The following come from general system stuff (e.g. files not openable)
|
||||
#define ZR_GENMASK 0x0000FF00
|
||||
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
|
||||
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
|
||||
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
|
||||
#define ZR_WRITE 0x00000400 // a general error writing to the file
|
||||
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
|
||||
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
|
||||
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
|
||||
#define ZR_READ 0x00000800 // a general error reading the file
|
||||
#define ZR_PASSWORD 0x00001000 // we didn't get the right password to unzip the file
|
||||
// The following come from mistakes on the part of the caller
|
||||
#define ZR_CALLERMASK 0x00FF0000
|
||||
#define ZR_ARGS 0x00010000 // general mistake with the arguments
|
||||
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
|
||||
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
|
||||
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
|
||||
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
|
||||
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
|
||||
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
|
||||
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
|
||||
// The following come from bugs within the zip library itself
|
||||
#define ZR_BUGMASK 0xFF000000
|
||||
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
|
||||
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
|
||||
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
|
||||
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// e.g.
|
||||
//
|
||||
// SetCurrentDirectory("c:\\docs\\stuff");
|
||||
// HZIP hz = OpenZip("c:\\stuff.zip",0);
|
||||
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
|
||||
// for (int i=0; i<numitems; i++)
|
||||
// { GetZipItem(hz,i,&ze);
|
||||
// UnzipItem(hz,i,ze.name);
|
||||
// }
|
||||
// CloseZip(hz);
|
||||
//
|
||||
//
|
||||
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
|
||||
// HANDLE hglob = LoadResource(hInstance,hrsrc);
|
||||
// void *zipbuf=LockResource(hglob);
|
||||
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
|
||||
// HZIP hz = OpenZip(zipbuf, ziplen, 0);
|
||||
// - unzip to a membuffer -
|
||||
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
|
||||
// char *ibuf = new char[ze.unc_size];
|
||||
// UnzipItem(hz,i, ibuf, ze.unc_size);
|
||||
// delete[] ibuf;
|
||||
// - unzip to a fixed membuff -
|
||||
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
|
||||
// char ibuf[1024]; ZRESULT zr=ZR_MORE; unsigned long totsize=0;
|
||||
// while (zr==ZR_MORE)
|
||||
// { zr = UnzipItem(hz,i, ibuf,1024);
|
||||
// unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
|
||||
// totsize+=bufsize;
|
||||
// }
|
||||
// - unzip to a pipe -
|
||||
// HANDLE hwrite; HANDLE hthread=CreateWavReaderThread(&hwrite);
|
||||
// int i; ZIPENTRY ze; FindZipItem(hz,"sound.wav",true,&i,&ze);
|
||||
// UnzipItemHandle(hz,i, hwrite);
|
||||
// CloseHandle(hwrite);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hwrite); CloseHandle(hthread);
|
||||
// - finished -
|
||||
// CloseZip(hz);
|
||||
// // note: no need to free resources obtained through Find/Load/LockResource
|
||||
//
|
||||
//
|
||||
// SetCurrentDirectory("c:\\docs\\pipedzipstuff");
|
||||
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,0,0);
|
||||
// CreateZipWriterThread(hwrite);
|
||||
// HZIP hz = OpenZipHandle(hread,0);
|
||||
// for (int i=0; ; i++)
|
||||
// { ZIPENTRY ze;
|
||||
// ZRESULT zr=GetZipItem(hz,i,&ze); if (zr!=ZR_OK) break; // no more
|
||||
// UnzipItem(hz,i, ze.name);
|
||||
// }
|
||||
// CloseZip(hz);
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// Now we indulge in a little skullduggery so that the code works whether
|
||||
// the user has included just zip or both zip and unzip.
|
||||
// Idea: if header files for both zip and unzip are present, then presumably
|
||||
// the cpp files for zip and unzip are both present, so we will call
|
||||
// one or the other of them based on a dynamic choice. If the header file
|
||||
// for only one is present, then we will bind to that particular one.
|
||||
ZRESULT CloseZipU(HZIP hz);
|
||||
unsigned int FormatZipMessageU(ZRESULT code, TCHAR* buf, unsigned int len);
|
||||
bool IsZipHandleU(HZIP hz);
|
||||
#ifdef _zip_H
|
||||
#undef CloseZip
|
||||
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
|
||||
#else
|
||||
#define CloseZip CloseZipU
|
||||
#define FormatZipMessage FormatZipMessageU
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // _unzip_H
|
||||
-205
@@ -1,205 +0,0 @@
|
||||
#include <Windows.h>
|
||||
#include <cstdlib>
|
||||
#ifndef _zip_H
|
||||
#define _zip_H
|
||||
|
||||
|
||||
// ZIP functions -- for creating zip files
|
||||
// This file is a repackaged form of the Info-Zip source code available
|
||||
// at www.info-zip.org. The original copyright notice may be found in
|
||||
// zip.cpp. The repackaging was done by Lucian Wischik to simplify and
|
||||
// extend its use in Windows/C++. Also to add encryption and unicode.
|
||||
|
||||
|
||||
#ifndef _unzip_H
|
||||
DECLARE_HANDLE(HZIP);
|
||||
#endif
|
||||
// An HZIP identifies a zip file that is being created
|
||||
|
||||
typedef DWORD ZRESULT;
|
||||
// return codes from any of the zip functions. Listed later.
|
||||
|
||||
|
||||
|
||||
HZIP CreateZip(const TCHAR* fn, const char* password);
|
||||
HZIP CreateZip(void* buf, unsigned int len, const char* password);
|
||||
HZIP CreateZipHandle(HANDLE h, const char* password);
|
||||
// CreateZip - call this to start the creation of a zip file.
|
||||
// As the zip is being created, it will be stored somewhere:
|
||||
// to a pipe: CreateZipHandle(hpipe_write);
|
||||
// in a file (by handle): CreateZipHandle(hfile);
|
||||
// in a file (by name): CreateZip("c:\\test.zip");
|
||||
// in memory: CreateZip(buf, len);
|
||||
// or in pagefile memory: CreateZip(0, len);
|
||||
// The final case stores it in memory backed by the system paging file,
|
||||
// where the zip may not exceed len bytes. This is a bit friendlier than
|
||||
// allocating memory with new[]: it won't lead to fragmentation, and the
|
||||
// memory won't be touched unless needed. That means you can give very
|
||||
// large estimates of the maximum-size without too much worry.
|
||||
// As for the password, it lets you encrypt every file in the archive.
|
||||
// (This api doesn't support per-file encryption.)
|
||||
// Note: because pipes don't allow random access, the structure of a zipfile
|
||||
// created into a pipe is slightly different from that created into a file
|
||||
// or memory. In particular, the compressed-size of the item cannot be
|
||||
// stored in the zipfile until after the item itself. (Also, for an item added
|
||||
// itself via a pipe, the uncompressed-size might not either be known until
|
||||
// after.) This is not normally a problem. But if you try to unzip via a pipe
|
||||
// as well, then the unzipper will not know these things about the item until
|
||||
// after it has been unzipped. Therefore: for unzippers which don't just write
|
||||
// each item to disk or to a pipe, but instead pre-allocate memory space into
|
||||
// which to unzip them, then either you have to create the zip not to a pipe,
|
||||
// or you have to add items not from a pipe, or at least when adding items
|
||||
// from a pipe you have to specify the length.
|
||||
// Note: for windows-ce, you cannot close the handle until after CloseZip.
|
||||
// but for real windows, the zip makes its own copy of your handle, so you
|
||||
// can close yours anytime.
|
||||
|
||||
|
||||
ZRESULT ZipAdd(HZIP hz, const TCHAR* dstzn, const TCHAR* fn);
|
||||
ZRESULT ZipAdd(HZIP hz, const TCHAR* dstzn, void* src, unsigned int len);
|
||||
ZRESULT ZipAddHandle(HZIP hz, const TCHAR* dstzn, HANDLE h);
|
||||
ZRESULT ZipAddHandle(HZIP hz, const TCHAR* dstzn, HANDLE h, unsigned int len);
|
||||
ZRESULT ZipAddFolder(HZIP hz, const TCHAR* dstzn);
|
||||
// ZipAdd - call this for each file to be added to the zip.
|
||||
// dstzn is the name that the file will be stored as in the zip file.
|
||||
// The file to be added to the zip can come
|
||||
// from a pipe: ZipAddHandle(hz,"file.dat", hpipe_read);
|
||||
// from a file: ZipAddHandle(hz,"file.dat", hfile);
|
||||
// from a filen: ZipAdd(hz,"file.dat", "c:\\docs\\origfile.dat");
|
||||
// from memory: ZipAdd(hz,"subdir\\file.dat", buf,len);
|
||||
// (folder): ZipAddFolder(hz,"subdir");
|
||||
// Note: if adding an item from a pipe, and if also creating the zip file itself
|
||||
// to a pipe, then you might wish to pass a non-zero length to the ZipAddHandle
|
||||
// function. This will let the zipfile store the item's size ahead of the
|
||||
// compressed item itself, which in turn makes it easier when unzipping the
|
||||
// zipfile from a pipe.
|
||||
|
||||
ZRESULT ZipGetMemory(HZIP hz, void** buf, unsigned long* len);
|
||||
// ZipGetMemory - If the zip was created in memory, via ZipCreate(0,len),
|
||||
// then this function will return information about that memory block.
|
||||
// buf will receive a pointer to its start, and len its length.
|
||||
// Note: you can't add any more after calling this.
|
||||
|
||||
ZRESULT CloseZip(HZIP hz);
|
||||
// CloseZip - the zip handle must be closed with this function.
|
||||
|
||||
unsigned int FormatZipMessage(ZRESULT code, TCHAR* buf, unsigned int len);
|
||||
// FormatZipMessage - given an error code, formats it as a string.
|
||||
// It returns the length of the error message. If buf/len points
|
||||
// to a real buffer, then it also writes as much as possible into there.
|
||||
|
||||
|
||||
|
||||
// These are the result codes:
|
||||
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
|
||||
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
|
||||
// The following come from general system stuff (e.g. files not openable)
|
||||
#define ZR_GENMASK 0x0000FF00
|
||||
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
|
||||
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
|
||||
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
|
||||
#define ZR_WRITE 0x00000400 // a general error writing to the file
|
||||
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
|
||||
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
|
||||
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
|
||||
#define ZR_READ 0x00000800 // a general error reading the file
|
||||
// The following come from mistakes on the part of the caller
|
||||
#define ZR_CALLERMASK 0x00FF0000
|
||||
#define ZR_ARGS 0x00010000 // general mistake with the arguments
|
||||
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
|
||||
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
|
||||
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
|
||||
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
|
||||
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
|
||||
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
|
||||
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
|
||||
// The following come from bugs within the zip library itself
|
||||
#define ZR_BUGMASK 0xFF000000
|
||||
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
|
||||
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
|
||||
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
|
||||
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// e.g.
|
||||
//
|
||||
// (1) Traditional use, creating a zipfile from existing files
|
||||
// HZIP hz = CreateZip("c:\\simple1.zip",0);
|
||||
// ZipAdd(hz,"znsimple.bmp", "c:\\simple.bmp");
|
||||
// ZipAdd(hz,"znsimple.txt", "c:\\simple.txt");
|
||||
// CloseZip(hz);
|
||||
//
|
||||
// (2) Memory use, creating an auto-allocated mem-based zip file from various sources
|
||||
// HZIP hz = CreateZip(0,100000, 0);
|
||||
// // adding a conventional file...
|
||||
// ZipAdd(hz,"src1.txt", "c:\\src1.txt");
|
||||
// // adding something from memory...
|
||||
// char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F);
|
||||
// ZipAdd(hz,"file.dat", buf,1000);
|
||||
// // adding something from a pipe...
|
||||
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,NULL,0);
|
||||
// HANDLE hthread = CreateThread(0,0,ThreadFunc,(void*)hwrite,0,0);
|
||||
// ZipAdd(hz,"unz3.dat", hread,1000); // the '1000' is optional.
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hthread); CloseHandle(hread);
|
||||
// ... meanwhile DWORD WINAPI ThreadFunc(void *dat)
|
||||
// { HANDLE hwrite = (HANDLE)dat;
|
||||
// char buf[1000]={17};
|
||||
// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL);
|
||||
// CloseHandle(hwrite);
|
||||
// return 0;
|
||||
// }
|
||||
// // and now that the zip is created, let's do something with it:
|
||||
// void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen);
|
||||
// HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
|
||||
// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL);
|
||||
// CloseHandle(hfz);
|
||||
// CloseZip(hz);
|
||||
//
|
||||
// (3) Handle use, for file handles and pipes
|
||||
// HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite,0,0);
|
||||
// HANDLE hthread = CreateThread(0,0,ZipReceiverThread,(void*)hzread,0,0);
|
||||
// HZIP hz = CreateZipHandle(hzwrite,0);
|
||||
// // ... add to it
|
||||
// CloseZip(hz);
|
||||
// CloseHandle(hzwrite);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hthread);
|
||||
// ... meanwhile DWORD WINAPI ZipReceiverThread(void *dat)
|
||||
// { HANDLE hread = (HANDLE)dat;
|
||||
// char buf[1000];
|
||||
// while (true)
|
||||
// { DWORD red; ReadFile(hread,buf,1000,&red,NULL);
|
||||
// // ... and do something with this zip data we're receiving
|
||||
// if (red==0) break;
|
||||
// }
|
||||
// CloseHandle(hread);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// Now we indulge in a little skullduggery so that the code works whether
|
||||
// the user has included just zip or both zip and unzip.
|
||||
// Idea: if header files for both zip and unzip are present, then presumably
|
||||
// the cpp files for zip and unzip are both present, so we will call
|
||||
// one or the other of them based on a dynamic choice. If the header file
|
||||
// for only one is present, then we will bind to that particular one.
|
||||
ZRESULT CloseZipZ(HZIP hz);
|
||||
unsigned int FormatZipMessageZ(ZRESULT code, char* buf, unsigned int len);
|
||||
bool IsZipHandleZ(HZIP hz);
|
||||
#ifdef _unzip_H
|
||||
#undef CloseZip
|
||||
#define CloseZip(hz) (IsZipHandleZ(hz)?CloseZipZ(hz):CloseZipU(hz))
|
||||
#else
|
||||
#define CloseZip CloseZipZ
|
||||
#define FormatZipMessage FormatZipMessageZ
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,192 @@
|
||||
#include <uMod_Main.h>
|
||||
#include <filesystem>
|
||||
#include "gMod_FileLoader.h"
|
||||
#include "XorStreamReader.h"
|
||||
|
||||
gMod_FileLoader::gMod_FileLoader(const std::string& fileName)
|
||||
{
|
||||
file_name = std::filesystem::absolute(fileName).string();
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> gMod_FileLoader::Load()
|
||||
{
|
||||
if (!loaded) {
|
||||
entry_cache = GetContents();
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
return entry_cache;
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> gMod_FileLoader::GetContents()
|
||||
{
|
||||
return file_name.ends_with(".tpf") ? GetTpfContents() : GetFileContents();
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> gMod_FileLoader::GetTpfContents()
|
||||
{
|
||||
std::vector<TpfEntry> entries;
|
||||
try {
|
||||
auto xorreader = XorStreamReader(file_name);
|
||||
const auto buffer = xorreader.ReadToEnd();
|
||||
const auto zip_archive = libzippp::ZipArchive::fromBuffer(buffer.data(), buffer.size(), false, TPF_PASSWORD);
|
||||
zip_archive->setErrorHandlerCallback(
|
||||
[](const std::string& message, const std::string& strerror, int zip_error_code, int system_error_code) -> void {
|
||||
Message("GetTpfContents: %s %s %d %d\n", message.c_str(), strerror.c_str(), zip_error_code, system_error_code);
|
||||
});
|
||||
zip_archive->open();
|
||||
LoadEntries(*zip_archive, entries);
|
||||
zip_archive->close();
|
||||
libzippp::ZipArchive::free(zip_archive);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
throw std::runtime_error("Failed to open zip file: " + file_name + "\n" + e.what());
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> gMod_FileLoader::GetFileContents()
|
||||
{
|
||||
std::vector<TpfEntry> entries;
|
||||
|
||||
try {
|
||||
libzippp::ZipArchive zip_archive(file_name);
|
||||
zip_archive.open();
|
||||
LoadEntries(zip_archive, entries);
|
||||
zip_archive.close();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
throw std::runtime_error("Failed to open zip file: " + file_name);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries)
|
||||
{
|
||||
for (const auto& entry : archive.getEntries()) {
|
||||
if (entry.isFile()) {
|
||||
//TODO: #6 - Implement regex search
|
||||
const auto dataPtr = entry.readAsBinary();
|
||||
const auto size = entry.getSize();
|
||||
auto name = entry.getName();
|
||||
|
||||
// Remove the part before the last underscore (if any)
|
||||
size_t firstIndex = name.find_last_of('_');
|
||||
while (firstIndex != std::string::npos) {
|
||||
if (firstIndex >= entry.getName().length() - 1) {
|
||||
name = entry.getName();
|
||||
}
|
||||
else {
|
||||
name = entry.getName().substr(firstIndex + 1);
|
||||
}
|
||||
|
||||
firstIndex = name.find_last_of('_');
|
||||
}
|
||||
|
||||
// Remove the file extension (if any)
|
||||
size_t lastIndex = name.find_last_of('.');
|
||||
if (lastIndex != std::string::npos) {
|
||||
name = name.substr(0, lastIndex);
|
||||
}
|
||||
|
||||
uint32_t crcHash;
|
||||
try {
|
||||
crcHash = std::stoul(name, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
Message("Failed to parse %s as a hash", name.c_str());
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
Message("Out of range while parsing %s as a hash", name.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.push_back({name, entry.getName(), crcHash, dataPtr, size});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseTexmodArchive(std::vector<std::string>& lines, libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries)
|
||||
{
|
||||
for (const auto& line : lines) {
|
||||
std::istringstream iss(line);
|
||||
std::string part;
|
||||
std::vector<std::string> splits;
|
||||
|
||||
// Split the line by '|'
|
||||
while (std::getline(iss, part, '|')) {
|
||||
splits.push_back(part);
|
||||
}
|
||||
|
||||
if (splits.size() != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string addrstr = splits[0];
|
||||
std::string path = splits[1];
|
||||
|
||||
// Remove unwanted characters from the beginning of the path
|
||||
while (!path.empty() && (path[0] == '.' && (path[1] == '/' || path[1] == '\\')) || path[0] == '/' || path[0] == '\\') {
|
||||
path.erase(0, 1);
|
||||
}
|
||||
|
||||
// Remove trailing newline and carriage return characters
|
||||
const size_t endpos = path.find_last_not_of("\r\n");
|
||||
if (endpos != std::string::npos) {
|
||||
path.erase(endpos + 1);
|
||||
}
|
||||
else if (!path.empty()) {
|
||||
path.clear();
|
||||
}
|
||||
|
||||
const auto entry = archive.getEntry(path);
|
||||
if (entry.isNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry.isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto data_ptr= entry.readAsBinary();
|
||||
const auto size = entry.getSize();
|
||||
uint32_t crcHash;
|
||||
try {
|
||||
crcHash = std::stoul(addrstr, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
Message("Failed to parse %s as a hash", addrstr.c_str());
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
Message("Out of range while parsing %s as a hash", addrstr.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.push_back({addrstr, entry.getName(), crcHash, data_ptr, size});
|
||||
}
|
||||
}
|
||||
|
||||
void gMod_FileLoader::LoadEntries(libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries)
|
||||
{
|
||||
// Iterate over the files in the zip archive
|
||||
const auto def_file = archive.getEntry("texmod.def");
|
||||
if (def_file.isNull() || !def_file.isFile()) {
|
||||
ParseSimpleArchive(archive, entries);
|
||||
}
|
||||
else {
|
||||
const auto def = def_file.readAsText();
|
||||
std::istringstream iss(def);
|
||||
std::vector<std::string> lines;
|
||||
std::string line;
|
||||
|
||||
while (std::getline(iss, line)) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
ParseTexmodArchive(lines, archive, entries);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,13 @@
|
||||
#include "uMod_Main.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uMod_FileHandler::uMod_FileHandler()
|
||||
{
|
||||
Message("uMod_FileHandler(): %lu\n", this);
|
||||
Number = 0;
|
||||
FieldCounter = 0;
|
||||
Files = nullptr;
|
||||
Message("uMod_FileHandler(): %p\n", this);
|
||||
}
|
||||
|
||||
uMod_FileHandler::~uMod_FileHandler()
|
||||
{
|
||||
Message("~uMod_FileHandler(): %lu\n", this);
|
||||
Message("~uMod_FileHandler(): %p\n", this);
|
||||
if (Files != nullptr) {
|
||||
for (int i = 0; i < FieldCounter; i++) {
|
||||
delete [] Files[i];
|
||||
@@ -25,7 +18,7 @@ uMod_FileHandler::~uMod_FileHandler()
|
||||
|
||||
int uMod_FileHandler::Add(TextureFileStruct* file)
|
||||
{
|
||||
Message("uMod_FileHandler::Add(%lu): %lu\n", file, this);
|
||||
Message("uMod_FileHandler::Add(%p): %p\n", file, this);
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
@@ -80,7 +73,7 @@ int uMod_FileHandler::Add(TextureFileStruct* file)
|
||||
|
||||
int uMod_FileHandler::Remove(TextureFileStruct* file)
|
||||
{
|
||||
Message("uMod_FileHandler::Remove(%lu): %lu\n", file, this);
|
||||
Message("uMod_FileHandler::Remove(%p): %p\n", file, this);
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
|
||||
+23
-51
@@ -1,22 +1,13 @@
|
||||
#include "uMod_DX9_dll.h"
|
||||
#include "uMod_Main.h"
|
||||
#include <Windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <TlHelp32.h>
|
||||
#pragma comment(lib, "Psapi.lib")
|
||||
//#include "detours.h"
|
||||
//#include "detourxs/detourxs/detourxs.h"
|
||||
|
||||
/*
|
||||
#include "detourxs/detourxs/ADE32.cpp"
|
||||
#include "detourxs/detourxs/detourxs.cpp"
|
||||
*/
|
||||
/*
|
||||
* global variable which are not linked external
|
||||
*/
|
||||
#include <array>
|
||||
#include <Windows.h>
|
||||
#include "uMod_Main.h"
|
||||
#include <Psapi.h>
|
||||
|
||||
HINSTANCE gl_hOriginalDll = nullptr;
|
||||
HINSTANCE gl_hThisInstance = nullptr;
|
||||
uMod_TextureServer* gl_TextureServer = nullptr;
|
||||
std::unique_ptr<uMod_TextureServer> gl_TextureServer = nullptr;
|
||||
HANDLE gl_ServerThread = nullptr;
|
||||
|
||||
using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT);
|
||||
@@ -51,9 +42,9 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
#ifdef BUILD_TYPE_DEBUG
|
||||
#ifdef _DEBUG
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("uMod Console");
|
||||
SetConsoleTitleA("gMod Console");
|
||||
freopen_s(&stdout_proxy, "CONOUT$", "w", stdout);
|
||||
freopen_s(&stderr_proxy, "CONOUT$", "w", stderr);
|
||||
#endif
|
||||
@@ -75,7 +66,7 @@ DWORD WINAPI ServerThread(LPVOID lpParam)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(lpParam);
|
||||
if (gl_TextureServer != nullptr) {
|
||||
gl_TextureServer->MainLoop(); //This is and endless mainloop, it sleep till something is written into the pipe.
|
||||
gl_TextureServer->Initialize(); //This is and endless mainloop, it sleep till something is written into the pipe.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -89,32 +80,27 @@ void InitInstance(HINSTANCE hModule)
|
||||
if (HookThisProgram(game)) //ask if we need to hook this program
|
||||
{
|
||||
OpenMessage();
|
||||
Message("InitInstance: %lu\n", hModule);
|
||||
char uMod[MAX_PATH];
|
||||
for (auto i = 0; i < MAX_PATH; i++) {
|
||||
uMod[i] = 0;
|
||||
}
|
||||
Message("InitInstance: %p\n", hModule);
|
||||
std::array<char, MAX_PATH> uMod{};
|
||||
|
||||
GetModuleFileNameA(hModule, uMod, MAX_PATH);
|
||||
Message("InitInstance: %s\n", uMod);
|
||||
gl_TextureServer = new uMod_TextureServer(game, uMod); //create the server which listen on the pipe and prepare the update for the texture clients
|
||||
GetModuleFileNameA(hModule, uMod.data(), MAX_PATH);
|
||||
Message("InitInstance: %s\n", uMod.data());
|
||||
gl_TextureServer = std::make_unique<uMod_TextureServer>(game, uMod.data()); //create the server which listen on the pipe and prepare the update for the texture clients
|
||||
LoadOriginalDll();
|
||||
if (gl_hOriginalDll) {
|
||||
Direct3DCreate9_fn = (Direct3DCreate9_type)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9");
|
||||
Direct3DCreate9_fn = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress(gl_hOriginalDll, "Direct3DCreate9"));
|
||||
if (Direct3DCreate9_fn != nullptr) {
|
||||
Message("Detour: Direct3DCreate9\n");
|
||||
Direct3DCreate9_fn = static_cast<Direct3DCreate9_type>(DetourFunc((BYTE*)Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9, 5));
|
||||
}
|
||||
|
||||
Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9Ex");
|
||||
Direct3DCreate9Ex_fn = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress(gl_hOriginalDll, "Direct3DCreate9Ex"));
|
||||
if (Direct3DCreate9Ex_fn != nullptr) {
|
||||
Message("Detour: Direct3DCreate9Ex\n");
|
||||
Direct3DCreate9Ex_fn = static_cast<Direct3DCreate9Ex_type>(DetourFunc((BYTE*)Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex, 7));
|
||||
}
|
||||
}
|
||||
gl_ServerThread = CreateThread(nullptr, 0, ServerThread, nullptr, 0, nullptr); //creating a thread for the mainloop
|
||||
if (gl_ServerThread == nullptr) { Message("InitInstance: Serverthread not started\n"); }
|
||||
|
||||
gl_TextureServer->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,22 +181,13 @@ void LoadOriginalDll()
|
||||
|
||||
void ExitInstance()
|
||||
{
|
||||
if (gl_ServerThread != nullptr) {
|
||||
CloseHandle(gl_ServerThread); // kill the server thread
|
||||
gl_ServerThread = nullptr;
|
||||
}
|
||||
if (gl_TextureServer != nullptr) {
|
||||
delete gl_TextureServer; //delete the texture server
|
||||
gl_TextureServer = nullptr;
|
||||
}
|
||||
|
||||
// Release the system's d3d9.dll
|
||||
if (gl_hOriginalDll != nullptr) {
|
||||
FreeLibrary(gl_hOriginalDll);
|
||||
gl_hOriginalDll = nullptr;
|
||||
}
|
||||
|
||||
#ifdef BUILD_TYPE_DEBUG
|
||||
#ifdef _DEBUG
|
||||
if (stdout_proxy)
|
||||
fclose(stdout_proxy);
|
||||
if (stderr_proxy)
|
||||
@@ -226,7 +203,7 @@ void ExitInstance()
|
||||
|
||||
IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9: original %lu, uMod %lu\n", Direct3DCreate9_fn, uMod_Direct3DCreate9);
|
||||
Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, uMod_Direct3DCreate9);
|
||||
|
||||
// in the Internet are many tutorials for detouring functions and all of them will work without the following 5 marked lines
|
||||
// but somehow, for me it only works, if I retour the function and calling afterward the original function
|
||||
@@ -256,7 +233,7 @@ IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion)
|
||||
}
|
||||
uMod_IDirect3D9* pIDirect3D9;
|
||||
if (pIDirect3D9_orig) {
|
||||
pIDirect3D9 = new uMod_IDirect3D9(pIDirect3D9_orig, gl_TextureServer); //creating our uMod_IDirect3D9 object
|
||||
pIDirect3D9 = new uMod_IDirect3D9(pIDirect3D9_orig, gl_TextureServer.get()); //creating our uMod_IDirect3D9 object
|
||||
}
|
||||
|
||||
// we detour again
|
||||
@@ -272,7 +249,7 @@ IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion)
|
||||
|
||||
HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9Ex: original %lu, uMod %lu\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex);
|
||||
Message("uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex);
|
||||
|
||||
// in the Internet are many tutorials for detouring functions and all of them will work without the following 5 marked lines
|
||||
// but somehow, for me it only works, if I retour the function and calling afterward the original function
|
||||
@@ -306,7 +283,7 @@ HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
|
||||
uMod_IDirect3D9Ex* pIDirect3D9Ex;
|
||||
if (pIDirect3D9Ex_orig) {
|
||||
pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig, gl_TextureServer); //creating our uMod_IDirect3D9 object
|
||||
pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig, gl_TextureServer.get()); //creating our uMod_IDirect3D9 object
|
||||
}
|
||||
|
||||
// we detour again
|
||||
@@ -327,12 +304,7 @@ bool HookThisProgram(char* ret)
|
||||
GetModuleFileName(GetModuleHandle(nullptr), Game, MAX_PATH); //ask for name and path of this executable
|
||||
|
||||
// we inject directly
|
||||
int i = 0;
|
||||
while (Game[i]) {
|
||||
ret[i] = Game[i];
|
||||
i++;
|
||||
}
|
||||
ret[i] = 0;
|
||||
strcpy(ret, Game);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,485 +0,0 @@
|
||||
#include "uMod_Main.h"
|
||||
#include "unzip.h"
|
||||
#include "uMod_File.h"
|
||||
#include "utils.h"
|
||||
#include "uMod_Texture.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#ifdef __CDT_PARSER__
|
||||
#define FindZipItem(...) 0
|
||||
#define UnzipItem(...) 0
|
||||
#define CloseZip(...) 0
|
||||
#define GetZipItem(...) 0
|
||||
#endif
|
||||
|
||||
|
||||
uMod_File::uMod_File()
|
||||
{
|
||||
Loaded = false;
|
||||
XORed = false;
|
||||
FileInMemory = static_cast<char*>(nullptr);
|
||||
MemoryLength = 0u;
|
||||
FileLen = 0u;
|
||||
}
|
||||
|
||||
uMod_File::uMod_File(const std::string file)
|
||||
{
|
||||
Loaded = false;
|
||||
XORed = false;
|
||||
FileInMemory = static_cast<char*>(nullptr);
|
||||
MemoryLength = 0u;
|
||||
FileLen = 0u;
|
||||
SetFile(file);
|
||||
}
|
||||
|
||||
|
||||
uMod_File::~uMod_File()
|
||||
{
|
||||
if (FileInMemory != static_cast<char*>(nullptr)) {
|
||||
delete[] FileInMemory;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool uMod_File::FileSupported()
|
||||
{
|
||||
const std::string file_type = GetFileExtension(FileName);
|
||||
if (file_type == "zip") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "tpf") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "bmp") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "jpg") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "tga") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "png") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "dds") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "ppm") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool uMod_File::PackageFile()
|
||||
{
|
||||
const std::string file_type = GetFileExtension(FileName);
|
||||
if (file_type == "zip") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "tpf") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool uMod_File::SingleFile()
|
||||
{
|
||||
const std::string file_type = GetFileExtension(FileName);
|
||||
if (file_type == "bmp") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "jpg") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "tga") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "png") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "dds") {
|
||||
return true;
|
||||
}
|
||||
if (file_type == "ppm") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int uMod_File::GetContent()
|
||||
{
|
||||
const std::string file_type = GetFileExtension(FileName);
|
||||
if (file_type == "zip") {
|
||||
AddZip();
|
||||
}
|
||||
else if (file_type == "tpf") {
|
||||
AddTpf();
|
||||
}
|
||||
else if (SingleFile()) {
|
||||
AddFile();
|
||||
}
|
||||
else {
|
||||
printf(FileName.c_str());
|
||||
printf(" Not supported\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uMod_File::ReadFile()
|
||||
{
|
||||
if (Loaded) {
|
||||
return 0;
|
||||
}
|
||||
XORed = false;
|
||||
|
||||
const auto name = FileName;
|
||||
std::ifstream inputFile(name, std::ios::binary);
|
||||
if (!inputFile ||
|
||||
!inputFile.is_open()) {
|
||||
printf(name.c_str());
|
||||
printf(" Could not open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile), {});
|
||||
if (FileInMemory) {
|
||||
delete[] FileInMemory;
|
||||
}
|
||||
|
||||
FileInMemory = new char[buffer.size()];
|
||||
for (auto i = 0; i < buffer.size(); i++) {
|
||||
FileInMemory[i] = buffer[i];
|
||||
}
|
||||
|
||||
FileLen = buffer.size();
|
||||
inputFile.close();
|
||||
FileInMemory[FileLen] = 0;
|
||||
printf(name.c_str());
|
||||
printf("%d\n", FileLen);
|
||||
|
||||
Loaded = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uMod_File::UnXOR()
|
||||
{
|
||||
if (XORed) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
*
|
||||
* BIG THANKS TO Tonttu
|
||||
* (TPFcreate 1.5)
|
||||
*
|
||||
*/
|
||||
const auto buff = (unsigned int*)FileInMemory;
|
||||
const unsigned int TPF_XOR = 0x3FA43FA4u;
|
||||
const unsigned int size = FileLen / 4u;
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
buff[i] ^= TPF_XOR;
|
||||
}
|
||||
for (unsigned int i = size * 4u; i < size * 4u + FileLen % 4u; i++) {
|
||||
((unsigned char*)FileInMemory)[i] ^= static_cast<unsigned char>(TPF_XOR);
|
||||
}
|
||||
|
||||
|
||||
unsigned int pos = FileLen - 1;
|
||||
while (pos > 0u && FileInMemory[pos]) {
|
||||
pos--;
|
||||
}
|
||||
if (pos > 0u && pos < FileLen - 1) {
|
||||
FileLen = pos + 1;
|
||||
}
|
||||
XORed = true;
|
||||
|
||||
/*
|
||||
* original code by Tonttu
|
||||
* The last bytes are not revealed correctly
|
||||
unsigned int j=0;
|
||||
while ( j <= result - 4 )
|
||||
{
|
||||
*( unsigned int* )( &buffer[j] ) ^= TPF_XOR;
|
||||
j += 4;
|
||||
}
|
||||
|
||||
while ( j < result )
|
||||
{
|
||||
buffer[j] ^= (unsigned char )( TPF_XOR >> 24 );
|
||||
TPF_XOR <<= 4;
|
||||
j++;
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uMod_File::AddFile()
|
||||
{
|
||||
DWORD64 temp_hash;
|
||||
|
||||
std::string name = AfterLast(FileName, '_');
|
||||
name = BeforeLast(name, '.');
|
||||
|
||||
try {
|
||||
// Convert hexadecimal string to unsigned long long
|
||||
temp_hash = std::stoull(name, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
printf("Encountered error");
|
||||
printf(e.what());
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
printf("Encountered error");
|
||||
printf(e.what());
|
||||
}
|
||||
|
||||
if (const int ret = ReadFile()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
FileHash = temp_hash;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uMod_File::AddZip()
|
||||
{
|
||||
if (const int ret = ReadFile()) {
|
||||
return ret;
|
||||
}
|
||||
return AddContent(nullptr);
|
||||
}
|
||||
|
||||
int uMod_File::AddTpf()
|
||||
{
|
||||
if (const int ret = ReadFile()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
UnXOR();
|
||||
|
||||
constexpr char pw[] = {
|
||||
0x73, 0x2A, 0x63, 0x7D, 0x5F, 0x0A, static_cast<char>(0xA6), static_cast<char>(0xBD),
|
||||
0x7D, 0x65, 0x7E, 0x67, 0x61, 0x2A, 0x7F, 0x7F,
|
||||
0x74, 0x61, 0x67, 0x5B, 0x60, 0x70, 0x45, 0x74,
|
||||
0x5C, 0x22, 0x74, 0x5D, 0x6E, 0x6A, 0x73, 0x41,
|
||||
0x77, 0x6E, 0x46, 0x47, 0x77, 0x49, 0x0C, 0x4B,
|
||||
0x46, 0x6F, '\0'
|
||||
};
|
||||
|
||||
return AddContent(pw);
|
||||
}
|
||||
|
||||
|
||||
int uMod_File::AddContent(const char* pw)
|
||||
{
|
||||
// Thats is really nasty code, but atm I am happy that it works. I should try an other unzip api,
|
||||
// This one seems to behave very strange.
|
||||
// I know, that also a bug in my code could be reason for the crashes, but UnzipItem( ... ) unzipes wrong files
|
||||
// and GetZipItem( ... ) returns garbage as file names, and the next call of GetZipItem( ... ) blows up the program.
|
||||
//
|
||||
// I have commented line 3519 in unzip.cpp.
|
||||
// It was stated this is a bug, but it did not solve my problems.
|
||||
//
|
||||
// closing and reopen the zip handle did the trick.
|
||||
//
|
||||
|
||||
const auto& name = FileName;
|
||||
HZIP ZIP_Handle = OpenZip(FileInMemory, FileLen, pw);
|
||||
if (ZIP_Handle == static_cast<HZIP>(nullptr)) {
|
||||
printf(name.c_str());
|
||||
printf(" Failed to unzip file\n");
|
||||
return -1;
|
||||
}
|
||||
ZIPENTRY ze;
|
||||
int index;
|
||||
FindZipItem(ZIP_Handle, "texmod.def", false, &index, &ze);
|
||||
if (index >= 0) //if texmod.def is present in the zip file
|
||||
{
|
||||
printf(name.c_str());
|
||||
printf(" Unzipping based on texmod.def of size %d\n", ze.unc_size);
|
||||
char* def;
|
||||
int len = ze.unc_size;
|
||||
try { def = new char[len + 1]; }
|
||||
catch (...) {
|
||||
printf(name.c_str());
|
||||
printf(" Memory error\n");
|
||||
return -1;
|
||||
}
|
||||
ZRESULT zr = UnzipItem(ZIP_Handle, index, def, len);
|
||||
|
||||
if (zr != ZR_OK && zr != ZR_MORE) {
|
||||
delete[] def;
|
||||
return -1;
|
||||
}
|
||||
def[len] = 0;
|
||||
|
||||
std::stringstream tokenStream(def);
|
||||
std::string token;
|
||||
DWORD64 temp_hash;
|
||||
std::string entry;
|
||||
std::string file;
|
||||
|
||||
while (std::getline(tokenStream, token)) {
|
||||
entry = token;
|
||||
printf(name.c_str());
|
||||
printf(" Parsing token %s\n", token.c_str());
|
||||
file = BeforeFirst(token, '|');
|
||||
try {
|
||||
temp_hash = std::stoull(file, nullptr, 16);
|
||||
// Successful conversion; can continue processing...
|
||||
}
|
||||
catch (const std::invalid_argument&) {
|
||||
// Handle invalid argument
|
||||
printf(name.c_str());
|
||||
printf(" Invalid hash\n");
|
||||
continue; // Skip the rest of the current loop iteration
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
// Handle out of range
|
||||
printf(name.c_str());
|
||||
printf(" Invalid hash\n");
|
||||
continue; // Skip the rest of the current loop iteration
|
||||
}
|
||||
|
||||
file = AfterFirst(entry, '|');
|
||||
ReplaceAll(file, "\r", "");
|
||||
|
||||
while ((!file.empty() && file[0] == '.' && (file.size() > 1 && (file[1] == '/' || file[1] == '\\')))
|
||||
|| (!file.empty() && (file[0] == '/' || file[0] == '\\'))) {
|
||||
file.erase(0, 1);
|
||||
}
|
||||
|
||||
FindZipItem(ZIP_Handle, file.c_str(), false, &index, &ze); // look for texture
|
||||
if (index >= 0) {
|
||||
std::vector<char> data;
|
||||
UModTexture texture;
|
||||
data.resize(ze.unc_size);
|
||||
|
||||
ZRESULT rz = UnzipItem(ZIP_Handle, index, data.data(), ze.unc_size);
|
||||
if (rz != ZR_OK && rz != ZR_MORE) {
|
||||
printf(name.c_str());
|
||||
printf(" Unzip error\n");
|
||||
}
|
||||
else {
|
||||
texture.hash = temp_hash;
|
||||
texture.data = data;
|
||||
texture.name = file;
|
||||
Textures.push_back(texture);
|
||||
printf(name.c_str());
|
||||
printf(" Added texture of size %d %s\n", data.size(), file.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf(name.c_str());
|
||||
printf(" Unzip error\n");
|
||||
CloseZip(ZIP_Handle); //somehow we need to close and to reopen the zip handle, otherwise the program crashes
|
||||
ZIP_Handle = OpenZip(FileInMemory, FileLen, pw);
|
||||
}
|
||||
}
|
||||
delete[] def;
|
||||
|
||||
CloseZip(ZIP_Handle);
|
||||
if (Textures.size() == 0) {
|
||||
printf(name.c_str());
|
||||
printf(" No textures parsed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//we load each dds file
|
||||
{
|
||||
printf(name.c_str());
|
||||
printf(" Unzipping without texmode.def\n");
|
||||
CloseZip(ZIP_Handle); //somehow we need to close and to reopen the zip handle, otherwise the program crashes
|
||||
ZIP_Handle = OpenZip(FileInMemory, FileLen, pw);
|
||||
if (ZIP_Handle == static_cast<HZIP>(nullptr)) {
|
||||
printf(name.c_str());
|
||||
printf(" Failed to unzip file");
|
||||
return -1;
|
||||
}
|
||||
std::string file;
|
||||
GetZipItem(ZIP_Handle, -1, &ze); //ask for number of entries
|
||||
int num = ze.index;
|
||||
DWORD64 temp_hash;
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (GetZipItem(ZIP_Handle, i, &ze) != ZR_OK) {
|
||||
continue; //ask for name and size
|
||||
}
|
||||
int len = ze.unc_size;
|
||||
|
||||
printf(name.c_str());
|
||||
printf(" Parsing token %s\n", ze.name);
|
||||
std::vector<char> data;
|
||||
UModTexture texture;
|
||||
data.resize(ze.unc_size);
|
||||
|
||||
ZRESULT rz = UnzipItem(ZIP_Handle, i, data.data(), len);
|
||||
if (rz != ZR_OK && rz != ZR_MORE) {
|
||||
printf(name.c_str());
|
||||
printf(" Unzip error\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
file = ze.name;
|
||||
if (file.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file == "Comment.txt") // skip comment
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto entryName = AfterLast(file, '.');
|
||||
if (entryName != "dds") {
|
||||
continue;
|
||||
}
|
||||
|
||||
entryName = AfterLast(file, L'_');
|
||||
entryName = BeforeLast(entryName, L'.');
|
||||
|
||||
try {
|
||||
temp_hash = std::stoull(entryName, nullptr, 16); // Convert hex string to number
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
printf(name.c_str());
|
||||
printf(" Invalid hash\n");
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
printf(name.c_str());
|
||||
printf(" Invalid hash\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
texture.hash = temp_hash;
|
||||
texture.name = entryName;
|
||||
texture.data = data;
|
||||
Textures.push_back(texture);
|
||||
printf(name.c_str());
|
||||
printf(" Added texture of size %d %s\n", data.size(), entryName.c_str());
|
||||
}
|
||||
|
||||
CloseZip(ZIP_Handle);
|
||||
if (Textures.size() == 0) {
|
||||
printf(name.c_str());
|
||||
printf(" No textures parsed\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
uMod_IDirect3D9::uMod_IDirect3D9(IDirect3D9* pOriginal, uMod_TextureServer* server)
|
||||
{
|
||||
Message(PRE_MESSAGE "::" PRE_MESSAGE "( %lu, %lu): %lu\n", pOriginal, server, this);
|
||||
Message(PRE_MESSAGE "::" PRE_MESSAGE "( %p, %p): %p\n", pOriginal, server, this);
|
||||
m_pIDirect3D9 = pOriginal;
|
||||
uMod_Server = server;
|
||||
}
|
||||
|
||||
uMod_IDirect3D9::~uMod_IDirect3D9()
|
||||
{
|
||||
Message(PRE_MESSAGE "::~" PRE_MESSAGE "(): %lu\n", this);
|
||||
Message(PRE_MESSAGE "::~" PRE_MESSAGE "(): %p\n", this);
|
||||
}
|
||||
|
||||
HRESULT __stdcall uMod_IDirect3D9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
@@ -118,7 +118,7 @@ HMONITOR __stdcall uMod_IDirect3D9::GetAdapterMonitor(UINT Adapter)
|
||||
|
||||
HRESULT __stdcall uMod_IDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
|
||||
{
|
||||
Message(PRE_MESSAGE "::CreateDevice(): %lu\n", this);
|
||||
Message(PRE_MESSAGE "::CreateDevice(): %p\n", this);
|
||||
// we intercept this call and provide our own "fake" Device Object
|
||||
const HRESULT hres = m_pIDirect3D9->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
HRESULT __stdcall uMod_IDirect3D9Ex::CreateDeviceEx(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode,
|
||||
IDirect3DDevice9Ex** ppReturnedDeviceInterface)
|
||||
{
|
||||
Message("uMod_IDirect3D9Ex::CreateDeviceEx: %lu\n", this);
|
||||
Message("uMod_IDirect3D9Ex::CreateDeviceEx: %p\n", this);
|
||||
// we intercept this call and provide our own "fake" Device Object
|
||||
const HRESULT hres = m_pIDirect3D9Ex->CreateDeviceEx(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode, ppReturnedDeviceInterface);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ ULONG APIENTRY uMod_IDirect3DCubeTexture9::AddRef()
|
||||
//this function yields for the non switched texture object
|
||||
ULONG APIENTRY uMod_IDirect3DCubeTexture9::Release()
|
||||
{
|
||||
Message("uMod_IDirect3DCubeTexture9::Release(): %lu\n", this);
|
||||
Message("uMod_IDirect3DCubeTexture9::Release(): %p\n", this);
|
||||
|
||||
void* cpy;
|
||||
const long ret = m_D3Ddev->QueryInterface(IID_IDirect3DTexture9, &cpy);
|
||||
|
||||
@@ -111,7 +111,7 @@ int uMod_IDirect3DDevice9::CreateSingleTexture()
|
||||
|
||||
uMod_IDirect3DDevice9::uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, uMod_TextureServer* server, int back_buffer_count)
|
||||
{
|
||||
Message(PRE_MESSAGE "::" PRE_MESSAGE "( %lu, %lu): %lu\n", pOriginal, server, this);
|
||||
Message(PRE_MESSAGE "::" PRE_MESSAGE "( %p, %p): %p\n", pOriginal, server, this);
|
||||
|
||||
BackBufferCount = back_buffer_count;
|
||||
NormalRendering = true;
|
||||
@@ -137,7 +137,7 @@ uMod_IDirect3DDevice9::uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, uMod_T
|
||||
|
||||
uMod_IDirect3DDevice9::~uMod_IDirect3DDevice9()
|
||||
{
|
||||
Message(PRE_MESSAGE "::~" PRE_MESSAGE "(): %lu\n", this);
|
||||
Message(PRE_MESSAGE "::~" PRE_MESSAGE "(): %p\n", this);
|
||||
}
|
||||
|
||||
HRESULT uMod_IDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
@@ -150,7 +150,7 @@ HRESULT uMod_IDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
}
|
||||
|
||||
*ppvObj = nullptr;
|
||||
Message(PRE_MESSAGE "::QueryInterface(): %lu\n", this);
|
||||
Message(PRE_MESSAGE "::QueryInterface(): %p\n", this);
|
||||
const HRESULT hRes = m_pIDirect3DDevice9->QueryInterface(riid, ppvObj);
|
||||
|
||||
if (*ppvObj == m_pIDirect3DDevice9) {
|
||||
@@ -164,7 +164,7 @@ HRESULT uMod_IDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
ULONG uMod_IDirect3DDevice9::AddRef()
|
||||
{
|
||||
uMod_Reference++; //increasing our counter
|
||||
Message("%lu = " PRE_MESSAGE "::AddRef(): %lu\n", uMod_Reference, this);
|
||||
Message("%p = " PRE_MESSAGE "::AddRef(): %p\n", uMod_Reference, this);
|
||||
return m_pIDirect3DDevice9->AddRef();
|
||||
}
|
||||
|
||||
@@ -188,20 +188,17 @@ ULONG uMod_IDirect3DDevice9::Release()
|
||||
OSD_Font->Release();
|
||||
}
|
||||
|
||||
if (uMod_Client != nullptr) {
|
||||
delete uMod_Client; //must be deleted at the end, because other releases might call a function of this object
|
||||
}
|
||||
|
||||
delete uMod_Client; //must be deleted at the end, because other releases might call a function of this object
|
||||
uMod_Client = nullptr;
|
||||
SingleTexture = nullptr;
|
||||
OSD_Font = nullptr;
|
||||
}
|
||||
|
||||
const ULONG count = m_pIDirect3DDevice9->Release();
|
||||
Message("%lu = " PRE_MESSAGE "::Release(): %lu\n", count, this);
|
||||
Message("%p = " PRE_MESSAGE "::Release(): %p\n", count, this);
|
||||
if (uMod_Reference != count) //bug
|
||||
{
|
||||
Message("Error in " PRE_MESSAGE "::Release(): %lu!=%lu\n", uMod_Reference, count);
|
||||
Message("Error in " PRE_MESSAGE "::Release(): %p!=%p\n", uMod_Reference, count);
|
||||
}
|
||||
|
||||
if (count == 0u) {
|
||||
@@ -416,7 +413,7 @@ HRESULT uMod_IDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface,C
|
||||
|
||||
HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture)
|
||||
{
|
||||
Message(PRE_MESSAGE "::UpdateTexture( %lu, %lu): %lu\n", pSourceTexture, pDestinationTexture, this);
|
||||
Message(PRE_MESSAGE "::UpdateTexture( %p, %p): %p\n", pSourceTexture, pDestinationTexture, this);
|
||||
// we must pass the real texture objects
|
||||
|
||||
|
||||
@@ -637,215 +634,25 @@ HRESULT uMod_IDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZSte
|
||||
|
||||
HRESULT uMod_IDirect3DDevice9::BeginScene()
|
||||
{
|
||||
//if ( NormalRendering )
|
||||
if (LastCreatedTexture != nullptr) // add the last created texture
|
||||
{
|
||||
if (LastCreatedTexture != nullptr) // add the last created texture
|
||||
{
|
||||
uMod_Client->AddTexture(LastCreatedTexture);
|
||||
}
|
||||
if (LastCreatedVolumeTexture != nullptr) // add the last created texture
|
||||
{
|
||||
uMod_Client->AddTexture(LastCreatedVolumeTexture);
|
||||
}
|
||||
if (LastCreatedCubeTexture != nullptr) // add the last created texture
|
||||
{
|
||||
uMod_Client->AddTexture(LastCreatedCubeTexture);
|
||||
}
|
||||
uMod_Client->MergeUpdate(); // merge an update, if present
|
||||
|
||||
if (uMod_Client->BoolSaveSingleTexture) {
|
||||
if (CreateSingleTexture() == 0) {
|
||||
if (uMod_Client->KeyBack > 0 && (GetAsyncKeyState(uMod_Client->KeyBack) & 1)) //ask for the status of the back key
|
||||
{
|
||||
UnswitchTextures(SingleTexture); // can be called, even if texture is not switched
|
||||
UnswitchTextures(SingleVolumeTexture); // can be called, even if texture is not switched
|
||||
UnswitchTextures(SingleCubeTexture); // can be called, even if texture is not switched
|
||||
|
||||
if (CounterSaveSingleTexture < -10) {
|
||||
CounterSaveSingleTexture = 0;
|
||||
SingleTextureMod = 0;
|
||||
} //first initialization of the counter
|
||||
else if (--CounterSaveSingleTexture < 0) {
|
||||
if (--SingleTextureMod < 0) {
|
||||
SingleTextureMod = 2;
|
||||
}
|
||||
switch (SingleTextureMod) {
|
||||
case 0:
|
||||
CounterSaveSingleTexture = uMod_Client->OriginalTextures.GetNumber() - 1;
|
||||
break;
|
||||
case 1:
|
||||
CounterSaveSingleTexture = uMod_Client->OriginalVolumeTextures.GetNumber() - 1;
|
||||
break;
|
||||
case 2:
|
||||
CounterSaveSingleTexture = uMod_Client->OriginalCubeTextures.GetNumber() - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CounterSaveSingleTexture >= 0) {
|
||||
switch (SingleTextureMod) {
|
||||
case 0:
|
||||
SwitchTextures(SingleTexture, uMod_Client->OriginalTextures[CounterSaveSingleTexture]);
|
||||
SingleTexture->Hash = uMod_Client->OriginalTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
|
||||
break;
|
||||
case 1:
|
||||
SwitchTextures(SingleVolumeTexture, uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]);
|
||||
SingleVolumeTexture->Hash = uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
|
||||
break;
|
||||
case 2:
|
||||
SwitchTextures(SingleCubeTexture, uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]);
|
||||
SingleCubeTexture->Hash = uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uMod_Client->KeySave > 0 && (GetAsyncKeyState(uMod_Client->KeySave) & 1)) //ask for the status of the save key
|
||||
{
|
||||
switch (SingleTextureMod) {
|
||||
case 0:
|
||||
uMod_Client->SaveTexture(SingleTexture); //after switching the SingleTexture holds the pointer to the original texture object
|
||||
break;
|
||||
case 1:
|
||||
uMod_Client->SaveTexture(SingleVolumeTexture); //after switching the SingleTexture holds the pointer to the original texture object
|
||||
break;
|
||||
case 2:
|
||||
uMod_Client->SaveTexture(SingleCubeTexture); //after switching the SingleTexture holds the pointer to the original texture object
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uMod_Client->KeyNext > 0 && (GetAsyncKeyState(uMod_Client->KeyNext) & 1)) //ask for the status of the next key
|
||||
{
|
||||
UnswitchTextures(SingleTexture); // can be called, even if texture is not switched
|
||||
UnswitchTextures(SingleVolumeTexture); // can be called, even if texture is not switched
|
||||
UnswitchTextures(SingleCubeTexture); // can be called, even if texture is not switched
|
||||
|
||||
if (CounterSaveSingleTexture < -10) {
|
||||
CounterSaveSingleTexture = 0;
|
||||
SingleTextureMod = 0;
|
||||
} //first initialization of the counter
|
||||
else {
|
||||
int num = 0;
|
||||
switch (SingleTextureMod) {
|
||||
case 0:
|
||||
num = uMod_Client->OriginalTextures.GetNumber();
|
||||
break;
|
||||
case 1:
|
||||
num = uMod_Client->OriginalVolumeTextures.GetNumber();
|
||||
break;
|
||||
case 2:
|
||||
num = uMod_Client->OriginalCubeTextures.GetNumber();
|
||||
break;
|
||||
}
|
||||
if (++CounterSaveSingleTexture >= num) {
|
||||
if (++SingleTextureMod > 2) {
|
||||
SingleTextureMod = 0;
|
||||
}
|
||||
switch (SingleTextureMod) {
|
||||
case 0:
|
||||
CounterSaveSingleTexture = uMod_Client->OriginalTextures.GetNumber() > 0 ? 0 : -1;
|
||||
break;
|
||||
case 1:
|
||||
CounterSaveSingleTexture = uMod_Client->OriginalVolumeTextures.GetNumber() > 0 ? 0 : -1;
|
||||
break;
|
||||
case 2:
|
||||
CounterSaveSingleTexture = uMod_Client->OriginalCubeTextures.GetNumber() > 0 ? 0 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CounterSaveSingleTexture >= 0) {
|
||||
switch (SingleTextureMod) {
|
||||
case 0:
|
||||
SwitchTextures(SingleTexture, uMod_Client->OriginalTextures[CounterSaveSingleTexture]);
|
||||
SingleTexture->Hash = uMod_Client->OriginalTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
|
||||
break;
|
||||
case 1:
|
||||
SwitchTextures(SingleVolumeTexture, uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]);
|
||||
SingleVolumeTexture->Hash = uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
|
||||
break;
|
||||
case 2:
|
||||
SwitchTextures(SingleCubeTexture, uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]);
|
||||
SingleCubeTexture->Hash = uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uMod_Client->AddTexture(LastCreatedTexture);
|
||||
}
|
||||
if (LastCreatedVolumeTexture != nullptr) // add the last created texture
|
||||
{
|
||||
uMod_Client->AddTexture(LastCreatedVolumeTexture);
|
||||
}
|
||||
if (LastCreatedCubeTexture != nullptr) // add the last created texture
|
||||
{
|
||||
uMod_Client->AddTexture(LastCreatedCubeTexture);
|
||||
}
|
||||
uMod_Client->MergeUpdate(); // merge an update, if present
|
||||
|
||||
return m_pIDirect3DDevice9->BeginScene();
|
||||
}
|
||||
|
||||
HRESULT uMod_IDirect3DDevice9::EndScene()
|
||||
{
|
||||
if (NormalRendering && uMod_Client->BoolSaveSingleTexture && SingleTexture != nullptr && SingleVolumeTexture != nullptr && SingleCubeTexture != nullptr) {
|
||||
if (OSD_Font == nullptr) // create the font
|
||||
{
|
||||
if (D3D_OK != D3DXCreateFontA(m_pIDirect3DDevice9, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &OSD_Font)) {
|
||||
OSD_Font = nullptr;
|
||||
return m_pIDirect3DDevice9->EndScene();
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[100];
|
||||
buffer[0] = 0;
|
||||
switch (SingleTextureMod) {
|
||||
case 0: {
|
||||
if (SingleTexture->CrossRef_D3Dtex != nullptr) {
|
||||
sprintf_s(buffer, 100, "normal texture: %4d (1..%d): %#lX", CounterSaveSingleTexture + 1, uMod_Client->OriginalTextures.GetNumber(), SingleTexture->Hash);
|
||||
}
|
||||
else {
|
||||
if (uMod_Client->OriginalTextures.GetNumber() > 0) {
|
||||
sprintf_s(buffer, 100, "normal texture: nothing selected (1..%d)", uMod_Client->OriginalTextures.GetNumber());
|
||||
}
|
||||
else {
|
||||
sprintf_s(buffer, 100, "normal texture: nothing loaded");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
if (SingleVolumeTexture->CrossRef_D3Dtex != nullptr) {
|
||||
sprintf_s(buffer, 100, "volume texture: %4d (1..%d): %#lX", CounterSaveSingleTexture + 1, uMod_Client->OriginalVolumeTextures.GetNumber(), SingleVolumeTexture->Hash);
|
||||
}
|
||||
else {
|
||||
if (uMod_Client->OriginalVolumeTextures.GetNumber() > 0) {
|
||||
sprintf_s(buffer, 100, "volume texture: nothing selected (1..%d)", uMod_Client->OriginalVolumeTextures.GetNumber());
|
||||
}
|
||||
else {
|
||||
sprintf_s(buffer, 100, "volume texture: nothing loaded");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
if (SingleCubeTexture->CrossRef_D3Dtex != nullptr) {
|
||||
sprintf_s(buffer, 100, "cube texture: %4d (1..%d): %#lX", CounterSaveSingleTexture + 1, uMod_Client->OriginalCubeTextures.GetNumber(), SingleCubeTexture->Hash);
|
||||
}
|
||||
else {
|
||||
if (uMod_Client->OriginalCubeTextures.GetNumber() > 0) {
|
||||
sprintf_s(buffer, 100, "cube texture: nothing selected (1..%d)", uMod_Client->OriginalCubeTextures.GetNumber());
|
||||
}
|
||||
else {
|
||||
sprintf_s(buffer, 100, "cube texture: nothing loaded");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
D3DVIEWPORT9 viewport;
|
||||
GetViewport(&viewport);
|
||||
RECT rct;
|
||||
rct.left = viewport.X + 10;
|
||||
rct.right = 0; //size of box is calculated automatically (DT_NOCLIP)
|
||||
rct.top = viewport.Y + 10;
|
||||
rct.bottom = 0; //size of box is calculated automatically (DT_NOCLIP)
|
||||
OSD_Font->DrawTextA(nullptr, buffer, -1, &rct, DT_NOCLIP, uMod_Client->FontColour);
|
||||
}
|
||||
return m_pIDirect3DDevice9->EndScene();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ ULONG APIENTRY uMod_IDirect3DTexture9::AddRef()
|
||||
//this function yields for the non switched texture object
|
||||
ULONG APIENTRY uMod_IDirect3DTexture9::Release()
|
||||
{
|
||||
Message("uMod_IDirect3DTexture9::Release(): %lu\n", this);
|
||||
Message("uMod_IDirect3DTexture9::Release(): %p\n", this);
|
||||
|
||||
void* cpy;
|
||||
const long ret = m_D3Ddev->QueryInterface(IID_IDirect3DTexture9, &cpy);
|
||||
@@ -103,7 +103,7 @@ ULONG APIENTRY uMod_IDirect3DTexture9::Release()
|
||||
delete(this);
|
||||
}
|
||||
|
||||
Message("uMod_IDirect3DTexture9::Release() end: %lu\n", this);
|
||||
Message("uMod_IDirect3DTexture9::Release() end: %p\n", this);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ ULONG APIENTRY uMod_IDirect3DVolumeTexture9::AddRef()
|
||||
//this function yields for the non switched texture object
|
||||
ULONG APIENTRY uMod_IDirect3DVolumeTexture9::Release()
|
||||
{
|
||||
Message("uMod_IDirect3DVolumeTexture9::Release(): %lu\n", this);
|
||||
Message("uMod_IDirect3DVolumeTexture9::Release(): %p\n", this);
|
||||
|
||||
void* cpy;
|
||||
const long ret = m_D3Ddev->QueryInterface(IID_IDirect3DTexture9, &cpy);
|
||||
|
||||
+19
-181
@@ -2,17 +2,9 @@
|
||||
|
||||
uMod_TextureClient::uMod_TextureClient(uMod_TextureServer* server, IDirect3DDevice9* device)
|
||||
{
|
||||
Message("uMod_TextureClient::uMod_TextureClient(): %lu\n", this);
|
||||
Message("uMod_TextureClient::uMod_TextureClient(): %p\n", this);
|
||||
Server = server;
|
||||
D3D9Device = device;
|
||||
BoolSaveAllTextures = false;
|
||||
BoolSaveSingleTexture = false;
|
||||
KeyBack = 0;
|
||||
KeySave = 0;
|
||||
KeyNext = 0;
|
||||
SavePath[0] = 0;
|
||||
GameName[0] = 0;
|
||||
|
||||
NumberToMod = 0;
|
||||
FileToMod = nullptr;
|
||||
|
||||
@@ -39,7 +31,7 @@ uMod_TextureClient::uMod_TextureClient(uMod_TextureServer* server, IDirect3DDevi
|
||||
|
||||
uMod_TextureClient::~uMod_TextureClient()
|
||||
{
|
||||
Message("uMod_TextureClient::~uMod_TextureClient(): %lu\n", this);
|
||||
Message("uMod_TextureClient::~uMod_TextureClient(): %p\n", this);
|
||||
if (Server != nullptr) {
|
||||
Server->RemoveClient(this);
|
||||
}
|
||||
@@ -76,7 +68,7 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
return RETURN_OK; // this is a fake texture
|
||||
}
|
||||
|
||||
Message("uMod_TextureClient::AddTexture( %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThreadId());
|
||||
Message("uMod_TextureClient::AddTexture( %p): %p (thread: %p)\n", pTexture, this, GetCurrentThreadId());
|
||||
|
||||
MyTypeHash hash;
|
||||
if (const int ret = pTexture->GetHash(hash)) {
|
||||
@@ -85,10 +77,6 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
|
||||
pTexture->Hash = hash;
|
||||
|
||||
if (BoolSaveAllTextures) {
|
||||
SaveTexture(pTexture);
|
||||
}
|
||||
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
@@ -113,7 +101,7 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
return RETURN_OK; // this is a fake texture
|
||||
}
|
||||
|
||||
Message("uMod_TextureClient::AddTexture( Volume: %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThreadId());
|
||||
Message("uMod_TextureClient::AddTexture( Volume: %p): %p (thread: %p)\n", pTexture, this, GetCurrentThreadId());
|
||||
|
||||
MyTypeHash hash;
|
||||
if (const int ret = pTexture->GetHash(hash)) {
|
||||
@@ -122,10 +110,6 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
|
||||
pTexture->Hash = hash;
|
||||
|
||||
if (BoolSaveAllTextures) {
|
||||
SaveTexture(pTexture);
|
||||
}
|
||||
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
@@ -150,7 +134,7 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
return RETURN_OK; // this is a fake texture
|
||||
}
|
||||
|
||||
Message("uMod_TextureClient::AddTexture( Cube: %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThreadId());
|
||||
Message("uMod_TextureClient::AddTexture( Cube: %p): %p (thread: %p)\n", pTexture, this, GetCurrentThreadId());
|
||||
|
||||
MyTypeHash hash;
|
||||
if (const int ret = pTexture->GetHash(hash)) {
|
||||
@@ -159,10 +143,6 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
|
||||
pTexture->Hash = hash;
|
||||
|
||||
if (BoolSaveAllTextures) {
|
||||
SaveTexture(pTexture);
|
||||
}
|
||||
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
}
|
||||
@@ -176,7 +156,7 @@ int uMod_TextureClient::AddTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
|
||||
int uMod_TextureClient::RemoveTexture(uMod_IDirect3DTexture9* pTexture) // is called from a texture, if it is finally released
|
||||
{
|
||||
Message("uMod_TextureClient::RemoveTexture( %lu, %#lX): %lu\n", pTexture, pTexture->Hash, this);
|
||||
Message("uMod_TextureClient::RemoveTexture( %p, %#lX): %p\n", pTexture, pTexture->Hash, this);
|
||||
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
@@ -205,7 +185,7 @@ int uMod_TextureClient::RemoveTexture(uMod_IDirect3DTexture9* pTexture) // is ca
|
||||
|
||||
int uMod_TextureClient::RemoveTexture(uMod_IDirect3DVolumeTexture9* pTexture) // is called from a texture, if it is finally released
|
||||
{
|
||||
Message("uMod_TextureClient::RemoveTexture( Volume %lu, %#lX): %lu\n", pTexture, pTexture->Hash, this);
|
||||
Message("uMod_TextureClient::RemoveTexture( Volume %p, %#lX): %p\n", pTexture, pTexture->Hash, this);
|
||||
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
@@ -234,7 +214,7 @@ int uMod_TextureClient::RemoveTexture(uMod_IDirect3DVolumeTexture9* pTexture) //
|
||||
|
||||
int uMod_TextureClient::RemoveTexture(uMod_IDirect3DCubeTexture9* pTexture) // is called from a texture, if it is finally released
|
||||
{
|
||||
Message("uMod_TextureClient::RemoveTexture( Cube %lu, %#lX): %lu\n", pTexture, pTexture->Hash, this);
|
||||
Message("uMod_TextureClient::RemoveTexture( Cube %p, %#lX): %p\n", pTexture, pTexture->Hash, this);
|
||||
|
||||
if (gl_ErrorState & uMod_ERROR_FATAL) {
|
||||
return RETURN_FATAL_ERROR;
|
||||
@@ -262,150 +242,9 @@ int uMod_TextureClient::RemoveTexture(uMod_IDirect3DCubeTexture9* pTexture) // i
|
||||
}
|
||||
|
||||
|
||||
int uMod_TextureClient::SaveAllTextures(bool val)
|
||||
{
|
||||
Message("uMod_TextureClient::SaveAllTextures( %d): %lu\n", val, this);
|
||||
BoolSaveAllTextures = val;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureClient::SaveSingleTexture(bool val)
|
||||
{
|
||||
Message("uMod_TextureClient::SaveSingleTexture( %d): %lu\n", val, this);
|
||||
if (BoolSaveSingleTexture && !val) //if BoolSaveSingleTexture is set to false and was previously true we switch the SingleTexture back
|
||||
{
|
||||
uMod_IDirect3DTexture9* pTexture;
|
||||
void* cpy;
|
||||
const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy);
|
||||
if (ret == 0x01000000L) {
|
||||
pTexture = static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->GetSingleTexture(); //this texture must no be added twice
|
||||
}
|
||||
else {
|
||||
pTexture = static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->GetSingleTexture(); //this texture must no be added twice
|
||||
}
|
||||
|
||||
if (pTexture != nullptr) {
|
||||
UnswitchTextures(pTexture);
|
||||
}
|
||||
}
|
||||
BoolSaveSingleTexture = val;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
int uMod_TextureClient::SetSaveDirectory(wchar_t* dir)
|
||||
{
|
||||
Message("uMod_TextureClient::SetSaveDirectory( %ls): %lu\n", dir, this);
|
||||
int i = 0;
|
||||
for (i = 0; i < MAX_PATH && (dir[i]); i++) {
|
||||
SavePath[i] = dir[i];
|
||||
}
|
||||
if (i == MAX_PATH) {
|
||||
SavePath[0] = 0;
|
||||
return RETURN_BAD_ARGUMENT;
|
||||
}
|
||||
SavePath[i] = 0;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureClient::SetGameName(wchar_t* name)
|
||||
{
|
||||
Message("uMod_TextureClient::SetGameName( %ls): %lu\n", name, this);
|
||||
int i = 0;
|
||||
for (i = 0; i < MAX_PATH && (name[i]); i++) {
|
||||
GameName[i] = name[i];
|
||||
}
|
||||
if (i == MAX_PATH) {
|
||||
GameName[0] = 0;
|
||||
return RETURN_BAD_ARGUMENT;
|
||||
}
|
||||
GameName[i] = 0;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uMod_TextureClient::SaveTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
{
|
||||
if (pTexture == nullptr) {
|
||||
return RETURN_BAD_ARGUMENT;
|
||||
}
|
||||
if (SavePath[0] == 0) {
|
||||
Message("uMod_TextureClient::SaveTexture( %#lX, %lu): %lu, SavePath not set\n", pTexture->Hash, pTexture->m_D3Dtex, this);
|
||||
return RETURN_TEXTURE_NOT_SAVED;
|
||||
}
|
||||
|
||||
wchar_t file[MAX_PATH];
|
||||
if (GameName[0]) {
|
||||
swprintf_s(file, MAX_PATH, L"%ls\\%ls_T_%#lX.dds", SavePath, GameName, pTexture->Hash);
|
||||
}
|
||||
else {
|
||||
swprintf_s(file, MAX_PATH, L"%ls\\T_%#lX.dds", SavePath, pTexture->Hash);
|
||||
}
|
||||
Message("uMod_TextureClient::SaveTexture( %ls): %lu\n", file, this);
|
||||
|
||||
if (D3D_OK != D3DXSaveTextureToFileW(file, D3DXIFF_DDS, pTexture->m_D3Dtex, nullptr)) {
|
||||
return RETURN_TEXTURE_NOT_SAVED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureClient::SaveTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
{
|
||||
if (pTexture == nullptr) {
|
||||
return RETURN_BAD_ARGUMENT;
|
||||
}
|
||||
if (SavePath[0] == 0) {
|
||||
Message("uMod_TextureClient::SaveTexture( %#lX, %lu): %lu, SavePath not set\n", pTexture->Hash, pTexture->m_D3Dtex, this);
|
||||
return RETURN_TEXTURE_NOT_SAVED;
|
||||
}
|
||||
|
||||
wchar_t file[MAX_PATH];
|
||||
if (GameName[0]) {
|
||||
swprintf_s(file, MAX_PATH, L"%ls\\%ls_V_%#lX.dds", SavePath, GameName, pTexture->Hash);
|
||||
}
|
||||
else {
|
||||
swprintf_s(file, MAX_PATH, L"%ls\\V_%#lX.dds", SavePath, pTexture->Hash);
|
||||
}
|
||||
Message("uMod_TextureClient::SaveTexture( %ls): %lu\n", file, this);
|
||||
|
||||
if (D3D_OK != D3DXSaveTextureToFileW(file, D3DXIFF_DDS, pTexture->m_D3Dtex, nullptr)) {
|
||||
return RETURN_TEXTURE_NOT_SAVED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureClient::SaveTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
{
|
||||
if (pTexture == nullptr) {
|
||||
return RETURN_BAD_ARGUMENT;
|
||||
}
|
||||
if (SavePath[0] == 0) {
|
||||
Message("uMod_TextureClient::SaveTexture( %#lX, %lu): %lu, SavePath not set\n", pTexture->Hash, pTexture->m_D3Dtex, this);
|
||||
return RETURN_TEXTURE_NOT_SAVED;
|
||||
}
|
||||
|
||||
wchar_t file[MAX_PATH];
|
||||
if (GameName[0]) {
|
||||
swprintf_s(file, MAX_PATH, L"%ls\\%ls_C_%#lX.dds", SavePath, GameName, pTexture->Hash);
|
||||
}
|
||||
else {
|
||||
swprintf_s(file, MAX_PATH, L"%ls\\C_%#lX.dds", SavePath, pTexture->Hash);
|
||||
}
|
||||
Message("uMod_TextureClient::SaveTexture( %ls): %lu\n", file, this);
|
||||
|
||||
if (D3D_OK != D3DXSaveTextureToFileW(file, D3DXIFF_DDS, pTexture->m_D3Dtex, nullptr)) {
|
||||
return RETURN_TEXTURE_NOT_SAVED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int uMod_TextureClient::AddUpdate(TextureFileStruct* update, int number) //client must delete the update array
|
||||
{
|
||||
Message("AddUpdate( %lu, %d): %lu\n", update, number, this);
|
||||
Message("AddUpdate( %p, %d): %p\n", update, number, this);
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_TEXTURE;
|
||||
return ret;
|
||||
@@ -419,7 +258,6 @@ int uMod_TextureClient::AddUpdate(TextureFileStruct* update, int number) //clie
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uMod_TextureClient::MergeUpdate()
|
||||
{
|
||||
if (NumberOfUpdate < 0) { return RETURN_OK; }
|
||||
@@ -428,7 +266,7 @@ int uMod_TextureClient::MergeUpdate()
|
||||
return ret;
|
||||
}
|
||||
|
||||
Message("MergeUpdate(): %lu\n", this);
|
||||
Message("MergeUpdate(): %p\n", this);
|
||||
|
||||
for (int i = 0; i < NumberOfUpdate; i++) {
|
||||
Update[i].NumberOfTextures = 0;
|
||||
@@ -822,7 +660,7 @@ int uMod_TextureClient::LookUpToMod(MyTypeHash hash, int num_index_list, int* in
|
||||
|
||||
int uMod_TextureClient::LookUpToMod(uMod_IDirect3DTexture9* pTexture, int num_index_list, int* index_list) // should only be called for original textures
|
||||
{
|
||||
Message("uMod_TextureClient::LookUpToMod( %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
|
||||
Message("uMod_TextureClient::LookUpToMod( %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this);
|
||||
if (pTexture->CrossRef_D3Dtex != nullptr) {
|
||||
return RETURN_OK; // bug, this texture is already switched
|
||||
}
|
||||
@@ -855,7 +693,7 @@ int uMod_TextureClient::LookUpToMod(uMod_IDirect3DTexture9* pTexture, int num_in
|
||||
|
||||
int uMod_TextureClient::LookUpToMod(uMod_IDirect3DVolumeTexture9* pTexture, int num_index_list, int* index_list) // should only be called for original textures
|
||||
{
|
||||
Message("uMod_TextureClient::LookUpToMod( Volume %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
|
||||
Message("uMod_TextureClient::LookUpToMod( Volume %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this);
|
||||
if (pTexture->CrossRef_D3Dtex != nullptr) {
|
||||
return RETURN_OK; // bug, this texture is already switched
|
||||
}
|
||||
@@ -888,7 +726,7 @@ int uMod_TextureClient::LookUpToMod(uMod_IDirect3DVolumeTexture9* pTexture, int
|
||||
|
||||
int uMod_TextureClient::LookUpToMod(uMod_IDirect3DCubeTexture9* pTexture, int num_index_list, int* index_list) // should only be called for original textures
|
||||
{
|
||||
Message("uMod_TextureClient::LookUpToMod( Cube %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
|
||||
Message("uMod_TextureClient::LookUpToMod( Cube %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this);
|
||||
if (pTexture->CrossRef_D3Dtex != nullptr) {
|
||||
return RETURN_OK; // bug, this texture is already switched
|
||||
}
|
||||
@@ -920,7 +758,7 @@ int uMod_TextureClient::LookUpToMod(uMod_IDirect3DCubeTexture9* pTexture, int nu
|
||||
|
||||
int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DTexture9** ppTexture) // to load fake texture from a file in memory
|
||||
{
|
||||
Message("LoadTexture( %lu, %lu, %#lX): %lu\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
|
||||
Message("LoadTexture( %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
|
||||
if (D3D_OK != D3DXCreateTextureFromFileInMemoryEx(D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, nullptr,
|
||||
(IDirect3DTexture9**)ppTexture))
|
||||
//if (D3D_OK != D3DXCreateTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DTexture9 **) ppTexture))
|
||||
@@ -939,13 +777,13 @@ int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDir
|
||||
static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedTexture(nullptr); //this texture must no be added twice
|
||||
}
|
||||
|
||||
Message("LoadTexture( %lu, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
|
||||
Message("LoadTexture( %p, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DVolumeTexture9** ppTexture) // to load fake texture from a file in memory
|
||||
{
|
||||
Message("LoadTexture( Volume %lu, %lu, %#lX): %lu\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
|
||||
Message("LoadTexture( Volume %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
|
||||
if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemoryEx(D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr,
|
||||
nullptr,
|
||||
(IDirect3DVolumeTexture9**)ppTexture))
|
||||
@@ -965,13 +803,13 @@ int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDir
|
||||
static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedVolumeTexture(nullptr); //this texture must no be added twice
|
||||
}
|
||||
|
||||
Message("LoadTexture( Volume %lu, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
|
||||
Message("LoadTexture( Volume %p, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DCubeTexture9** ppTexture) // to load fake texture from a file in memory
|
||||
{
|
||||
Message("LoadTexture( Cube %lu, %lu, %#lX): %lu\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
|
||||
Message("LoadTexture( Cube %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
|
||||
if (D3D_OK != D3DXCreateCubeTextureFromFileInMemoryEx(D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, nullptr,
|
||||
(IDirect3DCubeTexture9**)ppTexture))
|
||||
//if (D3D_OK != D3DXCreateCubeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DCubeTexture9 **) ppTexture))
|
||||
@@ -990,6 +828,6 @@ int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDir
|
||||
static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedCubeTexture(nullptr); //this texture must no be added twice
|
||||
}
|
||||
|
||||
Message("LoadTexture( Cube %lu, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
|
||||
Message("LoadTexture( Cube %p, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
+68
-439
@@ -1,17 +1,19 @@
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include "uMod_Main.h"
|
||||
#include "uMod_File.h"
|
||||
#include "gMod_FileLoader.h"
|
||||
|
||||
long long loadedSize = 0;
|
||||
|
||||
uMod_TextureServer::uMod_TextureServer(char* game, char* uModName)
|
||||
{
|
||||
Message("uMod_TextureServer(): %lu\n", this);
|
||||
|
||||
Mutex = CreateMutex(nullptr, false, nullptr);
|
||||
Message("uMod_TextureServer(): %p\n", this);
|
||||
|
||||
Clients = nullptr;
|
||||
NumberOfClients = 0;
|
||||
LenghtOfClients = 0;
|
||||
BoolSaveAllTextures = false;
|
||||
BoolSaveSingleTexture = false;
|
||||
SavePath[0] = 0;
|
||||
|
||||
int len = 0;
|
||||
@@ -44,28 +46,12 @@ uMod_TextureServer::uMod_TextureServer(char* game, char* uModName)
|
||||
GameName[0] = 0;
|
||||
}
|
||||
|
||||
for (len = 0; len < MAX_PATH; len++) {
|
||||
UModName[len] = uModName[len];
|
||||
}
|
||||
|
||||
KeyBack = 0;
|
||||
KeySave = 0;
|
||||
KeyNext = 0;
|
||||
|
||||
FontColour = 0u;
|
||||
TextureColour = 0u;
|
||||
|
||||
Pipe.In = INVALID_HANDLE_VALUE;
|
||||
Pipe.Out = INVALID_HANDLE_VALUE;
|
||||
strcpy(UModName, uModName);
|
||||
}
|
||||
|
||||
uMod_TextureServer::~uMod_TextureServer()
|
||||
{
|
||||
Message("~uMod_TextureServer(): %lu\n", this);
|
||||
if (Mutex != nullptr) {
|
||||
CloseHandle(Mutex);
|
||||
}
|
||||
|
||||
Message("~uMod_TextureServer(): %p\n", this);
|
||||
//delete the files in memory
|
||||
int num = CurrentMod.GetNumber();
|
||||
for (int i = 0; i < num; i++) {
|
||||
@@ -76,55 +62,14 @@ uMod_TextureServer::~uMod_TextureServer()
|
||||
for (int i = 0; i < num; i++) {
|
||||
delete[] OldMod[i]->pData; //delete the file content of the texture
|
||||
}
|
||||
|
||||
if (Pipe.In != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(Pipe.In);
|
||||
}
|
||||
Pipe.In = INVALID_HANDLE_VALUE;
|
||||
if (Pipe.Out != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(Pipe.Out);
|
||||
}
|
||||
Pipe.Out = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
int uMod_TextureServer::AddClient(uMod_TextureClient* client, TextureFileStruct** update, int* number) // called from a client
|
||||
{
|
||||
Message("AddClient(%lu): %lu\n", client, this);
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Message("AddClient(%p): %p\n", client, this);
|
||||
// the following functions must not change the original uMod_IDirect3DDevice9 object
|
||||
// somehow on game start some uMod_IDirect3DDevice9 object are created, which must rest unchanged!!
|
||||
// these objects are released and are not used for rendering
|
||||
client->SetGameName(GameName);
|
||||
client->SaveAllTextures(BoolSaveAllTextures);
|
||||
client->SaveSingleTexture(BoolSaveSingleTexture);
|
||||
client->SetSaveDirectory(SavePath);
|
||||
if (KeyBack > 0) {
|
||||
client->SetKeyBack(KeyBack);
|
||||
}
|
||||
if (KeySave > 0) {
|
||||
client->SetKeySave(KeySave);
|
||||
}
|
||||
if (KeyNext > 0) {
|
||||
client->SetKeyNext(KeyNext);
|
||||
}
|
||||
|
||||
if (FontColour > 0u) {
|
||||
const DWORD r = FontColour >> 16 & 0xFF;
|
||||
const DWORD g = FontColour >> 8 & 0xFF;
|
||||
const DWORD b = FontColour & 0xFF;
|
||||
client->SetFontColour(r, g, b);
|
||||
}
|
||||
if (TextureColour > 0u) {
|
||||
const DWORD r = TextureColour >> 16 & 0xFF;
|
||||
const DWORD g = TextureColour >> 8 & 0xFF;
|
||||
const DWORD b = TextureColour & 0xFF;
|
||||
client->SetTextureColour(r, g, b);
|
||||
}
|
||||
|
||||
|
||||
if (const int ret = PrepareUpdate(update, number)) {
|
||||
return ret; // get a copy of all texture to be modded
|
||||
@@ -137,9 +82,6 @@ int uMod_TextureServer::AddClient(uMod_TextureClient* client, TextureFileStruct*
|
||||
try { temp = new uMod_TextureClient*[LenghtOfClients + 10]; }
|
||||
catch (...) {
|
||||
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
|
||||
if (const int ret = UnlockMutex()) {
|
||||
return ret;
|
||||
}
|
||||
return RETURN_NO_MEMORY;
|
||||
}
|
||||
for (int i = 0; i < LenghtOfClients; i++) {
|
||||
@@ -153,17 +95,12 @@ int uMod_TextureServer::AddClient(uMod_TextureClient* client, TextureFileStruct*
|
||||
}
|
||||
Clients[NumberOfClients++] = client;
|
||||
|
||||
return UnlockMutex();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureServer::RemoveClient(uMod_TextureClient* client) // called from a client
|
||||
{
|
||||
Message("RemoveClient(): %lu\n", client);
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Message("RemoveClient(): %p\n", client);
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
if (client == Clients[i]) {
|
||||
NumberOfClients--;
|
||||
@@ -171,12 +108,12 @@ int uMod_TextureServer::RemoveClient(uMod_TextureClient* client) // called from
|
||||
break;
|
||||
}
|
||||
}
|
||||
return UnlockMutex();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureServer::AddFile(char* buffer, unsigned int size, MyTypeHash hash, bool force) // called from Mainloop()
|
||||
int uMod_TextureServer::AddFile(char* dataPtr, unsigned int size, MyTypeHash hash, bool force) // called from Mainloop()
|
||||
{
|
||||
Message("uMod_TextureServer::AddFile( %lu %lu, %#lX, %d): %lu\n", buffer, size, hash, force, this);
|
||||
Message("uMod_TextureServer::AddFile( %p %p, %#lX, %d): %p\n", dataPtr, size, hash, force, this);
|
||||
|
||||
TextureFileStruct* temp = nullptr;
|
||||
|
||||
@@ -188,7 +125,9 @@ int uMod_TextureServer::AddFile(char* buffer, unsigned int size, MyTypeHash hash
|
||||
temp = CurrentMod[i];
|
||||
break;
|
||||
} // we need to reload it
|
||||
return RETURN_OK; // we still have added this texture
|
||||
|
||||
|
||||
return RETURN_EXISTS; // we still have added this texture
|
||||
}
|
||||
}
|
||||
if (temp == nullptr) // if not found, look through all old textures
|
||||
@@ -202,7 +141,8 @@ int uMod_TextureServer::AddFile(char* buffer, unsigned int size, MyTypeHash hash
|
||||
if (force) {
|
||||
break; // we must reload it
|
||||
}
|
||||
return RETURN_OK; // we should not reload it
|
||||
|
||||
return RETURN_EXISTS; // we should not reload it
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,22 +163,7 @@ int uMod_TextureServer::AddFile(char* buffer, unsigned int size, MyTypeHash hash
|
||||
temp->Reference = -1;
|
||||
}
|
||||
|
||||
try {
|
||||
temp->pData = new char[size];
|
||||
}
|
||||
catch (...) {
|
||||
if (!new_file) {
|
||||
CurrentMod.Remove(temp); // if this is a not a new file it is in the list of the CurrentMod
|
||||
}
|
||||
delete temp;
|
||||
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
|
||||
return RETURN_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
temp->pData[i] = buffer[i];
|
||||
}
|
||||
|
||||
temp->pData = dataPtr;
|
||||
temp->Size = size;
|
||||
temp->NumberOfTextures = 0;
|
||||
temp->Textures = nullptr;
|
||||
@@ -255,270 +180,9 @@ int uMod_TextureServer::AddFile(char* buffer, unsigned int size, MyTypeHash hash
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureServer::AddFile(wchar_t* file_name, MyTypeHash hash, bool force) // called from Mainloop
|
||||
// this functions does the same, but loads the file content from disk
|
||||
{
|
||||
Message("uMod_TextureServer::AddFile( %ls, %#lX, %d): %lu\n", file_name, hash, force, this);
|
||||
|
||||
TextureFileStruct* temp = nullptr;
|
||||
|
||||
int num = CurrentMod.GetNumber();
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (CurrentMod[i]->Hash == hash) {
|
||||
if (force) {
|
||||
temp = CurrentMod[i];
|
||||
break;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
}
|
||||
if (temp == nullptr) {
|
||||
num = OldMod.GetNumber();
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (OldMod[i]->Hash == hash) {
|
||||
temp = OldMod[i];
|
||||
OldMod.Remove(temp);
|
||||
CurrentMod.Add(temp);
|
||||
if (force) {
|
||||
break;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FILE* file;
|
||||
if (_wfopen_s(&file, file_name, L"rb") != 0) {
|
||||
Message("AddFile( ): file not found\n");
|
||||
return RETURN_FILE_NOT_LOADED;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
const unsigned int size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
bool new_file = true;
|
||||
if (temp != nullptr) {
|
||||
new_file = false;
|
||||
|
||||
delete[] temp->pData;
|
||||
|
||||
temp->pData = nullptr;
|
||||
}
|
||||
else {
|
||||
new_file = true;
|
||||
temp = new TextureFileStruct;
|
||||
temp->Reference = -1;
|
||||
}
|
||||
|
||||
try {
|
||||
temp->pData = new char[size];
|
||||
}
|
||||
catch (...) {
|
||||
if (!new_file) {
|
||||
CurrentMod.Remove(temp);
|
||||
}
|
||||
delete temp;
|
||||
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
|
||||
return RETURN_NO_MEMORY;
|
||||
}
|
||||
const int result = fread(temp->pData, 1, size, file);
|
||||
fclose(file);
|
||||
if (result != size) {
|
||||
delete[] temp->pData;
|
||||
if (!new_file) {
|
||||
CurrentMod.Remove(temp);
|
||||
}
|
||||
delete temp;
|
||||
return RETURN_FILE_NOT_LOADED;
|
||||
}
|
||||
|
||||
temp->Size = size;
|
||||
temp->NumberOfTextures = 0;
|
||||
temp->Textures = nullptr;
|
||||
temp->Hash = hash;
|
||||
|
||||
if (new_file) {
|
||||
temp->ForceReload = false;
|
||||
}
|
||||
else {
|
||||
temp->ForceReload = force;
|
||||
}
|
||||
|
||||
Message("End AddFile(%#lX)\n", hash);
|
||||
if (new_file) {
|
||||
return CurrentMod.Add(temp);
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureServer::RemoveFile(MyTypeHash hash) // called from Mainloop()
|
||||
{
|
||||
Message("RemoveFile( %lu): %lu\n", hash, this);
|
||||
|
||||
const int num = CurrentMod.GetNumber();
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (CurrentMod[i]->Hash == hash) {
|
||||
TextureFileStruct* temp = CurrentMod[i];
|
||||
CurrentMod.Remove(temp);
|
||||
return OldMod.Add(temp);
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SaveAllTextures(bool val) // called from Mainloop()
|
||||
{
|
||||
if (BoolSaveAllTextures == val) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
BoolSaveAllTextures = val;
|
||||
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SaveAllTextures(BoolSaveAllTextures);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SaveSingleTexture(bool val) // called from Mainloop()
|
||||
{
|
||||
if (BoolSaveSingleTexture == val) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
BoolSaveSingleTexture = val;
|
||||
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SaveSingleTexture(BoolSaveSingleTexture);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SetSaveDirectory(wchar_t* dir) // called from Mainloop()
|
||||
{
|
||||
Message("uMod_TextureServer::SetSaveDirectory( %ls): %lu\n", dir, this);
|
||||
int i = 0;
|
||||
for (i = 0; i < MAX_PATH && dir[i]; i++) {
|
||||
SavePath[i] = dir[i];
|
||||
}
|
||||
if (i == MAX_PATH) {
|
||||
SavePath[0] = 0;
|
||||
return RETURN_BAD_ARGUMENT;
|
||||
}
|
||||
SavePath[i] = 0;
|
||||
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SetSaveDirectory(SavePath);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SetKeyBack(int key) // called from Mainloop()
|
||||
{
|
||||
if (KeyBack == key || KeySave == key || KeyNext == key) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
KeyBack = key;
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SetKeyBack(key);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SetKeySave(int key) // called from Mainloop()
|
||||
{
|
||||
if (KeyBack == key || KeySave == key || KeyNext == key) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
KeySave = key;
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SetKeySave(key);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SetKeyNext(int key) // called from Mainloop()
|
||||
{
|
||||
if (KeyBack == key || KeySave == key || KeyNext == key) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
KeyNext = key;
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SetKeyNext(key);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SetFontColour(DWORD colour) // called from Mainloop()
|
||||
{
|
||||
if (colour == 0u) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
FontColour = colour;
|
||||
const DWORD r = (FontColour >> 16) & 0xFF;
|
||||
const DWORD g = (FontColour >> 8) & 0xFF;
|
||||
const DWORD b = (FontColour) & 0xFF;
|
||||
Message("uMod_TextureServer::SetFontColour( %u %u %u): %lu\n", r, g, b, this);
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SetFontColour(r, g, b);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::SetTextureColour(DWORD colour) // called from Mainloop()
|
||||
{
|
||||
if (colour == 0u) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_SERVER;
|
||||
return ret;
|
||||
}
|
||||
TextureColour = colour;
|
||||
const DWORD r = (TextureColour >> 16) & 0xFF;
|
||||
const DWORD g = (TextureColour >> 8) & 0xFF;
|
||||
const DWORD b = (TextureColour) & 0xFF;
|
||||
Message("uMod_TextureServer::SetTextureColour( %u %u %u): %lu\n", r, g, b, this);
|
||||
for (int i = 0; i < NumberOfClients; i++) {
|
||||
Clients[i]->SetTextureColour(r, g, b);
|
||||
}
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called from Mainloop(), send the update to all clients
|
||||
{
|
||||
Message("PropagateUpdate(%lu): %lu\n", client, this);
|
||||
if (const int ret = LockMutex()) {
|
||||
gl_ErrorState |= uMod_ERROR_TEXTURE;
|
||||
return ret;
|
||||
}
|
||||
Message("PropagateUpdate(%p): %p\n", client, this);
|
||||
if (client != nullptr) {
|
||||
TextureFileStruct* update;
|
||||
int number;
|
||||
@@ -537,18 +201,19 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr
|
||||
Clients[i]->AddUpdate(update, number);
|
||||
}
|
||||
}
|
||||
return UnlockMutex();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
#define cpy_file_struct( a, b) \
|
||||
{ \
|
||||
a.ForceReload = b.ForceReload; \
|
||||
a.pData = b.pData; \
|
||||
a.Size = b.Size; \
|
||||
a.NumberOfTextures = b.NumberOfTextures; \
|
||||
a.Reference = b.Reference; \
|
||||
a.Textures = b.Textures; \
|
||||
a.Hash = b.Hash; }
|
||||
void cpy_file_struct(TextureFileStruct& a,TextureFileStruct& b)
|
||||
{
|
||||
a.ForceReload = b.ForceReload;
|
||||
a.pData = b.pData;
|
||||
a.Size = b.Size;
|
||||
a.NumberOfTextures = b.NumberOfTextures;
|
||||
a.Reference = b.Reference;
|
||||
a.Textures = b.Textures;
|
||||
a.Hash = b.Hash;
|
||||
}
|
||||
|
||||
int TextureFileStruct_Compare(const void* elem1, const void* elem2)
|
||||
{
|
||||
@@ -566,7 +231,7 @@ int TextureFileStruct_Compare(const void* elem1, const void* elem2)
|
||||
int uMod_TextureServer::PrepareUpdate(TextureFileStruct** update, int* number) // called from the PropagateUpdate() and AddClient.
|
||||
// Prepare an update for one client. The allocated memory must deleted by the client.
|
||||
{
|
||||
Message("PrepareUpdate(%lu, %d): %lu\n", update, number, this);
|
||||
Message("PrepareUpdate(%p, %d): %p\n", update, number, this);
|
||||
|
||||
TextureFileStruct* temp = nullptr;
|
||||
const int num = CurrentMod.GetNumber();
|
||||
@@ -581,100 +246,64 @@ int uMod_TextureServer::PrepareUpdate(TextureFileStruct** update, int* number) /
|
||||
qsort(temp, num, sizeof(TextureFileStruct), TextureFileStruct_Compare);
|
||||
}
|
||||
|
||||
|
||||
*update = temp;
|
||||
*number = num;
|
||||
return RETURN_OK;
|
||||
}
|
||||
#undef cpy_file_struct
|
||||
|
||||
int uMod_TextureServer::LockMutex()
|
||||
void uMod_TextureServer::LoadModsFromFile(const char* source)
|
||||
{
|
||||
if ((gl_ErrorState & (uMod_ERROR_FATAL | uMod_ERROR_MUTEX))) {
|
||||
return RETURN_NO_MUTEX;
|
||||
}
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(Mutex, 100)) {
|
||||
return RETURN_MUTEX_LOCK; //waiting 100ms, to wait infinite pass INFINITE
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
Message("Initialize: searching in %s\n", source);
|
||||
|
||||
int uMod_TextureServer::UnlockMutex()
|
||||
{
|
||||
if (ReleaseMutex(Mutex) == 0) {
|
||||
return RETURN_MUTEX_UNLOCK;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
std::ifstream file(source);
|
||||
if (file.is_open()) {
|
||||
Message("Initialize: found modlist.txt. Reading\n");
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
Message("Initialize: loading file %s\n", line.c_str());
|
||||
|
||||
void uMod_TextureServer::LoadModsFromFile(char* source)
|
||||
{
|
||||
Message("MainLoop: searching in %s\n", source);
|
||||
// Attempt to open the file
|
||||
FILE* file = fopen(source, "r");
|
||||
if (file) {
|
||||
Message("MainLoop: found modlist.txt. Reading\n");
|
||||
// Read each line from the file
|
||||
char line[MAX_PATH];
|
||||
while (fgets(line, sizeof(line), file) != nullptr) {
|
||||
Message("MainLoop: loading file %s\n", line);
|
||||
for (auto i = 0; i < MAX_PATH; i++) {
|
||||
if (line[i] == '\n') {
|
||||
line[i] = 0;
|
||||
}
|
||||
}
|
||||
// Remove newline character
|
||||
line.erase(std::ranges::remove(line, '\n').begin(), line.end());
|
||||
|
||||
const auto file = new uMod_File(line);
|
||||
const auto result = file->GetContent();
|
||||
if (file->Textures.size() > 0) {
|
||||
if (!result) {
|
||||
Message("MainLoop: WARNING! GetContent returned failure, but some textures have been loaded for %s\n", line);
|
||||
}
|
||||
auto file_loader = gMod_FileLoader(line);
|
||||
const auto entries = file_loader.Load();
|
||||
if (!entries.empty()) {
|
||||
Message("Initialize: Texture count %zu %s\n", entries.size(), line.c_str());
|
||||
for (const auto& tpf_entry : entries) {
|
||||
loadedSize += tpf_entry.size;
|
||||
if (AddFile(static_cast<char*>(tpf_entry.data), static_cast<unsigned int>(tpf_entry.size), tpf_entry.crc_hash, false) == RETURN_EXISTS) {
|
||||
//Texture is already loaded, so we need to clear our data
|
||||
loadedSize -= tpf_entry.size;
|
||||
}
|
||||
|
||||
Message("MainLoop: Texture count %d %s\n", file->Textures.size(), line);
|
||||
for (auto& texture : file->Textures) {
|
||||
AddFile(texture.data.data(), texture.data.size(), texture.hash, true);
|
||||
Message("LoadModsFromFile: Loaded %d bytes", loadedSize);
|
||||
}
|
||||
|
||||
PropagateUpdate(nullptr);
|
||||
}
|
||||
else {
|
||||
Message("MainLoop: Failed to load any textures for %s\n", line);
|
||||
Message("Initialize: Failed to load any textures for %s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uMod_TextureServer::MainLoop() // run as a separated thread
|
||||
int uMod_TextureServer::Initialize()
|
||||
{
|
||||
Message("MainLoop: searching for modlist.txt\n");
|
||||
Message("Initialize: begin\n");
|
||||
Message("Initialize: searching for modlist.txt\n");
|
||||
char gwpath[MAX_PATH];
|
||||
GetModuleFileName(GetModuleHandle(nullptr), gwpath, MAX_PATH); //ask for name and path of this executable
|
||||
char* last_backslash = strrchr(gwpath, '\\');
|
||||
if (last_backslash != nullptr) {
|
||||
// Terminate the string at the last backslash to remove the executable name
|
||||
*last_backslash = '\0';
|
||||
const auto exe = std::filesystem::path(gwpath).parent_path();
|
||||
const auto dll = std::filesystem::path(UModName).parent_path();
|
||||
for (const auto& path : {exe, dll}) {
|
||||
const auto modlist = path / "modlist.txt";
|
||||
if (std::filesystem::exists(modlist)) {
|
||||
LoadModsFromFile(modlist.string().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
strcat(gwpath, "\\modlist.txt");
|
||||
LoadModsFromFile(gwpath);
|
||||
|
||||
char umodpath[MAX_PATH];
|
||||
strcpy(umodpath, UModName);
|
||||
|
||||
last_backslash = strrchr(umodpath, '\\');
|
||||
if (last_backslash != nullptr) {
|
||||
// Terminate the string at the last backslash to remove the executable name
|
||||
*last_backslash = '\0';
|
||||
}
|
||||
|
||||
strcat(umodpath, "\\modlist.txt");
|
||||
LoadModsFromFile(umodpath);
|
||||
|
||||
Message("MainLoop: begin\n");
|
||||
for (auto i = 0; i < 10; i++) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
Message("Initialize: end\n");
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
-4163
File diff suppressed because it is too large
Load Diff
-3152
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user