├── .clang-format
├── .git-blame-ignore-revs
├── .gitattributes
├── .github
└── workflows
│ ├── build.yml
│ └── linting.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CMakeLists.txt
├── bootstrap.bat
├── bootstrap.ps1
├── licenses
├── 7zip.txt
├── AntlrBuildTask.txt
├── BY-SA-v3.0.txt
├── Castle.txt
├── DXTex.txt
├── GNU-LGPL-v2.1.txt
├── GPL-v2.0.txt
├── GPL-v3.0.txt
├── LGPL-v3.0.txt
├── ValveFileVDF.txt
├── boost.txt
├── cpptoml.txt
├── fmt.txt
├── openssl.txt
├── python.txt
├── sip.txt
├── spdlog.txt
├── udis86.txt
└── zlib.txt
├── mob.ini
├── readme.md
├── src
├── CMakeLists.txt
├── cmd
│ ├── build.cpp
│ ├── cmake_config.cpp
│ ├── commands.cpp
│ ├── commands.h
│ ├── git.cpp
│ ├── list.cpp
│ ├── pch.h
│ ├── pr.cpp
│ ├── release.cpp
│ └── tx.cpp
├── core
│ ├── conf.cpp
│ ├── conf.h
│ ├── context.cpp
│ ├── context.h
│ ├── env.cpp
│ ├── env.h
│ ├── formatters.h
│ ├── ini.cpp
│ ├── ini.h
│ ├── op.cpp
│ ├── op.h
│ ├── paths.cpp
│ ├── paths.h
│ ├── pch.h
│ ├── pipe.cpp
│ ├── pipe.h
│ ├── process.cpp
│ └── process.h
├── main.cpp
├── net.cpp
├── net.h
├── pch.cpp
├── pch.h
├── tasks
│ ├── explorerpp.cpp
│ ├── installer.cpp
│ ├── licenses.cpp
│ ├── modorganizer.cpp
│ ├── pch.h
│ ├── stylesheets.cpp
│ ├── task.cpp
│ ├── task.h
│ ├── task_manager.cpp
│ ├── task_manager.h
│ ├── tasks.h
│ ├── translations.cpp
│ └── usvfs.cpp
├── tools
│ ├── cmake.cpp
│ ├── cmake.h
│ ├── downloader.cpp
│ ├── extractor.cpp
│ ├── git.cpp
│ ├── git.h
│ ├── msbuild.cpp
│ ├── msbuild.h
│ ├── pch.h
│ ├── process_runner.cpp
│ ├── tools.cpp
│ └── tools.h
├── utility.cpp
├── utility.h
└── utility
│ ├── algo.h
│ ├── assert.cpp
│ ├── assert.h
│ ├── enum.h
│ ├── fs.cpp
│ ├── fs.h
│ ├── io.cpp
│ ├── io.h
│ ├── pch.h
│ ├── string.cpp
│ ├── string.h
│ ├── threading.cpp
│ └── threading.h
└── third-party
├── bin
├── 7z.dll
├── 7z.exe
├── jom.exe
├── msys-2.0.dll
├── nasm.exe
├── nuget.exe
├── patch.exe
├── tx.exe
└── vswhere.exe
├── include
├── clipp.h
├── curl
│ ├── curl.h
│ ├── curlver.h
│ ├── easy.h
│ ├── mprintf.h
│ ├── multi.h
│ ├── stdcheaders.h
│ ├── system.h
│ ├── typecheck-gcc.h
│ └── urlapi.h
└── nlohmann
│ └── json.hpp
└── lib
├── libcurl-d.lib
├── libcurl.lib
├── zlib.lib
└── zlibd.lib
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | # We'll use defaults from the LLVM style, but with 4 columns indentation.
3 | BasedOnStyle: LLVM
4 | IndentWidth: 4
5 | ---
6 | Language: Cpp
7 | # Force pointers to the type for C++.
8 | DerivePointerAlignment: false
9 | PointerAlignment: Left
10 | AlignConsecutiveAssignments: true
11 | AllowShortFunctionsOnASingleLine: Inline
12 | AllowShortIfStatementsOnASingleLine: Never
13 | AllowShortLambdasOnASingleLine: Empty
14 | AlwaysBreakTemplateDeclarations: Yes
15 | AccessModifierOffset: -4
16 | AlignTrailingComments: true
17 | SpacesBeforeTrailingComments: 2
18 | NamespaceIndentation: All
19 | MaxEmptyLinesToKeep: 1
20 | BreakBeforeBraces: Stroustrup
21 | ColumnLimit: 88
22 | IncludeBlocks: Preserve
23 | IncludeCategories:
24 | - Regex: '^"pch.h"$'
25 | Priority: -1
26 | SortPriority: -1
27 |
--------------------------------------------------------------------------------
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | d0913d07d33929d7b753a3a09a0dac70e5befbc1
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | * text=auto
3 |
4 | # Explicitly declare text files you want to always be normalized and converted
5 | # to native line endings on checkout.
6 | *.cpp text eol=crlf
7 | *.h text eol=crlf
8 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build Mob
2 |
3 | on:
4 | push:
5 | branches: master
6 | pull_request:
7 | types: [opened, synchronize, reopened]
8 |
9 | jobs:
10 | build:
11 | runs-on: windows-2022
12 | steps:
13 | - uses: actions/checkout@v4
14 | - name: Build Mob
15 | shell: pwsh
16 | run: ./bootstrap.ps1 -Verbose
17 |
--------------------------------------------------------------------------------
/.github/workflows/linting.yml:
--------------------------------------------------------------------------------
1 | name: Lint Mob
2 |
3 | on:
4 | push:
5 | pull_request:
6 | types: [opened, synchronize, reopened]
7 |
8 | jobs:
9 | lint:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v3
13 | - name: Check format
14 | uses: ModOrganizer2/check-formatting-action@master
15 | with:
16 | check-path: "."
17 | exclude-regex: "third-party"
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # mob-specific files
2 | /build
3 | /vs/obj
4 | /vs/.vs
5 | /vs/*.user
6 | /mob.exe
7 | /mob.log
8 |
9 | # Files built by mob
10 | /*/build
11 | /*/downloads
12 | /*/install
13 | /*/releases
14 | /*/mob.ini
15 | /*/mob.log
16 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v5.0.0
4 | hooks:
5 | - id: trailing-whitespace
6 | exclude: '^(third-party|licenses)/.*$'
7 | - id: end-of-file-fixer
8 | exclude: '^(third-party|licenses)/.*$'
9 | - id: check-merge-conflict
10 | exclude: '^(third-party|licenses)/.*$'
11 | - id: check-case-conflict
12 | exclude: '^(third-party|licenses)/.*$'
13 | - repo: https://github.com/pre-commit/mirrors-clang-format
14 | rev: v19.1.5
15 | hooks:
16 | - id: clang-format
17 | 'types_or': [c++, c]
18 | exclude: '^third-party/.*$'
19 |
20 | ci:
21 | autofix_commit_msg: "[pre-commit.ci] Auto fixes from pre-commit.com hooks."
22 | autofix_prs: true
23 | autoupdate_commit_msg: "[pre-commit.ci] Pre-commit autoupdate."
24 | autoupdate_schedule: quarterly
25 | submodules: false
26 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16)
2 |
3 | project(mob)
4 | add_subdirectory(src)
5 |
6 | set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT mob)
7 |
--------------------------------------------------------------------------------
/bootstrap.bat:
--------------------------------------------------------------------------------
1 | @type bootstrap.ps1 | powershell -
2 |
--------------------------------------------------------------------------------
/bootstrap.ps1:
--------------------------------------------------------------------------------
1 | param(
2 | [switch]
3 | $Verbose,
4 | [ValidateSet("Debug", "RelWithDebInfo", "Release")]
5 | [string]
6 | $Config = "Release"
7 | )
8 |
9 | $root = $PSScriptRoot
10 | if (!$root) {
11 | $root = "."
12 | }
13 |
14 | $output = if ($Verbose) { "Out-Default" } else { "Out-Null" }
15 |
16 | cmake -B $root/build -G "Visual Studio 17 2022" $root | & $output
17 |
18 | $installationPath = & $root\third-party\bin\vswhere.exe -products * -nologo -prerelease -latest -property installationPath
19 | if (! $?) {
20 | Write-Error "vswhere returned $LastExitCode"
21 | exit $LastExitCode
22 | }
23 |
24 | if (! $installationPath) {
25 | Write-Error "Empty installation path"
26 | exit 1
27 | }
28 |
29 | $opts = ""
30 | $opts += " $root\build\mob.sln"
31 | $opts += " -m"
32 | $opts += " -p:Configuration=${Config}"
33 | $opts += " -noLogo"
34 | $opts += " -p:UseMultiToolTask=true"
35 | $opts += " -p:EnforceProcessCountAcrossBuilds=true"
36 |
37 | if (!$Verbose) {
38 | $opts += " -clp:ErrorsOnly;Verbosity=minimal"
39 | }
40 |
41 | $vsDevCmd = "$installationPath\Common7\Tools\VsDevCmd.bat"
42 | if (!(Test-Path "$vsDevCmd")) {
43 | Write-Error "VdDevCmd.bat not found at $vsDevCmd"
44 | exit 1
45 | }
46 |
47 | & "${env:COMSPEC}" /c "`"$vsDevCmd`" -no_logo -arch=amd64 -host_arch=amd64 && msbuild $opts"
48 |
49 | if (! $?) {
50 | Write-Error "Build failed"
51 | exit $LastExitCode
52 | }
53 |
54 | Copy-Item "$root\build\src\${Config}\mob.exe" "$root\mob.exe"
55 | Write-Output "run ``.\mob -d prefix/path build`` to start building"
56 |
--------------------------------------------------------------------------------
/licenses/7zip.txt:
--------------------------------------------------------------------------------
1 | 7-Zip source code
2 | ~~~~~~~~~~~~~~~~~
3 | License for use and distribution
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 |
6 | 7-Zip Copyright (C) 1999-2024 Igor Pavlov.
7 |
8 | The licenses for files are:
9 |
10 | - CPP/7zip/Compress/Rar* files: the "GNU LGPL" with "unRAR license restriction"
11 | - CPP/7zip/Compress/LzfseDecoder.cpp: the "BSD 3-clause License"
12 | - C/ZstdDec.c: the "BSD 3-clause License"
13 | - C/Xxh64.c: the "BSD 2-clause License"
14 | - Some files are "public domain" files, if "public domain" status is stated in source file.
15 | - the "GNU LGPL" for all other files. If there is no license information in
16 | some source file, that file is under the "GNU LGPL".
17 |
18 | The "GNU LGPL" with "unRAR license restriction" means that you must follow both
19 | "GNU LGPL" rules and "unRAR license restriction" rules.
20 |
21 |
22 |
23 |
24 | GNU LGPL information
25 | --------------------
26 |
27 | This library is free software; you can redistribute it and/or
28 | modify it under the terms of the GNU Lesser General Public
29 | License as published by the Free Software Foundation; either
30 | version 2.1 of the License, or (at your option) any later version.
31 |
32 | This library is distributed in the hope that it will be useful,
33 | but WITHOUT ANY WARRANTY; without even the implied warranty of
34 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 | Lesser General Public License for more details.
36 |
37 | You should have received a copy of the GNU Lesser General Public
38 | License along with this library; if not,
39 | you can get a copy of the GNU Lesser General Public License from
40 | http://www.gnu.org/
41 |
42 |
43 |
44 |
45 | BSD 3-clause License in 7-Zip code
46 | ----------------------------------
47 |
48 | The "BSD 3-clause License" is used for the following code in 7z.dll
49 | 1) LZFSE data decompression.
50 | CPP/7zip/Compress/LzfseDecoder.cpp.
51 | That code was derived from the code in the "LZFSE compression library" developed by Apple Inc,
52 | that also uses the "BSD 3-clause License".
53 | 2) ZSTD data decompression.
54 | C/ZstdDec.c
55 | that code was developed using original zstd decoder code as reference code.
56 | The original zstd decoder code was developed by Facebook Inc,
57 | that also uses the "BSD 3-clause License".
58 |
59 | Copyright (c) 2015-2016, Apple Inc. All rights reserved.
60 | Copyright (c) Facebook, Inc. All rights reserved.
61 | Copyright (c) 2023-2024 Igor Pavlov.
62 |
63 | Text of the "BSD 3-clause License"
64 | ----------------------------------
65 |
66 | Redistribution and use in source and binary forms, with or without modification,
67 | are permitted provided that the following conditions are met:
68 |
69 | 1. Redistributions of source code must retain the above copyright notice, this
70 | list of conditions and the following disclaimer.
71 |
72 | 2. Redistributions in binary form must reproduce the above copyright notice,
73 | this list of conditions and the following disclaimer in the documentation
74 | and/or other materials provided with the distribution.
75 |
76 | 3. Neither the name of the copyright holder nor the names of its contributors may
77 | be used to endorse or promote products derived from this software without
78 | specific prior written permission.
79 |
80 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
81 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
82 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
83 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
84 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
85 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
86 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
87 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90 |
91 | ---
92 |
93 |
94 |
95 |
96 | BSD 2-clause License in 7-Zip code
97 | ----------------------------------
98 |
99 | The "BSD 2-clause License" is used for the XXH64 code in 7-Zip.
100 | C/Xxh64.c
101 |
102 | XXH64 code in 7-Zip was derived from the original XXH64 code developed by Yann Collet.
103 |
104 | Copyright (c) 2012-2021 Yann Collet.
105 | Copyright (c) 2023-2024 Igor Pavlov.
106 |
107 | Text of the "BSD 2-clause License"
108 | ----------------------------------
109 |
110 | Redistribution and use in source and binary forms, with or without modification,
111 | are permitted provided that the following conditions are met:
112 |
113 | 1. Redistributions of source code must retain the above copyright notice, this
114 | list of conditions and the following disclaimer.
115 |
116 | 2. Redistributions in binary form must reproduce the above copyright notice,
117 | this list of conditions and the following disclaimer in the documentation
118 | and/or other materials provided with the distribution.
119 |
120 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
121 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
124 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
127 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130 |
131 | ---
132 |
133 |
134 |
135 |
136 | unRAR license restriction
137 | -------------------------
138 |
139 | The decompression engine for RAR archives was developed using source
140 | code of unRAR program.
141 | All copyrights to original unRAR code are owned by Alexander Roshal.
142 |
143 | The license for original unRAR code has the following restriction:
144 |
145 | The unRAR sources cannot be used to re-create the RAR compression algorithm,
146 | which is proprietary. Distribution of modified unRAR sources in separate form
147 | or as a part of other software is permitted, provided that it is clearly
148 | stated in the documentation and source comments that the code may
149 | not be used to develop a RAR (WinRAR) compatible archiver.
150 |
151 | --
152 |
--------------------------------------------------------------------------------
/licenses/AntlrBuildTask.txt:
--------------------------------------------------------------------------------
1 | [The "BSD license"]
2 | Copyright (c) 2011 Terence Parr
3 | C# Port (c) 2011 Sam Harwell, Tunnel Vision Laboratories, LLC
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions
8 | are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | 2. Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | 3. The name of the author may not be used to endorse or promote products
16 | derived from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/licenses/Castle.txt:
--------------------------------------------------------------------------------
1 | Copyright 2004-2014 Castle Project - http://www.castleproject.org/
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
15 |
--------------------------------------------------------------------------------
/licenses/DXTex.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011-2020 Microsoft Corp
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this
6 | software and associated documentation files (the "Software"), to deal in the Software
7 | without restriction, including without limitation the rights to use, copy, modify,
8 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all copies
13 | or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/licenses/LGPL-v3.0.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/licenses/ValveFileVDF.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Matthias Moeller 2016 m_moeller@live.de
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/licenses/boost.txt:
--------------------------------------------------------------------------------
1 | Boost Software License - Version 1.0 - August 17th, 2003
2 |
3 | Permission is hereby granted, free of charge, to any person or organization
4 | obtaining a copy of the software and accompanying documentation covered by
5 | this license (the "Software") to use, reproduce, display, distribute,
6 | execute, and transmit the Software, and to prepare derivative works of the
7 | Software, and to permit third-parties to whom the Software is furnished to
8 | do so, all subject to the following:
9 |
10 | The copyright notices in the Software and this entire statement, including
11 | the above license grant, this restriction and the following disclaimer,
12 | must be included in all copies of the Software, in whole or in part, and
13 | all derivative works of the Software, unless such copies or derivative
14 | works are solely in the form of machine-executable object code generated by
15 | a source language processor.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/licenses/cpptoml.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Chase Geigle
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/licenses/fmt.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | --- Optional exception to the license ---
23 |
24 | As an exception, if, as a result of your compiling your source code, portions
25 | of this Software are embedded into a machine-executable object form of such
26 | source code, you may redistribute such embedded portions in such object form
27 | without including the above copyright and permission notices.
28 |
--------------------------------------------------------------------------------
/licenses/sip.txt:
--------------------------------------------------------------------------------
1 | Copyright 2024 Phil Thompson
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 |
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/licenses/spdlog.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Gabi Melman.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 | -- NOTE: Third party dependency used by this software --
24 | This software depends on the fmt lib (MIT License),
25 | and users must comply to its license: https://raw.githubusercontent.com/fmtlib/fmt/master/LICENSE
26 |
27 |
--------------------------------------------------------------------------------
/licenses/udis86.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2002-2012, Vivek Thampi
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/licenses/zlib.txt:
--------------------------------------------------------------------------------
1 | Copyright notice:
2 |
3 | (C) 1995-2022 Jean-loup Gailly and Mark Adler
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any damages
7 | arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any purpose,
10 | including commercial applications, and to alter it and redistribute it
11 | freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must not
14 | claim that you wrote the original software. If you use this software
15 | in a product, an acknowledgment in the product documentation would be
16 | appreciated but is not required.
17 | 2. Altered source versions must be plainly marked as such, and must not be
18 | misrepresented as being the original software.
19 | 3. This notice may not be removed or altered from any source distribution.
20 |
21 | Jean-loup Gailly Mark Adler
22 | jloup@gzip.org madler@alumni.caltech.edu
23 |
--------------------------------------------------------------------------------
/mob.ini:
--------------------------------------------------------------------------------
1 | [global]
2 | dry = false
3 | redownload = false
4 | reextract = false
5 | reconfigure = false
6 | rebuild = false
7 | clean_task = true
8 | fetch_task = true
9 | build_task = true
10 | output_log_level = 3
11 | file_log_level = 5
12 | log_file = mob.log
13 | ignore_uncommitted = false
14 | github_key =
15 |
16 | [cmake]
17 | install_message = never
18 | host =
19 |
20 | [aliases]
21 | super = cmake_common modorganizer* githubpp
22 | plugins = check_fnis bsapacker bsa_extractor diagnose_basic installer_* plugin_python preview_base preview_bsa tool_* game_*
23 |
24 | [task]
25 | enabled = true
26 | mo_org = ModOrganizer2
27 | mo_branch = master
28 | mo_fallback =
29 | no_pull = false
30 | ignore_ts = false
31 | revert_ts = false
32 | configuration = RelWithDebInfo
33 |
34 | git_url_prefix = https://github.com/
35 | git_shallow = true
36 | git_username =
37 | git_email =
38 |
39 | set_origin_remote = false
40 | remote_org =
41 | remote_key =
42 | remote_no_push_upstream = false
43 | remote_push_default_origin = false
44 |
45 | [super:task]
46 | git_shallow = false
47 |
48 | [usvfs:task]
49 | git_shallow = false
50 | configuration = Release
51 |
52 | [installer:task]
53 | enabled = false
54 | git_shallow = false
55 |
56 | [translations:task]
57 | enabled = false
58 |
59 | [tools]
60 | sevenz = 7z.exe
61 | jom = jom.exe
62 | patch = patch.exe
63 | git = git.exe
64 | cmake = cmake.exe
65 | perl = perl.exe
66 | devenv = devenv.exe
67 | msbuild = msbuild.exe
68 | nmake = nmake.exe
69 | nuget = nuget.exe
70 | vswhere = vswhere.exe
71 | nasm = nasm.exe
72 | tx = tx.exe
73 | lrelease = lrelease.exe
74 | iscc = ISCC.exe
75 | vcvars =
76 |
77 | [transifex]
78 | enabled = true
79 | key =
80 | team = mod-organizer-2-team
81 | project = mod-organizer-2
82 | url = https://app.transifex.com
83 | minimum = 60
84 | force = false
85 | configure = true
86 | pull = true
87 |
88 | [versions]
89 | vs = 17
90 | vs_year = 2022
91 | vs_toolset = 14.3
92 | sdk = 10.0.26100.0
93 | pyqt = 6.7.1
94 | qt = 6.7.3
95 | qt_vs = 2022
96 | usvfs = master
97 | explorerpp = 1.4.0
98 | ss_paper_lad_6788 = 7.2
99 | ss_paper_automata_6788 = 3.2
100 | ss_paper_mono_6788 = 3.2
101 | ss_dark_mode_1809_6788 = 3.0
102 | ss_morrowind_trosski = 1.1
103 | ss_skyrim_trosski = v1.1
104 | ss_starfield_trosski = V1.11
105 | ss_fallout3_trosski = v1.11
106 | ss_fallout4_trosski = v1.11
107 |
108 | [paths]
109 | third_party =
110 | prefix =
111 | cache =
112 | licenses =
113 | build =
114 | install =
115 | install_bin =
116 | install_installer =
117 | install_libs =
118 | install_pdbs =
119 | install_dlls =
120 | install_plugins =
121 | install_stylesheets =
122 | install_licenses =
123 | install_translations =
124 | vs =
125 | vcpkg =
126 | qt_install =
127 | qt_bin =
128 | qt_translations =
129 | pf_x86 =
130 | pf_x64 =
131 | temp_dir =
132 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16)
2 |
3 | file(GLOB_RECURSE source_files *.cpp)
4 | file(GLOB_RECURSE header_files *.h)
5 |
6 | add_executable(mob ${source_files} ${header_files})
7 | set_target_properties(mob PROPERTIES CXX_STANDARD 20)
8 |
9 | target_compile_definitions(mob PUBLIC NOMINMAX)
10 | target_compile_options(mob PUBLIC "/MT")
11 | target_include_directories(mob PUBLIC ${CMAKE_SOURCE_DIR}/third-party/include)
12 | target_link_libraries(mob PUBLIC
13 | wsock32 ws2_32 crypt32 wldap32 dbghelp shlwapi version
14 | optimized ${CMAKE_SOURCE_DIR}/third-party/lib/libcurl.lib
15 | debug ${CMAKE_SOURCE_DIR}/third-party/lib/libcurl-d.lib
16 | optimized ${CMAKE_SOURCE_DIR}/third-party/lib/zlib.lib
17 | debug ${CMAKE_SOURCE_DIR}/third-party/lib/zlibd.lib)
18 |
19 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}
20 | PREFIX src
21 | FILES ${source_files} ${header_files})
22 | set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT mob)
23 |
--------------------------------------------------------------------------------
/src/cmd/build.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "../core/conf.h"
3 | #include "../core/context.h"
4 | #include "../core/ini.h"
5 | #include "../core/op.h"
6 | #include "../tasks/task_manager.h"
7 | #include "commands.h"
8 |
9 | namespace mob {
10 |
11 | build_command::build_command() : command(requires_options | handle_sigint) {}
12 |
13 | command::meta_t build_command::meta() const
14 | {
15 | return {"build", "builds tasks"};
16 | }
17 |
18 | clipp::group build_command::do_group()
19 | {
20 | return (clipp::command("build")).set(picked_),
21 |
22 | (clipp::option("-h", "--help") >> help_) % ("shows this message"),
23 |
24 | (clipp::option("-g", "--redownload") >> redownload_) %
25 | "redownloads archives, see --reextract",
26 |
27 | (clipp::option("-e", "--reextract") >> reextract_) %
28 | "deletes source directories and re-extracts archives",
29 |
30 | (clipp::option("-c", "--reconfigure") >> reconfigure_) %
31 | "reconfigures the task by running cmake, configure scripts, "
32 | "etc.; some tasks might have to delete the whole source "
33 | "directory",
34 |
35 | (clipp::option("-b", "--rebuild") >> rebuild_) %
36 | "cleans and rebuilds projects; some tasks might have to "
37 | "delete the whole source directory",
38 |
39 | (clipp::option("-n", "--new") >> new_) %
40 | "deletes everything and starts from scratch",
41 |
42 | (clipp::option("--clean-task").call([&] {
43 | clean_ = true;
44 | }) |
45 | clipp::option("--no-clean-task").call([&] {
46 | clean_ = false;
47 | })) %
48 | "sets whether tasks are cleaned",
49 |
50 | (clipp::option("--fetch-task").call([&] {
51 | fetch_ = true;
52 | }) |
53 | clipp::option("--no-fetch-task").call([&] {
54 | fetch_ = false;
55 | })) %
56 | "sets whether tasks are fetched",
57 |
58 | (clipp::option("--build-task").call([&] {
59 | build_ = true;
60 | }) |
61 | clipp::option("--no-build-task").call([&] {
62 | build_ = false;
63 | })) %
64 | "sets whether tasks are built",
65 |
66 | (clipp::option("--pull").call([&] {
67 | nopull_ = false;
68 | }) |
69 | clipp::option("--no-pull").call([&] {
70 | nopull_ = true;
71 | })) %
72 | "whether to pull repos that are already cloned; global override",
73 |
74 | (clipp::option("--revert-ts").call([&] {
75 | revert_ts_ = true;
76 | }) |
77 | clipp::option("--no-revert-ts").call([&] {
78 | revert_ts_ = false;
79 | })) %
80 | "whether to revert all the .ts files in a repo before pulling to "
81 | "avoid merge errors; global override",
82 |
83 | (clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_) %
84 | "when --reextract is given, directories controlled by git will "
85 | "be deleted even if they contain uncommitted changes",
86 |
87 | (clipp::option("--keep-msbuild") >> keep_msbuild_) %
88 | "don't terminate msbuild.exe instances after building",
89 |
90 | (clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
91 | "tasks to run; specify 'super' to only build modorganizer "
92 | "projects";
93 | }
94 |
95 | void build_command::convert_cl_to_conf()
96 | {
97 | command::convert_cl_to_conf();
98 |
99 | if (redownload_ || new_)
100 | common.options.push_back("global/redownload=true");
101 |
102 | if (reextract_ || new_)
103 | common.options.push_back("global/reextract=true");
104 |
105 | if (reconfigure_ || new_)
106 | common.options.push_back("global/reconfigure=true");
107 |
108 | if (rebuild_ || new_)
109 | common.options.push_back("global/rebuild=true");
110 |
111 | if (ignore_uncommitted_)
112 | common.options.push_back("global/ignore_uncommitted=true");
113 |
114 | if (clean_) {
115 | if (*clean_)
116 | common.options.push_back("global/clean_task=true");
117 | else
118 | common.options.push_back("global/clean_task=false");
119 | }
120 |
121 | if (fetch_) {
122 | if (*fetch_)
123 | common.options.push_back("global/fetch_task=true");
124 | else
125 | common.options.push_back("global/fetch_task=false");
126 | }
127 |
128 | if (build_) {
129 | if (*build_)
130 | common.options.push_back("global/build_task=true");
131 | else
132 | common.options.push_back("global/build_task=false");
133 | }
134 |
135 | if (nopull_) {
136 | if (*nopull_)
137 | common.options.push_back("_override:task/no_pull=true");
138 | else
139 | common.options.push_back("_override:task/no_pull=false");
140 | }
141 |
142 | if (revert_ts_) {
143 | if (*revert_ts_)
144 | common.options.push_back("_override:task/revert_ts=true");
145 | else
146 | common.options.push_back("_override:task/revert_ts=false");
147 | }
148 |
149 | if (!tasks_.empty())
150 | set_task_enabled_flags(tasks_);
151 | }
152 |
153 | int build_command::do_run()
154 | {
155 | try {
156 | create_prefix_ini();
157 |
158 | task_manager::instance().run_all();
159 |
160 | if (!keep_msbuild_)
161 | terminate_msbuild();
162 |
163 | mob::gcx().info(mob::context::generic, "mob done");
164 | return 0;
165 | }
166 | catch (bailed&) {
167 | gcx().error(context::generic, "bailing out");
168 | return 1;
169 | }
170 | }
171 |
172 | void build_command::create_prefix_ini()
173 | {
174 | const auto prefix = conf().path().prefix();
175 |
176 | // creating prefix
177 | if (!exists(prefix))
178 | op::create_directories(gcx(), prefix);
179 |
180 | const auto ini = prefix / default_ini_filename();
181 | if (!exists(ini)) {
182 | std::ofstream(ini) << "[paths]\n"
183 | << "prefix = .\n";
184 | }
185 | }
186 |
187 | void build_command::terminate_msbuild()
188 | {
189 | if (conf().global().dry())
190 | return;
191 |
192 | system("taskkill /im msbuild.exe /f > NUL 2>&1");
193 | }
194 |
195 | } // namespace mob
196 |
--------------------------------------------------------------------------------
/src/cmd/cmake_config.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
3 | #include "../core/conf.h"
4 | #include "../tasks/tasks.h"
5 |
6 | #include "commands.h"
7 |
8 | namespace mob {
9 |
10 | cmake_config_command::cmake_config_command() : command(requires_options) {}
11 |
12 | command::meta_t cmake_config_command::meta() const
13 | {
14 | return {"cmake-config", "print CMake configuration variables"};
15 | }
16 |
17 | clipp::group cmake_config_command::do_group()
18 | {
19 | return clipp::group(
20 | clipp::command("cmake-config").set(picked_),
21 | (clipp::option("-h", "--help") >> help_) % ("shows this message"),
22 | clipp::command("prefix-path").set(var_, variable::prefix_path) |
23 | clipp::command("install-prefix").set(var_, variable::install_prefix));
24 | }
25 |
26 | std::string cmake_config_command::do_doc()
27 | {
28 | return "Print CMake variables to be used when configuring projects.\n";
29 | }
30 |
31 | int cmake_config_command::do_run()
32 | {
33 | switch (var_) {
34 | case variable::prefix_path:
35 | u8cout << tasks::modorganizer::cmake_prefix_path();
36 | break;
37 | case variable::install_prefix:
38 | u8cout << conf().path().install().string();
39 | break;
40 | }
41 | return 0;
42 | }
43 | } // namespace mob
44 |
--------------------------------------------------------------------------------
/src/cmd/git.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "../tasks/tasks.h"
3 | #include "../tools/tools.h"
4 | #include "commands.h"
5 |
6 | namespace mob {
7 |
8 | git_command::git_command() : command(requires_options) {}
9 |
10 | command::meta_t git_command::meta() const
11 | {
12 | return {"git", "manages the git repos"};
13 | }
14 |
15 | clipp::group git_command::do_group()
16 | {
17 | return clipp::group(
18 | clipp::command("git").set(picked_),
19 |
20 | (clipp::option("-h", "--help") >> help_) % ("shows this message"),
21 |
22 | "set-remotes" %
23 | (clipp::command("set-remotes").set(mode_, modes::set_remotes),
24 | (clipp::required("-u", "--username") &
25 | clipp::value("USERNAME") >> username_) %
26 | "git username",
27 |
28 | (clipp::required("-e", "--email") &
29 | clipp::value("EMAIL") >> email_) %
30 | "git email",
31 |
32 | (clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
33 | "path to putty key",
34 |
35 | (clipp::option("-s", "--no-push").set(nopush_) %
36 | "disables pushing to 'upstream' by changing the push url "
37 | "to 'nopushurl' to avoid accidental pushes"),
38 |
39 | (clipp::option("-p", "--push-origin").set(push_default_) %
40 | "sets the new 'origin' remote as the default push target"),
41 |
42 | (clipp::opt_value("path") >> path_) % "only use this repo")
43 |
44 | |
45 |
46 | "add-remote" %
47 | (clipp::command("add-remote").set(mode_, modes::add_remote),
48 | (clipp::required("-n", "--name") &
49 | clipp::value("NAME") >> remote_) %
50 | "name of new remote",
51 |
52 | (clipp::required("-u", "--username") &
53 | clipp::value("USERNAME") >> username_) %
54 | "git username",
55 |
56 | (clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
57 | "path to putty key",
58 |
59 | (clipp::option("-p", "--push-origin").set(push_default_) %
60 | "sets this new remote as the default push target"),
61 |
62 | (clipp::opt_value("path") >> path_) % "only use this repo")
63 |
64 | |
65 |
66 | "ignore-ts" % (clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
67 | (clipp::command("on").set(tson_, true) |
68 | clipp::command("off").set(tson_, false)))
69 |
70 | |
71 |
72 | "branches" % (clipp::command("branches").set(mode_, modes::branches),
73 | clipp::option("-a", "--all").set(all_branches_) %
74 | "shows all branches, including those on master"));
75 | }
76 |
77 | int git_command::do_run()
78 | {
79 | switch (mode_) {
80 | case modes::set_remotes: {
81 | do_set_remotes();
82 | break;
83 | }
84 |
85 | case modes::add_remote: {
86 | do_add_remote();
87 | break;
88 | }
89 |
90 | case modes::ignore_ts: {
91 | do_ignore_ts();
92 | break;
93 | }
94 |
95 | case modes::branches: {
96 | do_branches();
97 | break;
98 | }
99 |
100 | case modes::none:
101 | default:
102 | u8cerr << "bad git mode " << static_cast(mode_) << "\n";
103 | throw bailed();
104 | }
105 |
106 | return 0;
107 | }
108 |
109 | std::string git_command::do_doc()
110 | {
111 | return "All the commands will go through all modorganizer repos, plus usvfs\n"
112 | "and NCC.\n"
113 | "\n"
114 | "Commands:\n"
115 | "set-remotes\n"
116 | " For each repo, this first sets the username and email. Then, it\n"
117 | " will rename the remote 'origin' to 'upstream' and create a new\n"
118 | " remote 'origin' with the given information. If the remote\n"
119 | " 'upstream' already exists in a repo, nothing happens.\n"
120 | "\n"
121 | "add-remote\n"
122 | " For each repo, adds a new remote with the given information. If a\n"
123 | " remote with the same name already exists, nothing happens.\n"
124 | "\n"
125 | "ignore-ts\n"
126 | " Toggles the --assume-changed status of all .ts files in all repos.\n"
127 | "\n"
128 | "branches\n"
129 | " Lists all git repos that are not on master. With -a, show all \n"
130 | " repos and their current branch.";
131 | }
132 |
133 | void git_command::do_set_remotes()
134 | {
135 | if (path_.empty()) {
136 | const auto repos = get_repos();
137 |
138 | for (auto&& r : repos)
139 | do_set_remotes(r);
140 | }
141 | else {
142 | do_set_remotes(path_);
143 | }
144 | }
145 |
146 | void git_command::do_set_remotes(const fs::path& r)
147 | {
148 | u8cout << "setting up " << path_to_utf8(r.filename()) << "\n";
149 |
150 | git_wrap(r).set_credentials(username_, email_);
151 |
152 | git_wrap(r).set_origin_and_upstream_remotes(username_, key_, nopush_,
153 | push_default_);
154 | }
155 |
156 | void git_command::do_add_remote()
157 | {
158 | u8cout << "adding remote '" << remote_ << "' "
159 | << "from '" << username_ << "' to repos\n";
160 |
161 | if (path_.empty()) {
162 | const auto repos = get_repos();
163 |
164 | for (auto&& r : repos)
165 | do_add_remote(r);
166 | }
167 | else {
168 | do_add_remote(path_);
169 | }
170 | }
171 |
172 | void git_command::do_add_remote(const fs::path& r)
173 | {
174 | u8cout << path_to_utf8(r.filename()) << "\n";
175 | git_wrap(r).add_remote(remote_, username_, key_, push_default_);
176 | }
177 |
178 | void git_command::do_ignore_ts()
179 | {
180 | if (tson_)
181 | u8cout << "ignoring .ts files\n";
182 | else
183 | u8cout << "un-ignoring .ts files\n";
184 |
185 | if (path_.empty()) {
186 | const auto repos = get_repos();
187 |
188 | for (auto&& r : repos)
189 | do_ignore_ts(r);
190 | }
191 | else {
192 | do_ignore_ts(path_);
193 | }
194 | }
195 |
196 | void git_command::do_ignore_ts(const fs::path& r)
197 | {
198 | u8cout << path_to_utf8(r.filename()) << "\n";
199 | git_wrap(r).ignore_ts(tson_);
200 | }
201 |
202 | void git_command::do_branches()
203 | {
204 | std::vector> v;
205 |
206 | for (auto&& r : get_repos()) {
207 | const auto b = git_wrap(r).current_branch();
208 | if (b == "master" && !all_branches_)
209 | continue;
210 |
211 | if (b.empty())
212 | v.push_back({r.filename().string(), "detached head"});
213 | else
214 | v.push_back({r.filename().string(), b});
215 | }
216 |
217 | u8cout << table(v, 0, 3) << "\n";
218 | }
219 |
220 | std::vector git_command::get_repos() const
221 | {
222 | std::vector v;
223 |
224 | // usvfs
225 | if (fs::exists(tasks::usvfs::source_path()))
226 | v.push_back(tasks::usvfs::source_path());
227 |
228 | const auto super = tasks::modorganizer::super_path();
229 |
230 | // all directories in super except for those starting with a dot
231 | if (fs::exists(super)) {
232 | for (auto e : fs::directory_iterator(super)) {
233 | if (!e.is_directory())
234 | continue;
235 |
236 | const auto p = e.path();
237 | if (path_to_utf8(p.filename()).starts_with("."))
238 | continue;
239 |
240 | v.push_back(p);
241 | }
242 | }
243 |
244 | return v;
245 | }
246 |
247 | } // namespace mob
248 |
--------------------------------------------------------------------------------
/src/cmd/list.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "../tasks/task.h"
3 | #include "../tasks/task_manager.h"
4 | #include "../utility/io.h"
5 | #include "commands.h"
6 |
7 | namespace mob {
8 |
9 | command::meta_t list_command::meta() const
10 | {
11 | return {"list", "lists available tasks"};
12 | }
13 |
14 | clipp::group list_command::do_group()
15 | {
16 | return clipp::group(
17 | clipp::command("list").set(picked_),
18 |
19 | (clipp::option("-h", "--help") >> help_) % "shows this message",
20 |
21 | (clipp::option("-a", "--all") >> all_) %
22 | "shows all the tasks, including pseudo parallel tasks",
23 |
24 | (clipp::option("-i", "--aliases") >> aliases_) % "shows only aliases",
25 |
26 | (clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
27 | "with -a; when given, acts like the tasks given to `build` and "
28 | "shows only the tasks that would run");
29 | }
30 |
31 | int list_command::do_run()
32 | {
33 | auto& tm = task_manager::instance();
34 |
35 | if (aliases_) {
36 | load_options();
37 | dump_aliases();
38 | }
39 | else {
40 | if (all_) {
41 | if (!tasks_.empty())
42 | set_task_enabled_flags(tasks_);
43 |
44 | load_options();
45 | dump(tm.top_level(), 0);
46 |
47 | u8cout << "\n\naliases:\n";
48 | dump_aliases();
49 | }
50 | else {
51 | for (auto&& t : tm.all())
52 | u8cout << " - " << join(t->names(), ", ") << "\n";
53 | }
54 | }
55 |
56 | return 0;
57 | }
58 |
59 | void list_command::dump(const std::vector& v, std::size_t indent) const
60 | {
61 | for (auto&& t : v) {
62 | if (!t->enabled())
63 | continue;
64 |
65 | u8cout << std::string(indent * 4, ' ') << " - " << join(t->names(), ",")
66 | << "\n";
67 |
68 | if (auto* pt = dynamic_cast(t))
69 | dump(pt->children(), indent + 1);
70 | }
71 | }
72 |
73 | void list_command::dump_aliases() const
74 | {
75 | const auto v = task_manager::instance().aliases();
76 | if (v.empty())
77 | return;
78 |
79 | for (auto&& [k, patterns] : v)
80 | u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
81 | }
82 |
83 | } // namespace mob
84 |
--------------------------------------------------------------------------------
/src/cmd/pch.h:
--------------------------------------------------------------------------------
1 | // for intellisense
2 | #include "../pch.h"
3 |
--------------------------------------------------------------------------------
/src/cmd/tx.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "../core/conf.h"
3 | #include "../core/context.h"
4 | #include "../core/env.h"
5 | #include "../net.h"
6 | #include "../tasks/tasks.h"
7 | #include "../utility.h"
8 | #include "commands.h"
9 |
10 | namespace mob {
11 |
12 | tx_command::tx_command() : command(requires_options) {}
13 |
14 | command::meta_t tx_command::meta() const
15 | {
16 | return {"tx", "manages transifex translations"};
17 | }
18 |
19 | clipp::group tx_command::do_group()
20 | {
21 | return clipp::group(
22 | clipp::command("tx").set(picked_),
23 |
24 | (clipp::option("-h", "--help") >> help_) % ("shows this message"),
25 |
26 | "get" % (clipp::command("get").set(mode_, modes::get),
27 | (clipp::option("-k", "--key") & clipp::value("APIKEY") >> key_) %
28 | "API key",
29 |
30 | (clipp::option("-t", "--team") & clipp::value("TEAM") >> team_) %
31 | "team name",
32 |
33 | (clipp::option("-p", "--project") &
34 | clipp::value("PROJECT") >> project_) %
35 | "project name",
36 |
37 | (clipp::option("-u", "--url") & clipp::value("URL") >> url_) %
38 | "project URL",
39 |
40 | (clipp::option("-m", "--minimum") &
41 | clipp::value("PERCENT").set(min_)) %
42 | "minimum translation threshold to download [0-100]",
43 |
44 | (clipp::option("-f", "--force").call([&] {
45 | force_ = true;
46 | })) %
47 | "don't check timestamps, re-download all translation files",
48 |
49 | (clipp::value("path") >> path_) %
50 | "path that will contain the .tx directory")
51 |
52 | |
53 |
54 | "build" % (clipp::command("build").set(mode_, modes::build),
55 |
56 | (clipp::value("source") >> path_) %
57 | "path that contains the translation directories",
58 |
59 | (clipp::value("destination") >> dest_) %
60 | "path that will contain the .qm files"));
61 | }
62 |
63 | void tx_command::convert_cl_to_conf()
64 | {
65 | command::convert_cl_to_conf();
66 |
67 | if (!key_.empty())
68 | common.options.push_back("transifex/key=" + key_);
69 |
70 | if (!team_.empty())
71 | common.options.push_back("transifex/team=" + team_);
72 |
73 | if (!project_.empty())
74 | common.options.push_back("transifex/project=" + project_);
75 |
76 | if (!url_.empty())
77 | common.options.push_back("transifex/url=" + url_);
78 |
79 | if (min_ >= 0)
80 | common.options.push_back("transifex/minimum=" + std::to_string(min_));
81 |
82 | if (force_)
83 | common.options.push_back("transifex/force=" + std::to_string(*force_));
84 | }
85 |
86 | int tx_command::do_run()
87 | {
88 | switch (mode_) {
89 | case modes::get:
90 | do_get();
91 | break;
92 |
93 | case modes::build:
94 | do_build();
95 | break;
96 |
97 | case modes::none:
98 | default:
99 | u8cerr << "bad tx mode " << static_cast(mode_) << "\n";
100 | throw bailed();
101 | }
102 |
103 | return 0;
104 | }
105 |
106 | std::string tx_command::do_doc()
107 | {
108 | return "Some values will be taken from the INI file if not specified.\n"
109 | "\n"
110 | "Commands:\n"
111 | "get\n"
112 | " Initializes a Transifex project in the given directory if\n"
113 | " necessary and pulls all the translation files.\n"
114 | "\n"
115 | "build\n"
116 | " Builds all .qm files. The path can either be the transifex\n"
117 | " project (where .tx is) or the `translations` directory (where the\n"
118 | " individual translation directories are).";
119 | }
120 |
121 | void tx_command::do_get()
122 | {
123 | const url u = conf().transifex().get("url") + "/" +
124 | conf().transifex().get("team") + "/" +
125 | conf().transifex().get("project");
126 |
127 | const std::string key = conf().transifex().get("key");
128 |
129 | if (key.empty() && !this_env::get_opt("TX_TOKEN")) {
130 | u8cout << "(no key was in the INI, --key wasn't given and TX_TOKEN env\n"
131 | "variable doesn't exist, this will probably fail)\n\n";
132 | }
133 |
134 | // copy the global context, the tools will modify it
135 | context cxcopy = gcx();
136 |
137 | u8cout << "initializing\n";
138 | transifex(transifex::init).root(path_).run(cxcopy);
139 |
140 | u8cout << "configuring\n";
141 | transifex(transifex::config)
142 | .stdout_level(context::level::info)
143 | .root(path_)
144 | .api_key(key)
145 | .url(u)
146 | .run(cxcopy);
147 |
148 | u8cout << "pulling\n";
149 | transifex(transifex::pull)
150 | .stdout_level(context::level::info)
151 | .root(path_)
152 | .api_key(key)
153 | .minimum(conf().transifex().get("minimum"))
154 | .force(conf().transifex().get("force"))
155 | .run(cxcopy);
156 | }
157 |
158 | void tx_command::do_build()
159 | {
160 | fs::path root = path_;
161 | if (fs::exists(root / ".tx") && fs::exists(root / "translations"))
162 | root = root / "translations";
163 |
164 | tasks::translations::projects ps(root);
165 |
166 | fs::path dest = dest_;
167 | op::create_directories(gcx(), dest, op::unsafe);
168 |
169 | for (auto&& w : ps.warnings())
170 | u8cerr << w << "\n";
171 |
172 | thread_pool tp;
173 |
174 | for (auto& p : ps.get()) {
175 | for (auto& lg : p.langs) {
176 | // copy the global context, each thread must have its own
177 | tp.add([&, cxcopy = gcx()]() mutable {
178 | lrelease()
179 | .project(p.name)
180 | .sources(lg.ts_files)
181 | .out(dest)
182 | .run(cxcopy);
183 | });
184 | }
185 | }
186 | }
187 |
188 | } // namespace mob
189 |
--------------------------------------------------------------------------------
/src/core/env.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../utility.h"
4 |
5 | namespace mob {
6 |
7 | // a set of environment variables; copy-on-write because this gets copied a lot
8 | //
9 | class env {
10 | public:
11 | using map = std::map;
12 |
13 | // used in set(); replaces, appends or prepends to a variable if it already
14 | // exists
15 | //
16 | enum flags { replace = 1, append, prepend };
17 |
18 | // Visual Studio environment variables for 32-bit
19 | //
20 | static env vs_x86();
21 |
22 | // Visual Studio environment variables for 64-bit
23 | //
24 | static env vs_x64();
25 |
26 | // Visual Studio environment variables for the given architecture
27 | //
28 | static env vs(arch a);
29 |
30 | // empty set
31 | //
32 | env();
33 |
34 | // handle ref count
35 | //
36 | env(const env& e);
37 | env(env&& e);
38 | env& operator=(const env& e);
39 | env& operator=(env&& e);
40 |
41 | // prepends to PATH
42 | //
43 | env& prepend_path(const fs::path& p);
44 | env& prepend_path(const std::vector& v);
45 |
46 | // appends to PATH
47 | //
48 | env& append_path(const fs::path& p);
49 | env& append_path(const std::vector& v);
50 |
51 | // sets k=v
52 | //
53 | env& set(std::string_view k, std::string_view v, flags f = replace);
54 | env& set(std::wstring k, std::wstring v, flags f = replace);
55 |
56 | // returns the variable' value, empty if not found
57 | //
58 | std::string get(std::string_view k) const;
59 |
60 | // map of variables
61 | //
62 | map get_map() const;
63 |
64 | // passed to CreateProcess() in the process class; returns a pointer to a
65 | // block of utf16 strings, owned by this, created on demand
66 | //
67 | void* get_unicode_pointers() const;
68 |
69 | private:
70 | // shared between copies
71 | //
72 | struct data {
73 | std::mutex m;
74 | map vars;
75 |
76 | // unicode strings, see get_unicode_pointers()
77 | mutable std::wstring sys;
78 | };
79 |
80 | // shared data
81 | std::shared_ptr data_;
82 |
83 | // whether this instance owns the data, set to true in copy_for_write()
84 | // when the data must be modified
85 | bool own_;
86 |
87 | // creates the unicode strings
88 | //
89 | void create_sys() const;
90 |
91 | // returns a pointer inside the map, null if not found
92 | //
93 | std::wstring* find(std::wstring_view name);
94 | const std::wstring* find(std::wstring_view name) const;
95 |
96 | // called by set(), sets the value in the map
97 | //
98 | void set_impl(std::wstring k, std::wstring v, flags f);
99 |
100 | // duplicates the data, sets own_=true
101 | //
102 | void copy_for_write();
103 |
104 | // called by the various *_path() functions, actually changes the PATH
105 | // value
106 | //
107 | env& change_path(const std::vector& v, flags f);
108 | };
109 |
110 | // represents mob's environment variables
111 | //
112 | struct this_env {
113 | // sets a variable
114 | //
115 | static void set(const std::string& k, const std::string& v,
116 | env::flags f = env::replace);
117 |
118 | // changes PATH
119 | //
120 | static void prepend_to_path(const fs::path& p);
121 | static void append_to_path(const fs::path& p);
122 |
123 | // returns mob's environment variables
124 | //
125 | static env get();
126 |
127 | // returns a specific variable; bails out if it doesn't exist
128 | //
129 | static std::string get(const std::string& k);
130 |
131 | // returns a specific variable, or empty if it doesn't exist
132 | //
133 | static std::optional get_opt(const std::string& k);
134 |
135 | private:
136 | // used by get() and get_opt(), does the actual work
137 | //
138 | static std::optional get_impl(const std::string& k);
139 | };
140 |
141 | } // namespace mob
142 |
--------------------------------------------------------------------------------
/src/core/formatters.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../utility/string.h"
4 |
5 | template <>
6 | struct std::formatter : std::formatter {
7 | template
8 | FmtContext::iterator format(std::wstring const& s, FmtContext& ctx) const
9 | {
10 | return std::formatter::format(mob::utf16_to_utf8(s), ctx);
11 | }
12 | };
13 |
14 | template <>
15 | struct std::formatter
16 | : std::formatter, char> {
17 | template
18 | FmtContext::iterator format(std::filesystem::path const& s, FmtContext& ctx) const
19 | {
20 | return std::formatter,
21 | char>::format(s.native(), ctx);
22 | }
23 | };
24 |
25 | template
26 | requires std::is_enum_v
27 | struct std::formatter
28 | : std::formatter, CharT> {
29 | template
30 | FmtContext::iterator format(Enum v, FmtContext& ctx) const
31 | {
32 | return std::formatter, CharT>::format(
33 | static_cast>(v), ctx);
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/src/core/ini.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace mob {
4 |
5 | std::string default_ini_filename();
6 |
7 | std::vector
8 | find_inis(bool auto_detect, const std::vector& from_cl, bool verbose);
9 |
10 | struct ini_data {
11 | using alias_patterns = std::vector;
12 | using aliases_map = std::map;
13 |
14 | using kv_map = std::map;
15 | using sections_vector = std::vector>;
16 |
17 | fs::path path;
18 | aliases_map aliases;
19 | sections_vector sections;
20 |
21 | kv_map& get_section(std::string_view name);
22 | void set(std::string_view section, std::string key, std::string value);
23 | };
24 |
25 | ini_data parse_ini(const fs::path& ini);
26 | std::string default_ini_filename();
27 |
28 | } // namespace mob
29 |
--------------------------------------------------------------------------------
/src/core/op.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../utility.h"
4 |
5 | namespace mob {
6 | class context;
7 | }
8 |
9 | namespace mob::op {
10 |
11 | // filesystem operations, also handle --dry
12 | //
13 | // for functions that end with _if_better(): the source is considered better
14 | // than the destination if:
15 | // 1) the destination doesn't exist, or
16 | // 2) the size is different, or
17 | // 3) the date is newer
18 |
19 | // various flags for the operations below, only some of them are used by some
20 | // functions
21 | //
22 | enum flags {
23 | noflags = 0x00,
24 |
25 | // the operation is optional, don't bail out if it fails
26 | optional = 0x01,
27 |
28 | // used by copy_glob_to_dir_if_better() to decide if files and/or
29 | // directories are copied
30 | copy_files = 0x02,
31 | copy_dirs = 0x04,
32 |
33 | // operations will typically fail early if paths are empty or if they're not
34 | // inside a list of approved locations, like the prefix, %TEMP%, etc.
35 | //
36 | // this is to prevent mob from going on a deletion spree in case of bugs
37 | unsafe = 0x08
38 | };
39 |
40 | MOB_ENUM_OPERATORS(flags);
41 |
42 | // creates the given file if it doesn't exist
43 | //
44 | void touch(const context& cx, const fs::path& p, flags f = noflags);
45 |
46 | // creates all the directories in the given path
47 | //
48 | void create_directories(const context& cx, const fs::path& p, flags f = noflags);
49 |
50 | // deletes the given directory, recursive
51 | //
52 | // if deletion fails because of access denied, attempts to remove the readonly
53 | // flag on all files and tries again; this happens with some archives like 7z
54 | //
55 | // if the directory is controlled by git, prefer git_wrap::delete_directory(),
56 | // which checks for uncommitted changes before
57 | //
58 | void delete_directory(const context& cx, const fs::path& p, flags f = noflags);
59 |
60 | // deletes the given file
61 | //
62 | void delete_file(const context& cx, const fs::path& p, flags f = noflags);
63 |
64 | // deletes all files matching the glob in the glob's parent directory
65 | //
66 | void delete_file_glob(const context& cx, const fs::path& glob, flags f = noflags);
67 |
68 | // removes the readonly flag for all files in `dir`, recursive
69 | //
70 | void remove_readonly(const context& cx, const fs::path& dir, flags f = noflags);
71 |
72 | // renames `src` to `dest`, files or directories; fails if it already exists
73 | //
74 | void rename(const context& cx, const fs::path& src, const fs::path& dest,
75 | flags f = noflags);
76 |
77 | // moves a file or directory `src` into dir `dest_dir`, using the same name
78 | // (renames src to dest_dir/src.filename()); fails if it already exists
79 | //
80 | void move_to_directory(const context& cx, const fs::path& src,
81 | const fs::path& dest_dir, flags f = noflags);
82 |
83 | // copies a single file `file` into `dest_dir`; if the file already exists, only
84 | // copies it if it's considered better (see comment on top); doesn't support
85 | // globs or directories
86 | //
87 | void copy_file_to_dir_if_better(const context& cx, const fs::path& file,
88 | const fs::path& dest_dir, flags f = noflags);
89 |
90 | // same as copy_file_to_dir_if_better(), but the `dest_file` contains the
91 | // target filename instead of being constructed from dest_dir/src.filename()
92 | //
93 | void copy_file_to_file_if_better(const context& cx, const fs::path& src_file,
94 | const fs::path& dest_file, flags f = noflags);
95 |
96 | // basically calls copy_file_to_dir_if_better() for every file matching the
97 | // glob; recursive
98 | //
99 | void copy_glob_to_dir_if_better(const context& cx, const fs::path& src_glob,
100 | const fs::path& dest_dir, flags f);
101 |
102 | // renames `dest` to `src`, deleting `src` if it exists; if `backup` is given,
103 | // `src` is first renamed to it
104 | //
105 | // this attempts an atomic rename with ReplaceFile(), falls back to non-atomic
106 | // renames if it fails
107 | //
108 | void replace_file(const context& cx, const fs::path& src, const fs::path& dest,
109 | const fs::path& backup = {}, flags f = noflags);
110 |
111 | // reads the given file, converts it to utf8 from the given encoding, returns
112 | // the utf8 string; if `e` is `dont_know`, returns the bytes as-is
113 | //
114 | std::string read_text_file(const context& cx, encodings e, const fs::path& p,
115 | flags f = noflags);
116 |
117 | // creates file `p`, writes the given utf8 string into it, converting the string
118 | // to the given encoding; if `e` is dont_know, the bytes are written as-is
119 | //
120 | void write_text_file(const context& cx, encodings e, const fs::path& p,
121 | std::string_view utf8, flags f = noflags);
122 |
123 | // creates an archive `dest_file` and puts all the files matching `src_glob`
124 | // into it, ignoring any file in `ignore` by name
125 | //
126 | // uses tools::archiver
127 | //
128 | void archive_from_glob(const context& cx, const fs::path& src_glob,
129 | const fs::path& dest_file,
130 | const std::vector& ignore, flags f = noflags);
131 |
132 | // creates an archive `dest_file` and puts all the files from `files` in it,
133 | // resolving relative paths against `files_root`
134 | //
135 | void archive_from_files(const context& cx, const std::vector& files,
136 | const fs::path& files_root, const fs::path& dest_file,
137 | flags f = noflags);
138 |
139 | } // namespace mob::op
140 |
--------------------------------------------------------------------------------
/src/core/paths.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace mob {
4 |
5 | // returns the path to mob.exe that's currently running, including filename;
6 | // bails on failure
7 | //
8 | fs::path mob_exe_path();
9 |
10 | // returns mob's root directory, contains third-party/, etc.; bails on failure
11 | //
12 | // this is not necessarily the parent of mob_exe_path(), it mob could be running
13 | // from the build directory
14 | //
15 | fs::path find_root(bool verbose = false);
16 |
17 | // resolves the given relative path against find_root(); bails when not found
18 | //
19 | fs::path find_in_root(const fs::path& file);
20 |
21 | // returns the absolute path of mob's third-party directory; bails when not
22 | // found
23 | //
24 | fs::path find_third_party_directory();
25 |
26 | // returns the absolute path to x86/x64 program files directory
27 | //
28 | fs::path find_program_files_x86();
29 | fs::path find_program_files_x64();
30 |
31 | // returns the absolute path to visual studio's root directory, the one that
32 | // contains Common7, VC, etc.; bails if not found
33 | //
34 | fs::path find_vs();
35 |
36 | // returns the absolute path to VCPKG root directory to be used as VCPKG_ROOT when
37 | // building
38 | //
39 | fs::path find_vcpkg();
40 |
41 | // returns the absolute path to Qt's root directory, the one that contains
42 | // bin, include, etc.; bails if not found
43 | //
44 | fs::path find_qt();
45 |
46 | // returns the absolute path to iscc.exe; bails if not found
47 | //
48 | fs::path find_iscc();
49 |
50 | // returns the absolute path to the system's temp directory; bails on error
51 | //
52 | fs::path find_temp_dir();
53 |
54 | // returns the absolute path to the vcvars batch file, bails if not found
55 | //
56 | fs::path find_vcvars();
57 |
58 | } // namespace mob
59 |
--------------------------------------------------------------------------------
/src/core/pch.h:
--------------------------------------------------------------------------------
1 | // for intellisense
2 | #include "../pch.h"
3 |
--------------------------------------------------------------------------------
/src/core/pipe.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../utility.h"
4 |
5 | namespace mob {
6 |
7 | // a pipe connected to a process's stdout or stderr, it is read from
8 | //
9 | class async_pipe_stdout {
10 | public:
11 | async_pipe_stdout(const context& cx);
12 |
13 | // a pipe has two ends: one that's given to the process so it can write to
14 | // it, and another that's kept so it can be read from
15 | //
16 | // this creates both ends and returns the handle that should be given to
17 | // the process
18 | //
19 | handle_ptr create();
20 |
21 | // reads from the pipe and returns bytes, if any
22 | //
23 | // if `finish` is true (happens when the process has terminated) and nothing
24 | // is available in the pipe, closed() will return true
25 | //
26 | // this may start an async read, so read() must be called repeatedly until
27 | // the process terminates
28 | //
29 | std::string_view read(bool finish);
30 |
31 | // if this returns true, everything has been read from the pipe
32 | //
33 | bool closed() const;
34 |
35 | private:
36 | // the maximum number of bytes that can be put in the pipe
37 | static const std::size_t buffer_size = 50'000;
38 |
39 | // calling context, used for logging
40 | const context& cx_;
41 |
42 | // end of the pipe that is read from
43 | handle_ptr pipe_;
44 |
45 | // an event that's given to pipe for overlapped reads, signalled when data
46 | // is available
47 | handle_ptr event_;
48 |
49 | // internal buffer of `buffer_size` bytes, the data from the pipe is put
50 | // in there
51 | std::unique_ptr buffer_;
52 |
53 | // used for async reads
54 | OVERLAPPED ov_;
55 |
56 | // whether the last read attempt said an async operation was started
57 | bool pending_;
58 |
59 | // whether the last read attempt had `finished` true and nothing was
60 | // available in the pipe; in this case, the pipe is considered closed
61 | bool closed_;
62 |
63 | // creates the actual pipe, sets stdout_ and returns the other end so it
64 | // can be given to the process
65 | //
66 | HANDLE create_named_pipe();
67 |
68 | // called when pending_ is false; tries to read from the pipe, which may
69 | // start an async operation, in which case pending_ is set to true and an
70 | // empty string is returned
71 | //
72 | // if the read operation was completed synchronously, returns the bytes
73 | // that were read
74 | //
75 | std::string_view try_read();
76 |
77 | // called when pending_ is true; if the async operation is finished, resets
78 | // pending_ and returns the bytes that were read
79 | //
80 | std::string_view check_pending();
81 | };
82 |
83 | // a pipe connected to a process's stdin, it is written to; this pipe is
84 | // synchronous and does not keep a copy of the given buffer, see write()
85 | //
86 | class async_pipe_stdin {
87 | public:
88 | async_pipe_stdin(const context& cx);
89 |
90 | handle_ptr create();
91 |
92 | // tries to send all of `s` down the pipe, returns the number of bytes
93 | // actually written
94 | //
95 | std::size_t write(std::string_view s);
96 |
97 | // closes the pipe, should be called as soon as everything has been written
98 | //
99 | void close();
100 |
101 | private:
102 | // calling context, used for logging
103 | const context& cx_;
104 |
105 | // end of the pipe that is written to
106 | handle_ptr pipe_;
107 | };
108 |
109 | } // namespace mob
110 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "cmd/commands.h"
3 | #include "core/conf.h"
4 | #include "core/op.h"
5 | #include "net.h"
6 | #include "tasks/task_manager.h"
7 | #include "tasks/tasks.h"
8 | #include "tools/tools.h"
9 | #include "utility.h"
10 | #include "utility/threading.h"
11 |
12 | namespace mob {
13 |
14 | void add_tasks()
15 | {
16 | using namespace tasks;
17 |
18 | // add new tasks here
19 | //
20 | // top level tasks are run sequentially, tasks added to a parallel_tasks will
21 | // run in parallel; which tasks are run in parallel is somewhat arbitrary when
22 | // there's no dependency, the goal is just to saturate the cpu
23 | //
24 | // mob doesn't have a concept of task dependencies, just task ordering, so
25 | // if a task depends on another, it has to be earlier in the order
26 |
27 | // super tasks
28 |
29 | using mo = modorganizer;
30 |
31 | // most of the alternate names below are from the transifex slugs, which
32 | // are sometimes different from the project names, for whatever reason
33 |
34 | add_task().add_task().add_task("cmake_common");
35 |
36 | add_task("modorganizer-uibase");
37 |
38 | add_task()
39 | .add_task("modorganizer-archive")
40 | .add_task("modorganizer-lootcli")
41 | .add_task("modorganizer-esptk")
42 | .add_task("modorganizer-bsatk")
43 | .add_task("modorganizer-nxmhandler")
44 | .add_task("modorganizer-helper")
45 | .add_task("modorganizer-game_bethesda");
46 |
47 | add_task()
48 | .add_task({"modorganizer-bsapacker", "bsa_packer"})
49 | .add_task({"modorganizer-tool_inieditor", "inieditor"})
50 | .add_task({"modorganizer-tool_inibakery", "inibakery"})
51 | .add_task("modorganizer-preview_bsa")
52 | .add_task("modorganizer-preview_base")
53 | .add_task("modorganizer-diagnose_basic")
54 | .add_task("modorganizer-check_fnis")
55 | .add_task("modorganizer-installer_bain")
56 | .add_task("modorganizer-installer_manual")
57 | .add_task("modorganizer-installer_bundle")
58 | .add_task("modorganizer-installer_quick")
59 | .add_task("modorganizer-installer_fomod")
60 | .add_task("modorganizer-installer_fomod_csharp")
61 | .add_task("modorganizer-installer_omod")
62 | .add_task("modorganizer-installer_wizard")
63 | .add_task("modorganizer-bsa_extractor")
64 | .add_task("modorganizer-plugin_python");
65 |
66 | add_task()
67 | .add_task()
68 | .add_task()
69 | .add_task()
70 | .add_task({"modorganizer-tool_configurator", "pycfg"})
71 | .add_task("modorganizer-fnistool")
72 | .add_task("modorganizer-basic_games")
73 | .add_task({"modorganizer-script_extender_plugin_checker",
74 | "scriptextenderpluginchecker"})
75 | .add_task({"modorganizer-form43_checker", "form43checker"})
76 | .add_task({"modorganizer-preview_dds", "ddspreview"})
77 | .add_task({"modorganizer", "organizer"});
78 |
79 | // other tasks
80 | add_task();
81 | add_task();
82 | }
83 |
84 | // figures out which command to run and returns it, if any
85 | //
86 | std::shared_ptr handle_command_line(const std::vector& args)
87 | {
88 | auto help = std::make_shared();
89 | auto build = std::make_shared();
90 |
91 | // available commands
92 | std::vector> commands = {
93 | help,
94 | std::make_unique(),
95 | std::make_unique(),
96 | build,
97 | std::make_unique(),
98 | std::make_unique(),
99 | std::make_unique(),
100 | std::make_unique(),
101 | std::make_unique(),
102 | std::make_unique(),
103 | std::make_unique()};
104 |
105 | // commands are shown in the help
106 | help->set_commands(commands);
107 |
108 | // root group with all the command groups
109 | clipp::group all_groups;
110 |
111 | // not sure, actually
112 | all_groups.scoped(false);
113 |
114 | // child groups are exclusive, that is, only one command can be given
115 | all_groups.exclusive(true);
116 |
117 | for (auto& c : commands)
118 | all_groups.push_back(c->group());
119 |
120 | // vs reports a no-op on the left side of the command, which is incorrect
121 | #pragma warning(suppress : 4548)
122 | auto cli = (all_groups, command::common_options_group());
123 | auto pr = clipp::parse(args, cli);
124 |
125 | if (!pr) {
126 | // if a command was picked, show its help instead of the main one
127 | for (auto&& c : commands) {
128 | if (c->picked()) {
129 | c->force_help();
130 | return std::move(c);
131 | }
132 | }
133 |
134 | // bad command line
135 | help->force_exit_code(1);
136 | return help;
137 | }
138 |
139 | for (auto&& c : commands) {
140 | if (c->picked())
141 | return std::move(c);
142 | }
143 |
144 | return {};
145 | }
146 |
147 | int run(const std::vector& args)
148 | {
149 | font_restorer fr;
150 | curl_init curl;
151 |
152 | try {
153 | add_tasks();
154 |
155 | auto c = handle_command_line(args);
156 | if (!c)
157 | return 1;
158 |
159 | return c->run();
160 | }
161 | catch (bailed&) {
162 | // silent
163 | return 1;
164 | }
165 | }
166 |
167 | } // namespace mob
168 |
169 | int wmain(int argc, wchar_t** argv)
170 | {
171 | // makes streams unicode
172 | mob::set_std_streams();
173 |
174 | // outputs stacktrace on crash
175 | mob::set_thread_exception_handlers();
176 |
177 | std::vector args;
178 | for (int i = 1; i < argc; ++i)
179 | args.push_back(mob::utf16_to_utf8(argv[i]));
180 |
181 | int r = mob::run(args);
182 | mob::dump_logs();
183 |
184 | return r;
185 | }
186 |
--------------------------------------------------------------------------------
/src/net.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "utility.h"
4 |
5 | namespace mob {
6 |
7 | class context;
8 |
9 | // curl global init/cleanup
10 | //
11 | struct curl_init {
12 | curl_init();
13 | ~curl_init();
14 |
15 | curl_init(const curl_init&) = delete;
16 | curl_init& operator=(const curl_init&) = delete;
17 | };
18 |
19 | // wrapper around curl_url
20 | //
21 | class url {
22 | public:
23 | url(const char* p);
24 | url(std::string s = {});
25 |
26 | const char* c_str() const;
27 | const std::string& string() const;
28 | bool empty() const;
29 |
30 | // component of the path after last separator
31 | //
32 | std::string filename() const;
33 |
34 | private:
35 | std::string s_;
36 | };
37 |
38 | // threaded downloader
39 | //
40 | class curl_downloader {
41 | public:
42 | using headers = std::vector>;
43 |
44 | curl_downloader(const context* cx = nullptr);
45 |
46 | // convenience: starts a thread, downloads url into given file
47 | //
48 | void start(const mob::url& u, const fs::path& file);
49 |
50 | // sets the url to download from
51 | //
52 | curl_downloader& url(const mob::url& u);
53 |
54 | // sets the output file
55 | //
56 | curl_downloader& file(const fs::path& file);
57 |
58 | // adds a header
59 | //
60 | curl_downloader& header(std::string name, std::string value);
61 |
62 | // starts the download in a thread
63 | //
64 | curl_downloader& start();
65 |
66 | // joins download thread
67 | //
68 | curl_downloader& join();
69 |
70 | // async interrupt
71 | //
72 | void interrupt();
73 |
74 | // whether the file was downloaded correctly; only valid after join()
75 | //
76 | bool ok() const;
77 |
78 | // if file() wasn't called, returns the content that was retrieved
79 | //
80 | const std::string& output();
81 | std::string steal_output();
82 |
83 | private:
84 | const context& cx_;
85 | mob::url url_;
86 | fs::path path_;
87 | handle_ptr file_;
88 | std::thread thread_;
89 | std::size_t bytes_;
90 | std::atomic interrupt_;
91 | bool ok_;
92 | std::string output_;
93 | headers headers_;
94 |
95 | void run();
96 | bool create_file();
97 | bool write_file(char* ptr, size_t size);
98 | bool write_string(char* ptr, size_t size);
99 |
100 | static size_t on_write_static(char* ptr, size_t size, size_t nmemb,
101 | void* user) noexcept;
102 |
103 | void on_write(char* ptr, std::size_t n) noexcept;
104 |
105 | static int on_progress_static(void* user, double dltotal, double dlnow,
106 | double ultotal, double ulnow) noexcept;
107 |
108 | static int on_xfer_static(void* user, curl_off_t dltotal, curl_off_t dlnow,
109 | curl_off_t ultotal, curl_off_t ulnow) noexcept;
110 |
111 | static int on_debug_static(CURL* handle, curl_infotype type, char* data,
112 | size_t size, void* user) noexcept;
113 |
114 | void on_debug(curl_infotype type, std::string_view s);
115 | };
116 |
117 | } // namespace mob
118 |
119 | template <>
120 | struct std::formatter : std::formatter {
121 | template
122 | FmtContext::iterator format(mob::url const& u, FmtContext& ctx) const
123 | {
124 | return std::formatter::format(u.string(), ctx);
125 | }
126 | };
127 |
--------------------------------------------------------------------------------
/src/pch.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
--------------------------------------------------------------------------------
/src/pch.h:
--------------------------------------------------------------------------------
1 | // global warnings
2 | #pragma warning(disable : 4464) // relative include path
3 | #pragma warning(disable : 4820) // padding added
4 | #pragma warning(disable : 4623) // implicitly defined as deleted
5 | #pragma warning(disable : 4625) // implicitly defined as deleted
6 | #pragma warning(disable : 4626) // implicitly defined as deleted
7 | #pragma warning(disable : 5026) // implicitly defined as deleted
8 | #pragma warning(disable : 5027) // implicitly defined as deleted
9 | #pragma warning(disable : 4514) // unreferenced inline
10 | #pragma warning(disable : 4866) // may not enforce left-to-right evaluation
11 | #pragma warning(disable : 4868) // may not enforce left-to-right evaluation
12 | #pragma warning(disable : 4711) // selected for automatic inline expansion
13 | #pragma warning(disable : 4251) // needs to have dll-interface
14 | #pragma warning(disable : 4571) // catch semantics
15 | #pragma warning(disable : 4686) // change in UDT return calling convention
16 | #pragma warning(disable : 5045) // spectre
17 | #pragma warning(disable : 4710) // function not inlined
18 | #pragma warning(disable : 4435) // /vd2
19 | #pragma warning(disable : 5052) // requires use of /std:c++latest
20 |
21 | // popped by warnings_pop.h
22 | #pragma warning(push, 3)
23 | #pragma warning(disable : 4355) // this used in initializer list
24 | #pragma warning(disable : 4668) // not defined as a preprocessor macro
25 | #pragma warning(disable : 4619) // there is no warning number 'x'
26 | #pragma warning(disable : 5031) // warning state pushed in different file
27 | #pragma warning(disable : 4643) // forward declaring in namespace std
28 | #pragma warning(disable : 4365) // signed/unsigned mismatch
29 | #pragma warning(disable : 4061) // enumerator is not explicitly handled
30 | #pragma warning(disable : 4265) // destructor is not virtual
31 | #pragma warning(disable : 4623) // default constructor implicitly deleted
32 | #pragma warning(disable : 4266) // no override available
33 | #pragma warning(disable : 4267) // conversion
34 | #pragma warning(disable : 4774) // format string
35 | #pragma warning(disable : 4371) // layout of class may have changed
36 | #pragma warning(disable : 5039) // throwing function passed to extern C
37 | #pragma warning(disable : 4388) // signed/unsigned mismatch
38 | #pragma warning(disable : 4582) // constructor is not implicitly called
39 | #pragma warning(disable : 4574) // macro is defined to be 'value'
40 | #pragma warning(disable : 4201) // nameless struct/union
41 | #pragma warning(disable : 4127) // conditional expression is constant
42 | #pragma warning(disable : 4100) // unreferenced parameter
43 | #pragma warning(disable : 4242) // possible loss of data
44 | #pragma warning(disable : 4244) // possible loss of data
45 | #pragma warning(disable : 4275) // non dll-interface base
46 |
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 | #include
53 | #include
54 | #include
55 | #include