├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── extern └── sqlite │ ├── shell.c │ ├── sqlite3.c │ ├── sqlite3.h │ └── sqlite3ext.h ├── images ├── Console.gif └── GUI.gif ├── include ├── API │ ├── Card.h │ ├── DB_API.h │ ├── Date.h │ └── File.h ├── Console │ └── Console.h └── GUI │ └── GUI.h └── src ├── API ├── Card.cpp ├── DB_API.cpp ├── DB_API_.h └── Date.cpp ├── CC_Generator ├── ProjectInfo_.h ├── console_main.cpp └── gui_main.cpp ├── Console ├── Console.cpp └── Console_.h └── GUI ├── GUI.cpp ├── GUI_.h └── emscripten_funcs.h /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | build -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "extern/ImGuiFileDialog"] 2 | path = extern/ImGuiFileDialog 3 | url = https://github.com/aiekick/ImGuiFileDialog.git 4 | [submodule "extern/DearImGui"] 5 | path = extern/DearImGui 6 | url = https://github.com/ocornut/imgui.git 7 | [submodule "extern/glfw"] 8 | path = extern/glfw 9 | url = https://github.com/glfw/glfw.git 10 | [submodule "extern/PDCurses"] 11 | path = extern/PDCurses 12 | url = https://github.com/wmcbrine/PDCurses.git 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16...3.27) 2 | project(CC_Generator VERSION 2.0.1 LANGUAGES C CXX) 3 | 4 | set(CMAKE_CXX_STANDARD 20) 5 | set(CMAKE_CXX_STANDARD_REQUIRED YES) 6 | 7 | add_library(api STATIC src/API/DB_API.cpp src/API/Card.cpp src/API/Date.cpp) 8 | target_include_directories(api PUBLIC include/API extern/sqlite) 9 | add_library(sqlite STATIC extern/sqlite/sqlite3.c) 10 | 11 | if(UNIX) 12 | target_link_libraries(sqlite PRIVATE sqlite3) 13 | endif() 14 | 15 | # Console 16 | if (WIN32) 17 | set(CURSES_SOURCES 18 | extern/PDCurses/pdcurses/addch.c 19 | extern/PDCurses/pdcurses/addchstr.c 20 | extern/PDCurses/pdcurses/addstr.c 21 | extern/PDCurses/pdcurses/attr.c 22 | extern/PDCurses/pdcurses/beep.c 23 | extern/PDCurses/pdcurses/bkgd.c 24 | extern/PDCurses/pdcurses/border.c 25 | extern/PDCurses/pdcurses/clear.c 26 | extern/PDCurses/pdcurses/color.c 27 | extern/PDCurses/pdcurses/debug.c 28 | extern/PDCurses/pdcurses/delch.c 29 | extern/PDCurses/pdcurses/deleteln.c 30 | extern/PDCurses/pdcurses/getch.c 31 | extern/PDCurses/pdcurses/getstr.c 32 | extern/PDCurses/pdcurses/getyx.c 33 | extern/PDCurses/pdcurses/inch.c 34 | extern/PDCurses/pdcurses/inchstr.c 35 | extern/PDCurses/pdcurses/initscr.c 36 | extern/PDCurses/pdcurses/inopts.c 37 | extern/PDCurses/pdcurses/insch.c 38 | extern/PDCurses/pdcurses/insstr.c 39 | extern/PDCurses/pdcurses/instr.c 40 | extern/PDCurses/pdcurses/kernel.c 41 | extern/PDCurses/pdcurses/keyname.c 42 | extern/PDCurses/pdcurses/mouse.c 43 | extern/PDCurses/pdcurses/move.c 44 | extern/PDCurses/pdcurses/outopts.c 45 | extern/PDCurses/pdcurses/overlay.c 46 | extern/PDCurses/pdcurses/pad.c 47 | extern/PDCurses/pdcurses/panel.c 48 | extern/PDCurses/pdcurses/printw.c 49 | extern/PDCurses/pdcurses/README.md 50 | extern/PDCurses/pdcurses/refresh.c 51 | extern/PDCurses/pdcurses/scanw.c 52 | extern/PDCurses/pdcurses/scroll.c 53 | extern/PDCurses/pdcurses/scr_dump.c 54 | extern/PDCurses/pdcurses/slk.c 55 | extern/PDCurses/pdcurses/termattr.c 56 | extern/PDCurses/pdcurses/touch.c 57 | extern/PDCurses/pdcurses/util.c 58 | extern/PDCurses/pdcurses/window.c 59 | extern/PDCurses/wincon/pdcclip.c 60 | extern/PDCurses/wincon/pdcdisp.c 61 | extern/PDCurses/wincon/pdcgetsc.c 62 | extern/PDCurses/wincon/pdckbd.c 63 | extern/PDCurses/wincon/pdcscrn.c 64 | extern/PDCurses/wincon/pdcsetsc.c 65 | extern/PDCurses/wincon/pdcutil.c 66 | ) 67 | 68 | add_library(ncurses STATIC ${CURSES_SOURCES}) 69 | target_include_directories(ncurses PUBLIC extern/PDCurses extern/PDCurses/wincon) 70 | endif() 71 | 72 | add_library(console STATIC src/Console/Console.cpp) 73 | target_include_directories(console PUBLIC include/Console) 74 | target_link_libraries(console PRIVATE api ncurses) 75 | 76 | 77 | add_executable(CC_Generator_Console src/CC_Generator/console_main.cpp) 78 | target_link_libraries(CC_Generator_Console PRIVATE api console sqlite ncurses) 79 | target_compile_features(CC_Generator_Console PUBLIC cxx_std_20) 80 | 81 | # GUI 82 | 83 | add_library(imgui STATIC 84 | extern/DearImGui/imgui.cpp 85 | extern/DearImGui/imgui_draw.cpp 86 | extern/DearImGui/imgui_widgets.cpp 87 | extern/DearImGui/imgui_tables.cpp 88 | extern/DearImGui/backends/imgui_impl_glfw.cpp 89 | extern/DearImGui/backends/imgui_impl_opengl3.cpp 90 | extern/DearImGui/misc/cpp/imgui_stdlib.cpp 91 | ) 92 | 93 | 94 | target_include_directories(imgui PUBLIC extern/DearImGui) 95 | target_include_directories(imgui PUBLIC extern/DearImGui/misc/cpp) 96 | 97 | add_library(imguifiledialog STATIC extern/ImGuiFileDialog/ImGuiFileDialog.cpp) 98 | target_include_directories(imguifiledialog PUBLIC extern/ImGuiFileDialog extern/DearImGui) 99 | target_link_libraries(imgui PUBLIC imguifiledialog) 100 | 101 | 102 | if(WIN32) 103 | add_definitions(-D_GLFW_WIN32) 104 | add_library(glfw STATIC 105 | extern/glfw/src/context.c 106 | extern/glfw/src/init.c 107 | extern/glfw/src/input.c 108 | extern/glfw/src/monitor.c 109 | extern/glfw/src/vulkan.c 110 | extern/glfw/src/window.c 111 | extern/glfw/src/platform.c 112 | extern/glfw/src/null_init.c 113 | extern/glfw/src/null_monitor.c 114 | extern/glfw/src/null_window.c 115 | extern/glfw/src/win32_module.c 116 | extern/glfw/src/null_joystick.c 117 | extern/glfw/src/win32_init.c 118 | extern/glfw/src/win32_joystick.c 119 | extern/glfw/src/win32_monitor.c 120 | extern/glfw/src/win32_time.c 121 | extern/glfw/src/win32_thread.c 122 | extern/glfw/src/win32_window.c 123 | extern/glfw/src/wgl_context.c 124 | extern/glfw/src/egl_context.c 125 | extern/glfw/src/osmesa_context.c 126 | ) 127 | 128 | target_link_libraries(glfw PRIVATE opengl32) 129 | elseif(UNIX) 130 | add_definitions(-D_GLFW_X11) 131 | add_library(glfw STATIC 132 | extern/glfw/src/context.c 133 | extern/glfw/src/init.c 134 | extern/glfw/src/input.c 135 | extern/glfw/src/monitor.c 136 | extern/glfw/src/vulkan.c 137 | extern/glfw/src/window.c 138 | extern/glfw/src/platform.c 139 | extern/glfw/src/null_init.c 140 | extern/glfw/src/null_monitor.c 141 | extern/glfw/src/null_window.c 142 | extern/glfw/src/x11_init.c 143 | extern/glfw/src/x11_monitor.c 144 | extern/glfw/src/x11_window.c 145 | extern/glfw/src/xkb_unicode.c 146 | extern/glfw/src/glx_context.c 147 | extern/glfw/src/egl_context.c 148 | extern/glfw/src/osmesa_context.c 149 | extern/glfw/src/linux_joystick.c 150 | extern/glfw/src/posix_time.c 151 | extern/glfw/src/posix_thread.c 152 | extern/glfw/src/posix_module.c 153 | extern/glfw/src/posix_poll.c 154 | extern/glfw/src/null_joystick.c 155 | ) 156 | target_link_libraries(glfw PRIVATE dl GL X11) 157 | 158 | 159 | target_link_libraries(glfw PRIVATE dl GL X11) 160 | endif() 161 | 162 | target_include_directories(glfw PUBLIC extern/glfw/include) 163 | target_link_libraries(imgui PUBLIC glfw) 164 | 165 | add_library(gui STATIC src/GUI/GUI.cpp) 166 | target_include_directories(gui PUBLIC include/GUI extern/DearImGui/backends) 167 | target_link_libraries(gui PUBLIC api imgui) 168 | if (WIN32) 169 | add_executable(CC_Generator_GUI WIN32 src/CC_Generator/gui_main.cpp) 170 | elseif(UNIX) 171 | add_executable(CC_Generator_GUI src/CC_Generator/gui_main.cpp) 172 | endif() 173 | 174 | target_link_libraries(CC_Generator_GUI PRIVATE api gui sqlite) 175 | target_compile_features(CC_Generator_GUI PUBLIC cxx_std_20) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 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 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![](https://img.shields.io/github/v/release/ItaiShek/CC_Generator)](https://github.com/ItaiShek/CC_Generator/releases) 3 | ![](https://img.shields.io/github/downloads/ItaiShek/CC_Generator/total?color=red) 4 | [![](https://img.shields.io/github/issues/ItaiShek/CC_Generator?color=yellow)](https://github.com/ItaiShek/CC_Generator/issues) 5 | [![](https://img.shields.io/github/license/ItaiShek/CC_Generator?label=license&color=green)](https://github.com/ItaiShek/CC_Generator/blob/main/LICENSE) 6 | 7 | # Description 8 | 9 | Generate a bunch of random credit card numbers quickly and easily. 10 | 11 | ![GUI](images/GUI.gif "GUI") 12 | 13 | ![Console](images/Console.gif "Console") 14 | 15 | ## Installation 16 | 17 | ### Direct download: 18 | [Windows](https://github.com/ItaiShek/CC_Generator/releases/latest/download/CC_Generator_win.zip) 19 | 20 | [Linux](https://github.com/ItaiShek/CC_Generator/releases/latest/download/CC_Generator_linux.zip) 21 | 22 | ### Try the Online Version 23 | You can also try it in your browser (no installation needed), though it will run significantly slower than the desktop version: 24 | 25 | 👉 https://ItaiShek.GitHub.io/CC_Generator 26 | 27 | ## Disclaimer 28 | 29 | Every credit card that is generated with CC_Generator is **random and fake** and does not hold any value. 30 | 31 | Credit card numbers that are generated with CC_Generator follow the Luhn algorithm for validating identification numbers. 32 | 33 | These credit cards are **not** to be used for harming or deceiving people. 34 | 35 | These credit cards are for educational and data testing purposes only. 36 | 37 | I will not take **any responsibility** for damages that arise from misusing CC_Generator. 38 | 39 | ## Credits 40 | * Names: [GitHub Gist - Elifiner](https://gist.github.com/elifiner/cc90fdd387449158829515782936a9a4) -------------------------------------------------------------------------------- /extern/sqlite/sqlite3ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2006 June 7 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This header file defines the SQLite interface for use by 13 | ** shared libraries that want to be imported as extensions into 14 | ** an SQLite instance. Shared libraries that intend to be loaded 15 | ** as extensions by SQLite should #include this file instead of 16 | ** sqlite3.h. 17 | */ 18 | #ifndef SQLITE3EXT_H 19 | #define SQLITE3EXT_H 20 | #include "sqlite3.h" 21 | 22 | /* 23 | ** The following structure holds pointers to all of the SQLite API 24 | ** routines. 25 | ** 26 | ** WARNING: In order to maintain backwards compatibility, add new 27 | ** interfaces to the end of this structure only. If you insert new 28 | ** interfaces in the middle of this structure, then older different 29 | ** versions of SQLite will not be able to load each other's shared 30 | ** libraries! 31 | */ 32 | struct sqlite3_api_routines { 33 | void * (*aggregate_context)(sqlite3_context*,int nBytes); 34 | int (*aggregate_count)(sqlite3_context*); 35 | int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); 36 | int (*bind_double)(sqlite3_stmt*,int,double); 37 | int (*bind_int)(sqlite3_stmt*,int,int); 38 | int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); 39 | int (*bind_null)(sqlite3_stmt*,int); 40 | int (*bind_parameter_count)(sqlite3_stmt*); 41 | int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); 42 | const char * (*bind_parameter_name)(sqlite3_stmt*,int); 43 | int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); 44 | int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); 45 | int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); 46 | int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); 47 | int (*busy_timeout)(sqlite3*,int ms); 48 | int (*changes)(sqlite3*); 49 | int (*close)(sqlite3*); 50 | int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, 51 | int eTextRep,const char*)); 52 | int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, 53 | int eTextRep,const void*)); 54 | const void * (*column_blob)(sqlite3_stmt*,int iCol); 55 | int (*column_bytes)(sqlite3_stmt*,int iCol); 56 | int (*column_bytes16)(sqlite3_stmt*,int iCol); 57 | int (*column_count)(sqlite3_stmt*pStmt); 58 | const char * (*column_database_name)(sqlite3_stmt*,int); 59 | const void * (*column_database_name16)(sqlite3_stmt*,int); 60 | const char * (*column_decltype)(sqlite3_stmt*,int i); 61 | const void * (*column_decltype16)(sqlite3_stmt*,int); 62 | double (*column_double)(sqlite3_stmt*,int iCol); 63 | int (*column_int)(sqlite3_stmt*,int iCol); 64 | sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); 65 | const char * (*column_name)(sqlite3_stmt*,int); 66 | const void * (*column_name16)(sqlite3_stmt*,int); 67 | const char * (*column_origin_name)(sqlite3_stmt*,int); 68 | const void * (*column_origin_name16)(sqlite3_stmt*,int); 69 | const char * (*column_table_name)(sqlite3_stmt*,int); 70 | const void * (*column_table_name16)(sqlite3_stmt*,int); 71 | const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); 72 | const void * (*column_text16)(sqlite3_stmt*,int iCol); 73 | int (*column_type)(sqlite3_stmt*,int iCol); 74 | sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); 75 | void * (*commit_hook)(sqlite3*,int(*)(void*),void*); 76 | int (*complete)(const char*sql); 77 | int (*complete16)(const void*sql); 78 | int (*create_collation)(sqlite3*,const char*,int,void*, 79 | int(*)(void*,int,const void*,int,const void*)); 80 | int (*create_collation16)(sqlite3*,const void*,int,void*, 81 | int(*)(void*,int,const void*,int,const void*)); 82 | int (*create_function)(sqlite3*,const char*,int,int,void*, 83 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 84 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 85 | void (*xFinal)(sqlite3_context*)); 86 | int (*create_function16)(sqlite3*,const void*,int,int,void*, 87 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 88 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 89 | void (*xFinal)(sqlite3_context*)); 90 | int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); 91 | int (*data_count)(sqlite3_stmt*pStmt); 92 | sqlite3 * (*db_handle)(sqlite3_stmt*); 93 | int (*declare_vtab)(sqlite3*,const char*); 94 | int (*enable_shared_cache)(int); 95 | int (*errcode)(sqlite3*db); 96 | const char * (*errmsg)(sqlite3*); 97 | const void * (*errmsg16)(sqlite3*); 98 | int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); 99 | int (*expired)(sqlite3_stmt*); 100 | int (*finalize)(sqlite3_stmt*pStmt); 101 | void (*free)(void*); 102 | void (*free_table)(char**result); 103 | int (*get_autocommit)(sqlite3*); 104 | void * (*get_auxdata)(sqlite3_context*,int); 105 | int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); 106 | int (*global_recover)(void); 107 | void (*interruptx)(sqlite3*); 108 | sqlite_int64 (*last_insert_rowid)(sqlite3*); 109 | const char * (*libversion)(void); 110 | int (*libversion_number)(void); 111 | void *(*malloc)(int); 112 | char * (*mprintf)(const char*,...); 113 | int (*open)(const char*,sqlite3**); 114 | int (*open16)(const void*,sqlite3**); 115 | int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); 116 | int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); 117 | void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); 118 | void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); 119 | void *(*realloc)(void*,int); 120 | int (*reset)(sqlite3_stmt*pStmt); 121 | void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); 122 | void (*result_double)(sqlite3_context*,double); 123 | void (*result_error)(sqlite3_context*,const char*,int); 124 | void (*result_error16)(sqlite3_context*,const void*,int); 125 | void (*result_int)(sqlite3_context*,int); 126 | void (*result_int64)(sqlite3_context*,sqlite_int64); 127 | void (*result_null)(sqlite3_context*); 128 | void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); 129 | void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); 130 | void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); 131 | void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); 132 | void (*result_value)(sqlite3_context*,sqlite3_value*); 133 | void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); 134 | int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, 135 | const char*,const char*),void*); 136 | void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); 137 | char * (*xsnprintf)(int,char*,const char*,...); 138 | int (*step)(sqlite3_stmt*); 139 | int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, 140 | char const**,char const**,int*,int*,int*); 141 | void (*thread_cleanup)(void); 142 | int (*total_changes)(sqlite3*); 143 | void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); 144 | int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); 145 | void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, 146 | sqlite_int64),void*); 147 | void * (*user_data)(sqlite3_context*); 148 | const void * (*value_blob)(sqlite3_value*); 149 | int (*value_bytes)(sqlite3_value*); 150 | int (*value_bytes16)(sqlite3_value*); 151 | double (*value_double)(sqlite3_value*); 152 | int (*value_int)(sqlite3_value*); 153 | sqlite_int64 (*value_int64)(sqlite3_value*); 154 | int (*value_numeric_type)(sqlite3_value*); 155 | const unsigned char * (*value_text)(sqlite3_value*); 156 | const void * (*value_text16)(sqlite3_value*); 157 | const void * (*value_text16be)(sqlite3_value*); 158 | const void * (*value_text16le)(sqlite3_value*); 159 | int (*value_type)(sqlite3_value*); 160 | char *(*vmprintf)(const char*,va_list); 161 | /* Added ??? */ 162 | int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); 163 | /* Added by 3.3.13 */ 164 | int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); 165 | int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); 166 | int (*clear_bindings)(sqlite3_stmt*); 167 | /* Added by 3.4.1 */ 168 | int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, 169 | void (*xDestroy)(void *)); 170 | /* Added by 3.5.0 */ 171 | int (*bind_zeroblob)(sqlite3_stmt*,int,int); 172 | int (*blob_bytes)(sqlite3_blob*); 173 | int (*blob_close)(sqlite3_blob*); 174 | int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, 175 | int,sqlite3_blob**); 176 | int (*blob_read)(sqlite3_blob*,void*,int,int); 177 | int (*blob_write)(sqlite3_blob*,const void*,int,int); 178 | int (*create_collation_v2)(sqlite3*,const char*,int,void*, 179 | int(*)(void*,int,const void*,int,const void*), 180 | void(*)(void*)); 181 | int (*file_control)(sqlite3*,const char*,int,void*); 182 | sqlite3_int64 (*memory_highwater)(int); 183 | sqlite3_int64 (*memory_used)(void); 184 | sqlite3_mutex *(*mutex_alloc)(int); 185 | void (*mutex_enter)(sqlite3_mutex*); 186 | void (*mutex_free)(sqlite3_mutex*); 187 | void (*mutex_leave)(sqlite3_mutex*); 188 | int (*mutex_try)(sqlite3_mutex*); 189 | int (*open_v2)(const char*,sqlite3**,int,const char*); 190 | int (*release_memory)(int); 191 | void (*result_error_nomem)(sqlite3_context*); 192 | void (*result_error_toobig)(sqlite3_context*); 193 | int (*sleep)(int); 194 | void (*soft_heap_limit)(int); 195 | sqlite3_vfs *(*vfs_find)(const char*); 196 | int (*vfs_register)(sqlite3_vfs*,int); 197 | int (*vfs_unregister)(sqlite3_vfs*); 198 | int (*xthreadsafe)(void); 199 | void (*result_zeroblob)(sqlite3_context*,int); 200 | void (*result_error_code)(sqlite3_context*,int); 201 | int (*test_control)(int, ...); 202 | void (*randomness)(int,void*); 203 | sqlite3 *(*context_db_handle)(sqlite3_context*); 204 | int (*extended_result_codes)(sqlite3*,int); 205 | int (*limit)(sqlite3*,int,int); 206 | sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); 207 | const char *(*sql)(sqlite3_stmt*); 208 | int (*status)(int,int*,int*,int); 209 | int (*backup_finish)(sqlite3_backup*); 210 | sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); 211 | int (*backup_pagecount)(sqlite3_backup*); 212 | int (*backup_remaining)(sqlite3_backup*); 213 | int (*backup_step)(sqlite3_backup*,int); 214 | const char *(*compileoption_get)(int); 215 | int (*compileoption_used)(const char*); 216 | int (*create_function_v2)(sqlite3*,const char*,int,int,void*, 217 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 218 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 219 | void (*xFinal)(sqlite3_context*), 220 | void(*xDestroy)(void*)); 221 | int (*db_config)(sqlite3*,int,...); 222 | sqlite3_mutex *(*db_mutex)(sqlite3*); 223 | int (*db_status)(sqlite3*,int,int*,int*,int); 224 | int (*extended_errcode)(sqlite3*); 225 | void (*log)(int,const char*,...); 226 | sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); 227 | const char *(*sourceid)(void); 228 | int (*stmt_status)(sqlite3_stmt*,int,int); 229 | int (*strnicmp)(const char*,const char*,int); 230 | int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); 231 | int (*wal_autocheckpoint)(sqlite3*,int); 232 | int (*wal_checkpoint)(sqlite3*,const char*); 233 | void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); 234 | int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); 235 | int (*vtab_config)(sqlite3*,int op,...); 236 | int (*vtab_on_conflict)(sqlite3*); 237 | /* Version 3.7.16 and later */ 238 | int (*close_v2)(sqlite3*); 239 | const char *(*db_filename)(sqlite3*,const char*); 240 | int (*db_readonly)(sqlite3*,const char*); 241 | int (*db_release_memory)(sqlite3*); 242 | const char *(*errstr)(int); 243 | int (*stmt_busy)(sqlite3_stmt*); 244 | int (*stmt_readonly)(sqlite3_stmt*); 245 | int (*stricmp)(const char*,const char*); 246 | int (*uri_boolean)(const char*,const char*,int); 247 | sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); 248 | const char *(*uri_parameter)(const char*,const char*); 249 | char *(*xvsnprintf)(int,char*,const char*,va_list); 250 | int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); 251 | /* Version 3.8.7 and later */ 252 | int (*auto_extension)(void(*)(void)); 253 | int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, 254 | void(*)(void*)); 255 | int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, 256 | void(*)(void*),unsigned char); 257 | int (*cancel_auto_extension)(void(*)(void)); 258 | int (*load_extension)(sqlite3*,const char*,const char*,char**); 259 | void *(*malloc64)(sqlite3_uint64); 260 | sqlite3_uint64 (*msize)(void*); 261 | void *(*realloc64)(void*,sqlite3_uint64); 262 | void (*reset_auto_extension)(void); 263 | void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, 264 | void(*)(void*)); 265 | void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, 266 | void(*)(void*), unsigned char); 267 | int (*strglob)(const char*,const char*); 268 | /* Version 3.8.11 and later */ 269 | sqlite3_value *(*value_dup)(const sqlite3_value*); 270 | void (*value_free)(sqlite3_value*); 271 | int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); 272 | int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); 273 | /* Version 3.9.0 and later */ 274 | unsigned int (*value_subtype)(sqlite3_value*); 275 | void (*result_subtype)(sqlite3_context*,unsigned int); 276 | /* Version 3.10.0 and later */ 277 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); 278 | int (*strlike)(const char*,const char*,unsigned int); 279 | int (*db_cacheflush)(sqlite3*); 280 | /* Version 3.12.0 and later */ 281 | int (*system_errno)(sqlite3*); 282 | /* Version 3.14.0 and later */ 283 | int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); 284 | char *(*expanded_sql)(sqlite3_stmt*); 285 | /* Version 3.18.0 and later */ 286 | void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); 287 | /* Version 3.20.0 and later */ 288 | int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, 289 | sqlite3_stmt**,const char**); 290 | int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, 291 | sqlite3_stmt**,const void**); 292 | int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); 293 | void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); 294 | void *(*value_pointer)(sqlite3_value*,const char*); 295 | int (*vtab_nochange)(sqlite3_context*); 296 | int (*value_nochange)(sqlite3_value*); 297 | const char *(*vtab_collation)(sqlite3_index_info*,int); 298 | /* Version 3.24.0 and later */ 299 | int (*keyword_count)(void); 300 | int (*keyword_name)(int,const char**,int*); 301 | int (*keyword_check)(const char*,int); 302 | sqlite3_str *(*str_new)(sqlite3*); 303 | char *(*str_finish)(sqlite3_str*); 304 | void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); 305 | void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); 306 | void (*str_append)(sqlite3_str*, const char *zIn, int N); 307 | void (*str_appendall)(sqlite3_str*, const char *zIn); 308 | void (*str_appendchar)(sqlite3_str*, int N, char C); 309 | void (*str_reset)(sqlite3_str*); 310 | int (*str_errcode)(sqlite3_str*); 311 | int (*str_length)(sqlite3_str*); 312 | char *(*str_value)(sqlite3_str*); 313 | /* Version 3.25.0 and later */ 314 | int (*create_window_function)(sqlite3*,const char*,int,int,void*, 315 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 316 | void (*xFinal)(sqlite3_context*), 317 | void (*xValue)(sqlite3_context*), 318 | void (*xInv)(sqlite3_context*,int,sqlite3_value**), 319 | void(*xDestroy)(void*)); 320 | /* Version 3.26.0 and later */ 321 | const char *(*normalized_sql)(sqlite3_stmt*); 322 | /* Version 3.28.0 and later */ 323 | int (*stmt_isexplain)(sqlite3_stmt*); 324 | int (*value_frombind)(sqlite3_value*); 325 | /* Version 3.30.0 and later */ 326 | int (*drop_modules)(sqlite3*,const char**); 327 | /* Version 3.31.0 and later */ 328 | sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64); 329 | const char *(*uri_key)(const char*,int); 330 | const char *(*filename_database)(const char*); 331 | const char *(*filename_journal)(const char*); 332 | const char *(*filename_wal)(const char*); 333 | /* Version 3.32.0 and later */ 334 | const char *(*create_filename)(const char*,const char*,const char*, 335 | int,const char**); 336 | void (*free_filename)(const char*); 337 | sqlite3_file *(*database_file_object)(const char*); 338 | /* Version 3.34.0 and later */ 339 | int (*txn_state)(sqlite3*,const char*); 340 | /* Version 3.36.1 and later */ 341 | sqlite3_int64 (*changes64)(sqlite3*); 342 | sqlite3_int64 (*total_changes64)(sqlite3*); 343 | /* Version 3.37.0 and later */ 344 | int (*autovacuum_pages)(sqlite3*, 345 | unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), 346 | void*, void(*)(void*)); 347 | /* Version 3.38.0 and later */ 348 | int (*error_offset)(sqlite3*); 349 | int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); 350 | int (*vtab_distinct)(sqlite3_index_info*); 351 | int (*vtab_in)(sqlite3_index_info*,int,int); 352 | int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); 353 | int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); 354 | /* Version 3.39.0 and later */ 355 | int (*deserialize)(sqlite3*,const char*,unsigned char*, 356 | sqlite3_int64,sqlite3_int64,unsigned); 357 | unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, 358 | unsigned int); 359 | const char *(*db_name)(sqlite3*,int); 360 | /* Version 3.40.0 and later */ 361 | int (*value_encoding)(sqlite3_value*); 362 | /* Version 3.41.0 and later */ 363 | int (*is_interrupted)(sqlite3*); 364 | /* Version 3.43.0 and later */ 365 | int (*stmt_explain)(sqlite3_stmt*,int); 366 | }; 367 | 368 | /* 369 | ** This is the function signature used for all extension entry points. It 370 | ** is also defined in the file "loadext.c". 371 | */ 372 | typedef int (*sqlite3_loadext_entry)( 373 | sqlite3 *db, /* Handle to the database. */ 374 | char **pzErrMsg, /* Used to set error string on failure. */ 375 | const sqlite3_api_routines *pThunk /* Extension API function pointers. */ 376 | ); 377 | 378 | /* 379 | ** The following macros redefine the API routines so that they are 380 | ** redirected through the global sqlite3_api structure. 381 | ** 382 | ** This header file is also used by the loadext.c source file 383 | ** (part of the main SQLite library - not an extension) so that 384 | ** it can get access to the sqlite3_api_routines structure 385 | ** definition. But the main library does not want to redefine 386 | ** the API. So the redefinition macros are only valid if the 387 | ** SQLITE_CORE macros is undefined. 388 | */ 389 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) 390 | #define sqlite3_aggregate_context sqlite3_api->aggregate_context 391 | #ifndef SQLITE_OMIT_DEPRECATED 392 | #define sqlite3_aggregate_count sqlite3_api->aggregate_count 393 | #endif 394 | #define sqlite3_bind_blob sqlite3_api->bind_blob 395 | #define sqlite3_bind_double sqlite3_api->bind_double 396 | #define sqlite3_bind_int sqlite3_api->bind_int 397 | #define sqlite3_bind_int64 sqlite3_api->bind_int64 398 | #define sqlite3_bind_null sqlite3_api->bind_null 399 | #define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count 400 | #define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index 401 | #define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name 402 | #define sqlite3_bind_text sqlite3_api->bind_text 403 | #define sqlite3_bind_text16 sqlite3_api->bind_text16 404 | #define sqlite3_bind_value sqlite3_api->bind_value 405 | #define sqlite3_busy_handler sqlite3_api->busy_handler 406 | #define sqlite3_busy_timeout sqlite3_api->busy_timeout 407 | #define sqlite3_changes sqlite3_api->changes 408 | #define sqlite3_close sqlite3_api->close 409 | #define sqlite3_collation_needed sqlite3_api->collation_needed 410 | #define sqlite3_collation_needed16 sqlite3_api->collation_needed16 411 | #define sqlite3_column_blob sqlite3_api->column_blob 412 | #define sqlite3_column_bytes sqlite3_api->column_bytes 413 | #define sqlite3_column_bytes16 sqlite3_api->column_bytes16 414 | #define sqlite3_column_count sqlite3_api->column_count 415 | #define sqlite3_column_database_name sqlite3_api->column_database_name 416 | #define sqlite3_column_database_name16 sqlite3_api->column_database_name16 417 | #define sqlite3_column_decltype sqlite3_api->column_decltype 418 | #define sqlite3_column_decltype16 sqlite3_api->column_decltype16 419 | #define sqlite3_column_double sqlite3_api->column_double 420 | #define sqlite3_column_int sqlite3_api->column_int 421 | #define sqlite3_column_int64 sqlite3_api->column_int64 422 | #define sqlite3_column_name sqlite3_api->column_name 423 | #define sqlite3_column_name16 sqlite3_api->column_name16 424 | #define sqlite3_column_origin_name sqlite3_api->column_origin_name 425 | #define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 426 | #define sqlite3_column_table_name sqlite3_api->column_table_name 427 | #define sqlite3_column_table_name16 sqlite3_api->column_table_name16 428 | #define sqlite3_column_text sqlite3_api->column_text 429 | #define sqlite3_column_text16 sqlite3_api->column_text16 430 | #define sqlite3_column_type sqlite3_api->column_type 431 | #define sqlite3_column_value sqlite3_api->column_value 432 | #define sqlite3_commit_hook sqlite3_api->commit_hook 433 | #define sqlite3_complete sqlite3_api->complete 434 | #define sqlite3_complete16 sqlite3_api->complete16 435 | #define sqlite3_create_collation sqlite3_api->create_collation 436 | #define sqlite3_create_collation16 sqlite3_api->create_collation16 437 | #define sqlite3_create_function sqlite3_api->create_function 438 | #define sqlite3_create_function16 sqlite3_api->create_function16 439 | #define sqlite3_create_module sqlite3_api->create_module 440 | #define sqlite3_create_module_v2 sqlite3_api->create_module_v2 441 | #define sqlite3_data_count sqlite3_api->data_count 442 | #define sqlite3_db_handle sqlite3_api->db_handle 443 | #define sqlite3_declare_vtab sqlite3_api->declare_vtab 444 | #define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache 445 | #define sqlite3_errcode sqlite3_api->errcode 446 | #define sqlite3_errmsg sqlite3_api->errmsg 447 | #define sqlite3_errmsg16 sqlite3_api->errmsg16 448 | #define sqlite3_exec sqlite3_api->exec 449 | #ifndef SQLITE_OMIT_DEPRECATED 450 | #define sqlite3_expired sqlite3_api->expired 451 | #endif 452 | #define sqlite3_finalize sqlite3_api->finalize 453 | #define sqlite3_free sqlite3_api->free 454 | #define sqlite3_free_table sqlite3_api->free_table 455 | #define sqlite3_get_autocommit sqlite3_api->get_autocommit 456 | #define sqlite3_get_auxdata sqlite3_api->get_auxdata 457 | #define sqlite3_get_table sqlite3_api->get_table 458 | #ifndef SQLITE_OMIT_DEPRECATED 459 | #define sqlite3_global_recover sqlite3_api->global_recover 460 | #endif 461 | #define sqlite3_interrupt sqlite3_api->interruptx 462 | #define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid 463 | #define sqlite3_libversion sqlite3_api->libversion 464 | #define sqlite3_libversion_number sqlite3_api->libversion_number 465 | #define sqlite3_malloc sqlite3_api->malloc 466 | #define sqlite3_mprintf sqlite3_api->mprintf 467 | #define sqlite3_open sqlite3_api->open 468 | #define sqlite3_open16 sqlite3_api->open16 469 | #define sqlite3_prepare sqlite3_api->prepare 470 | #define sqlite3_prepare16 sqlite3_api->prepare16 471 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 472 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 473 | #define sqlite3_profile sqlite3_api->profile 474 | #define sqlite3_progress_handler sqlite3_api->progress_handler 475 | #define sqlite3_realloc sqlite3_api->realloc 476 | #define sqlite3_reset sqlite3_api->reset 477 | #define sqlite3_result_blob sqlite3_api->result_blob 478 | #define sqlite3_result_double sqlite3_api->result_double 479 | #define sqlite3_result_error sqlite3_api->result_error 480 | #define sqlite3_result_error16 sqlite3_api->result_error16 481 | #define sqlite3_result_int sqlite3_api->result_int 482 | #define sqlite3_result_int64 sqlite3_api->result_int64 483 | #define sqlite3_result_null sqlite3_api->result_null 484 | #define sqlite3_result_text sqlite3_api->result_text 485 | #define sqlite3_result_text16 sqlite3_api->result_text16 486 | #define sqlite3_result_text16be sqlite3_api->result_text16be 487 | #define sqlite3_result_text16le sqlite3_api->result_text16le 488 | #define sqlite3_result_value sqlite3_api->result_value 489 | #define sqlite3_rollback_hook sqlite3_api->rollback_hook 490 | #define sqlite3_set_authorizer sqlite3_api->set_authorizer 491 | #define sqlite3_set_auxdata sqlite3_api->set_auxdata 492 | #define sqlite3_snprintf sqlite3_api->xsnprintf 493 | #define sqlite3_step sqlite3_api->step 494 | #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata 495 | #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup 496 | #define sqlite3_total_changes sqlite3_api->total_changes 497 | #define sqlite3_trace sqlite3_api->trace 498 | #ifndef SQLITE_OMIT_DEPRECATED 499 | #define sqlite3_transfer_bindings sqlite3_api->transfer_bindings 500 | #endif 501 | #define sqlite3_update_hook sqlite3_api->update_hook 502 | #define sqlite3_user_data sqlite3_api->user_data 503 | #define sqlite3_value_blob sqlite3_api->value_blob 504 | #define sqlite3_value_bytes sqlite3_api->value_bytes 505 | #define sqlite3_value_bytes16 sqlite3_api->value_bytes16 506 | #define sqlite3_value_double sqlite3_api->value_double 507 | #define sqlite3_value_int sqlite3_api->value_int 508 | #define sqlite3_value_int64 sqlite3_api->value_int64 509 | #define sqlite3_value_numeric_type sqlite3_api->value_numeric_type 510 | #define sqlite3_value_text sqlite3_api->value_text 511 | #define sqlite3_value_text16 sqlite3_api->value_text16 512 | #define sqlite3_value_text16be sqlite3_api->value_text16be 513 | #define sqlite3_value_text16le sqlite3_api->value_text16le 514 | #define sqlite3_value_type sqlite3_api->value_type 515 | #define sqlite3_vmprintf sqlite3_api->vmprintf 516 | #define sqlite3_vsnprintf sqlite3_api->xvsnprintf 517 | #define sqlite3_overload_function sqlite3_api->overload_function 518 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 519 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 520 | #define sqlite3_clear_bindings sqlite3_api->clear_bindings 521 | #define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob 522 | #define sqlite3_blob_bytes sqlite3_api->blob_bytes 523 | #define sqlite3_blob_close sqlite3_api->blob_close 524 | #define sqlite3_blob_open sqlite3_api->blob_open 525 | #define sqlite3_blob_read sqlite3_api->blob_read 526 | #define sqlite3_blob_write sqlite3_api->blob_write 527 | #define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 528 | #define sqlite3_file_control sqlite3_api->file_control 529 | #define sqlite3_memory_highwater sqlite3_api->memory_highwater 530 | #define sqlite3_memory_used sqlite3_api->memory_used 531 | #define sqlite3_mutex_alloc sqlite3_api->mutex_alloc 532 | #define sqlite3_mutex_enter sqlite3_api->mutex_enter 533 | #define sqlite3_mutex_free sqlite3_api->mutex_free 534 | #define sqlite3_mutex_leave sqlite3_api->mutex_leave 535 | #define sqlite3_mutex_try sqlite3_api->mutex_try 536 | #define sqlite3_open_v2 sqlite3_api->open_v2 537 | #define sqlite3_release_memory sqlite3_api->release_memory 538 | #define sqlite3_result_error_nomem sqlite3_api->result_error_nomem 539 | #define sqlite3_result_error_toobig sqlite3_api->result_error_toobig 540 | #define sqlite3_sleep sqlite3_api->sleep 541 | #define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit 542 | #define sqlite3_vfs_find sqlite3_api->vfs_find 543 | #define sqlite3_vfs_register sqlite3_api->vfs_register 544 | #define sqlite3_vfs_unregister sqlite3_api->vfs_unregister 545 | #define sqlite3_threadsafe sqlite3_api->xthreadsafe 546 | #define sqlite3_result_zeroblob sqlite3_api->result_zeroblob 547 | #define sqlite3_result_error_code sqlite3_api->result_error_code 548 | #define sqlite3_test_control sqlite3_api->test_control 549 | #define sqlite3_randomness sqlite3_api->randomness 550 | #define sqlite3_context_db_handle sqlite3_api->context_db_handle 551 | #define sqlite3_extended_result_codes sqlite3_api->extended_result_codes 552 | #define sqlite3_limit sqlite3_api->limit 553 | #define sqlite3_next_stmt sqlite3_api->next_stmt 554 | #define sqlite3_sql sqlite3_api->sql 555 | #define sqlite3_status sqlite3_api->status 556 | #define sqlite3_backup_finish sqlite3_api->backup_finish 557 | #define sqlite3_backup_init sqlite3_api->backup_init 558 | #define sqlite3_backup_pagecount sqlite3_api->backup_pagecount 559 | #define sqlite3_backup_remaining sqlite3_api->backup_remaining 560 | #define sqlite3_backup_step sqlite3_api->backup_step 561 | #define sqlite3_compileoption_get sqlite3_api->compileoption_get 562 | #define sqlite3_compileoption_used sqlite3_api->compileoption_used 563 | #define sqlite3_create_function_v2 sqlite3_api->create_function_v2 564 | #define sqlite3_db_config sqlite3_api->db_config 565 | #define sqlite3_db_mutex sqlite3_api->db_mutex 566 | #define sqlite3_db_status sqlite3_api->db_status 567 | #define sqlite3_extended_errcode sqlite3_api->extended_errcode 568 | #define sqlite3_log sqlite3_api->log 569 | #define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 570 | #define sqlite3_sourceid sqlite3_api->sourceid 571 | #define sqlite3_stmt_status sqlite3_api->stmt_status 572 | #define sqlite3_strnicmp sqlite3_api->strnicmp 573 | #define sqlite3_unlock_notify sqlite3_api->unlock_notify 574 | #define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint 575 | #define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint 576 | #define sqlite3_wal_hook sqlite3_api->wal_hook 577 | #define sqlite3_blob_reopen sqlite3_api->blob_reopen 578 | #define sqlite3_vtab_config sqlite3_api->vtab_config 579 | #define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict 580 | /* Version 3.7.16 and later */ 581 | #define sqlite3_close_v2 sqlite3_api->close_v2 582 | #define sqlite3_db_filename sqlite3_api->db_filename 583 | #define sqlite3_db_readonly sqlite3_api->db_readonly 584 | #define sqlite3_db_release_memory sqlite3_api->db_release_memory 585 | #define sqlite3_errstr sqlite3_api->errstr 586 | #define sqlite3_stmt_busy sqlite3_api->stmt_busy 587 | #define sqlite3_stmt_readonly sqlite3_api->stmt_readonly 588 | #define sqlite3_stricmp sqlite3_api->stricmp 589 | #define sqlite3_uri_boolean sqlite3_api->uri_boolean 590 | #define sqlite3_uri_int64 sqlite3_api->uri_int64 591 | #define sqlite3_uri_parameter sqlite3_api->uri_parameter 592 | #define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf 593 | #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 594 | /* Version 3.8.7 and later */ 595 | #define sqlite3_auto_extension sqlite3_api->auto_extension 596 | #define sqlite3_bind_blob64 sqlite3_api->bind_blob64 597 | #define sqlite3_bind_text64 sqlite3_api->bind_text64 598 | #define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension 599 | #define sqlite3_load_extension sqlite3_api->load_extension 600 | #define sqlite3_malloc64 sqlite3_api->malloc64 601 | #define sqlite3_msize sqlite3_api->msize 602 | #define sqlite3_realloc64 sqlite3_api->realloc64 603 | #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension 604 | #define sqlite3_result_blob64 sqlite3_api->result_blob64 605 | #define sqlite3_result_text64 sqlite3_api->result_text64 606 | #define sqlite3_strglob sqlite3_api->strglob 607 | /* Version 3.8.11 and later */ 608 | #define sqlite3_value_dup sqlite3_api->value_dup 609 | #define sqlite3_value_free sqlite3_api->value_free 610 | #define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 611 | #define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 612 | /* Version 3.9.0 and later */ 613 | #define sqlite3_value_subtype sqlite3_api->value_subtype 614 | #define sqlite3_result_subtype sqlite3_api->result_subtype 615 | /* Version 3.10.0 and later */ 616 | #define sqlite3_status64 sqlite3_api->status64 617 | #define sqlite3_strlike sqlite3_api->strlike 618 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush 619 | /* Version 3.12.0 and later */ 620 | #define sqlite3_system_errno sqlite3_api->system_errno 621 | /* Version 3.14.0 and later */ 622 | #define sqlite3_trace_v2 sqlite3_api->trace_v2 623 | #define sqlite3_expanded_sql sqlite3_api->expanded_sql 624 | /* Version 3.18.0 and later */ 625 | #define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid 626 | /* Version 3.20.0 and later */ 627 | #define sqlite3_prepare_v3 sqlite3_api->prepare_v3 628 | #define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 629 | #define sqlite3_bind_pointer sqlite3_api->bind_pointer 630 | #define sqlite3_result_pointer sqlite3_api->result_pointer 631 | #define sqlite3_value_pointer sqlite3_api->value_pointer 632 | /* Version 3.22.0 and later */ 633 | #define sqlite3_vtab_nochange sqlite3_api->vtab_nochange 634 | #define sqlite3_value_nochange sqlite3_api->value_nochange 635 | #define sqlite3_vtab_collation sqlite3_api->vtab_collation 636 | /* Version 3.24.0 and later */ 637 | #define sqlite3_keyword_count sqlite3_api->keyword_count 638 | #define sqlite3_keyword_name sqlite3_api->keyword_name 639 | #define sqlite3_keyword_check sqlite3_api->keyword_check 640 | #define sqlite3_str_new sqlite3_api->str_new 641 | #define sqlite3_str_finish sqlite3_api->str_finish 642 | #define sqlite3_str_appendf sqlite3_api->str_appendf 643 | #define sqlite3_str_vappendf sqlite3_api->str_vappendf 644 | #define sqlite3_str_append sqlite3_api->str_append 645 | #define sqlite3_str_appendall sqlite3_api->str_appendall 646 | #define sqlite3_str_appendchar sqlite3_api->str_appendchar 647 | #define sqlite3_str_reset sqlite3_api->str_reset 648 | #define sqlite3_str_errcode sqlite3_api->str_errcode 649 | #define sqlite3_str_length sqlite3_api->str_length 650 | #define sqlite3_str_value sqlite3_api->str_value 651 | /* Version 3.25.0 and later */ 652 | #define sqlite3_create_window_function sqlite3_api->create_window_function 653 | /* Version 3.26.0 and later */ 654 | #define sqlite3_normalized_sql sqlite3_api->normalized_sql 655 | /* Version 3.28.0 and later */ 656 | #define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain 657 | #define sqlite3_value_frombind sqlite3_api->value_frombind 658 | /* Version 3.30.0 and later */ 659 | #define sqlite3_drop_modules sqlite3_api->drop_modules 660 | /* Version 3.31.0 and later */ 661 | #define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64 662 | #define sqlite3_uri_key sqlite3_api->uri_key 663 | #define sqlite3_filename_database sqlite3_api->filename_database 664 | #define sqlite3_filename_journal sqlite3_api->filename_journal 665 | #define sqlite3_filename_wal sqlite3_api->filename_wal 666 | /* Version 3.32.0 and later */ 667 | #define sqlite3_create_filename sqlite3_api->create_filename 668 | #define sqlite3_free_filename sqlite3_api->free_filename 669 | #define sqlite3_database_file_object sqlite3_api->database_file_object 670 | /* Version 3.34.0 and later */ 671 | #define sqlite3_txn_state sqlite3_api->txn_state 672 | /* Version 3.36.1 and later */ 673 | #define sqlite3_changes64 sqlite3_api->changes64 674 | #define sqlite3_total_changes64 sqlite3_api->total_changes64 675 | /* Version 3.37.0 and later */ 676 | #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages 677 | /* Version 3.38.0 and later */ 678 | #define sqlite3_error_offset sqlite3_api->error_offset 679 | #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value 680 | #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct 681 | #define sqlite3_vtab_in sqlite3_api->vtab_in 682 | #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first 683 | #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next 684 | /* Version 3.39.0 and later */ 685 | #ifndef SQLITE_OMIT_DESERIALIZE 686 | #define sqlite3_deserialize sqlite3_api->deserialize 687 | #define sqlite3_serialize sqlite3_api->serialize 688 | #endif 689 | #define sqlite3_db_name sqlite3_api->db_name 690 | /* Version 3.40.0 and later */ 691 | #define sqlite3_value_encoding sqlite3_api->value_encoding 692 | /* Version 3.41.0 and later */ 693 | #define sqlite3_is_interrupted sqlite3_api->is_interrupted 694 | /* Version 3.43.0 and later */ 695 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain 696 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ 697 | 698 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) 699 | /* This case when the file really is being compiled as a loadable 700 | ** extension */ 701 | # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; 702 | # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; 703 | # define SQLITE_EXTENSION_INIT3 \ 704 | extern const sqlite3_api_routines *sqlite3_api; 705 | #else 706 | /* This case when the file is being statically linked into the 707 | ** application */ 708 | # define SQLITE_EXTENSION_INIT1 /*no-op*/ 709 | # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ 710 | # define SQLITE_EXTENSION_INIT3 /*no-op*/ 711 | #endif 712 | 713 | #endif /* SQLITE3EXT_H */ 714 | -------------------------------------------------------------------------------- /images/Console.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ItaiShek/CC_Generator/2387c66ea1be18d411854bd5b5e9a6baabf099e1/images/Console.gif -------------------------------------------------------------------------------- /images/GUI.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ItaiShek/CC_Generator/2387c66ea1be18d411854bd5b5e9a6baabf099e1/images/GUI.gif -------------------------------------------------------------------------------- /include/API/Card.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * @class Card 10 | * @brief Represents a credit card with issuer information, length, and prefixes. 11 | * 12 | * The Card class provides functionality to parse numeric ranges and generate 13 | * random valid card numbers based on predefined parameters. 14 | */ 15 | class Card 16 | { 17 | public: 18 | // constructors 19 | Card() = default; 20 | 21 | /** 22 | * @brief Parameterized constructor. 23 | * @param issuer The issuer of the card. 24 | * @param len The length of the card number. 25 | * @param prefixes The numeric prefixes associated with the card. 26 | */ 27 | Card(const std::string &issuer, int len, const std::string &prefixes) : m_issuer{issuer}, m_len{len}, m_prefixes{prefixes} { parse_ranges(prefixes); } 28 | 29 | // getters 30 | const std::string get_issuer() const { return m_issuer; } 31 | const int get_len() const { return m_len; } 32 | const std::string get_prefixes() const { return m_prefixes; } 33 | 34 | // setters 35 | void set_issuer(const std::string &issuer) { m_issuer = issuer; } 36 | void set_len(int len) { m_len = len; } 37 | void set_prefixes(const std::string &prefixes) { m_prefixes = prefixes; } 38 | 39 | // other methods 40 | bool empty() const { return m_issuer.empty() || m_prefixes.empty() || m_len == 0; } 41 | 42 | bool operator==(const Card &c) const 43 | { 44 | return (c.m_issuer == m_issuer && c.m_len == m_len && c.m_prefixes == m_prefixes); 45 | } 46 | 47 | // Parses a string representing numeric ranges and populates the Card object. 48 | void parse_ranges(const std::string &ranges_str); 49 | 50 | // Generates a random card number based on predefined ranges and Luhn's algorithm. 51 | // Appends the generated card number to the provided std::ostringstream. 52 | void generate_card(std::ostringstream &oss) const; 53 | 54 | // Validates a credit card based on issuer, length, and prefixes. 55 | static bool validate_card(const std::string &issuer, int length, const std::string &prefixes); 56 | 57 | // Validates the issuer of a credit card. 58 | static bool validate_issuer(const std::string &issuer); 59 | 60 | // Validates the prefix of a credit card based on its length. 61 | static bool validate_prefix(const std::string &prefix, int len); 62 | 63 | // Validates the length of a credit card number. 64 | static bool validate_length(int len); 65 | 66 | static void generate_cvv(const char delimiter, std::ostringstream &oss); 67 | static void generate_date(const char delimiter, std::chrono::year_month_day start, std::chrono::year_month_day end, std::ostringstream &oss); 68 | 69 | private: 70 | std::string m_issuer{}; // The issuer of the card. 71 | int m_len{}; // The length of the card number. 72 | std::string m_prefixes{}; // The numeric prefixes associated with the card. 73 | std::vector> m_ranges; // Parsed numeric ranges. 74 | static std::mt19937 m_rng; 75 | }; -------------------------------------------------------------------------------- /include/API/DB_API.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "sqlite3.h" 8 | #include "Card.h" 9 | 10 | /** 11 | * @namespace DB_API 12 | * @brief Provides functions for interacting with an SQLite database and managing credit card data. 13 | * 14 | * The DB_API namespace contains functions for various database-related operations 15 | * such as checking file existence, reading an SQLite database, and writing/reading 16 | * credit card data. It encapsulates all related database utilities in a single, logical scope. 17 | */ 18 | namespace DB_API 19 | { 20 | // Checks if a file exists. 21 | bool check_file_exists(const std::string &filename); 22 | 23 | // Reads an SQLite database and returns a shared pointer to it. 24 | std::shared_ptr read_db(const std::string &db_path); 25 | 26 | // Writes credit card data to the database, updating existing entries. 27 | int write_cards(std::shared_ptr db, const std::vector &data, std::string &error_msg); 28 | 29 | // Reads credit card data from the database and stores it in a vector. 30 | int read_cards(std::shared_ptr db, std::vector &data, std::string &error_msg); 31 | 32 | // Reads a random first and last name and returns it as a string. 33 | std::string get_random_name(std::shared_ptr db); 34 | }; -------------------------------------------------------------------------------- /include/API/Date.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * @namespace Date 6 | * @brief Provides utility functions for working with dates, including validation, conversion, and date calculations. 7 | * 8 | * This namespace contains functions for handling dates, such as determining the number of days in a month, 9 | * validating if one date is earlier than another, converting a date to a string, and constructing date objects 10 | * from day, month, and year values. 11 | */ 12 | namespace Date 13 | { 14 | // Returns the number of days in a given month and year. 15 | int days_in_month(int year, int month); 16 | 17 | // Constructs a std::chrono::year_month_day object from day, month, and year values. 18 | std::chrono::year_month_day get_date_from_ymd(unsigned int d, unsigned int m, int y); 19 | 20 | // Validates that a second date is not earlier than the first date. 21 | bool vali_date(int d1, int m1, int y1, int d2, int m2, int y2); 22 | 23 | // Converts a std::chrono::year_month_day object to a string. 24 | std::string string_from_date(std::chrono::year_month_day date); 25 | } -------------------------------------------------------------------------------- /include/API/File.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #ifdef __EMSCRIPTEN__ 15 | #include 16 | #endif 17 | 18 | #include "sqlite3.h" 19 | #include "Card.h" 20 | #include "DB_API.h" 21 | 22 | extern std::atomic g_paused; 23 | extern std::atomic g_started; 24 | extern std::atomic g_progress; 25 | std::atomic export_finished = false; 26 | 27 | /** 28 | * @struct date_struct 29 | * @brief Represents a date range with a generation flag. 30 | * 31 | * This structure holds a flag that determines whether a date range should be generated, along with the 32 | * start and end dates of the range. The dates are represented using `std::chrono::year_month_day`. 33 | */ 34 | struct date_struct 35 | { 36 | /** 37 | * @brief Start date of the range. 38 | * 39 | * This field holds the start date of the range, represented as `std::chrono::year_month_day`. 40 | */ 41 | std::chrono::year_month_day start{std::chrono::year_month_day{std::chrono::floor(std::chrono::system_clock::now())}}; // current date 42 | 43 | /** 44 | * @brief End date of the range. 45 | * 46 | * This field holds the end date of the range, represented as `std::chrono::year_month_day`. 47 | */ 48 | std::chrono::year_month_day end{start + std::chrono::years{3}}; // 3 years from now 49 | }; 50 | 51 | /** 52 | * @class File 53 | * @brief Represents a file-related utility class. 54 | * 55 | * This class provides methods for exporting cards, estimating time, and estimating size. 56 | */ 57 | class File 58 | { 59 | public: 60 | /** 61 | * @brief Retrieves the indices of true values in a boolean vector. 62 | * 63 | * This function takes a boolean vector as input and returns a vector containing the indices 64 | * of the true values in the input vector. 65 | * 66 | * @param vec A boolean vector to process. 67 | * @return A vector containing the indices of true values in the input vector. 68 | * 69 | */ 70 | static std::vector get_true_vec(const std::vector &vec) 71 | { 72 | std::vector true_vec; 73 | 74 | for (int i{}; i < vec.size(); i++) 75 | { 76 | if (vec[i]) 77 | { 78 | true_vec.push_back(i); 79 | } 80 | } 81 | return true_vec; 82 | } 83 | 84 | /** 85 | * @brief Chooses a random index from a vector of integers. 86 | * 87 | * This function takes a vector of integers as input and returns a randomly chosen index 88 | * from that vector. The randomness is determined using a uniform distribution. 89 | * 90 | * @param vec A vector of integers from which to choose a random index. 91 | * @return A randomly selected index from the input vector. 92 | * 93 | */ 94 | static int choose_random_index(const std::vector &vec) 95 | { 96 | if (vec.empty()) 97 | { 98 | return -1; 99 | } 100 | 101 | std::uniform_int_distribution dist(0, static_cast(vec.size() - 1)); 102 | return vec[dist(m_gen)]; 103 | } 104 | 105 | /** 106 | * @brief Exports a specified number of randomly selected cards to a file. 107 | * 108 | * This templated function exports a specified number of randomly selected cards from 109 | * the provided vector to the given file. It uses a selection vector to determine which 110 | * cards to export. The export is performed in chunks to enhance performance. 111 | * 112 | * @tparam T The type of the amount parameter. 113 | * @param file An output file stream to write the exported cards. 114 | * @param cards_vec A vector containing the cards to choose from. 115 | * @param selection_vec A vector of boolean values indicating the selection status of cards. 116 | * @param amount The number of cards to export. 117 | * @param db A shared pointer to the database. 118 | * 119 | */ 120 | template 121 | static void export_cards(std::ofstream &file, const std::vector &cards_vec, const std::vector &selection_vec, T amount, std::shared_ptr db) 122 | { 123 | constexpr int chunk = 4096; 124 | std::vector indexes_vec{get_true_vec(selection_vec)}; 125 | std::ostringstream oss(std::ios_base::ate); 126 | T size{}; 127 | int rnd_idx{}; 128 | T i; 129 | for (i = 0; i < amount; i++) 130 | { 131 | while (g_paused) 132 | { 133 | std::this_thread::sleep_for(std::chrono::milliseconds(250)); 134 | if (g_started == false) 135 | { 136 | break; 137 | } 138 | } 139 | if (g_started == false) 140 | { 141 | break; 142 | } 143 | rnd_idx = choose_random_index(indexes_vec); 144 | cards_vec[rnd_idx].generate_card(oss); 145 | 146 | if (m_cvv_flag) 147 | { 148 | Card::generate_cvv(m_delimiter, oss); 149 | } 150 | 151 | if (m_date_flag) 152 | { 153 | Card::generate_date(m_delimiter, m_date.start, m_date.end, oss); 154 | } 155 | 156 | if (m_name_flag and db != nullptr) 157 | { 158 | std::string name = DB_API::get_random_name(db); 159 | if (name.empty() == false) 160 | { 161 | oss << m_delimiter; 162 | oss << name; 163 | } 164 | } 165 | 166 | oss << "\n"; 167 | 168 | // write chunk to file 169 | if (oss.tellp() > chunk) 170 | { 171 | // Extract and write the first "chunk" bytes 172 | file << oss.str().substr(0, chunk); 173 | 174 | // Remove the bytes from the stringstream 175 | oss.str(oss.str().substr(chunk)); 176 | 177 | // update the progress bar value 178 | g_progress = static_cast(i) / amount; 179 | } 180 | } 181 | 182 | // Write any remaining content in the stringstream 183 | if (g_started) 184 | { 185 | // int size = oss.tellp(); 186 | std::streamoff size = oss.tellp(); 187 | 188 | if (size > 0) 189 | { 190 | size -= 1; 191 | oss.str(oss.str().substr(0, size)); 192 | } 193 | file << oss.str(); 194 | g_progress = static_cast(i) / amount; 195 | } 196 | 197 | file.close(); 198 | g_started = false; 199 | } 200 | 201 | /** 202 | * @brief Estimates the time taken to generate a single card. 203 | * 204 | * This templated function estimates the time taken to generate a single card 205 | * using a temporary card object and a specified number of iterations. The time 206 | * is calculated by measuring the duration it takes to generate the card the 207 | * specified number of times and then dividing by the number of iterations. 208 | * 209 | * @tparam T The duration type (e.g., std::chrono::milliseconds, std::chrono::seconds). 210 | * @return The estimated time taken to generate a single card. 211 | * 212 | */ 213 | template 214 | static T estimate_time() 215 | { 216 | Card temp_card = Card{"temp", 16, "1,2,3,4,5-6"}; 217 | size_t div{1000}; 218 | size_t i{}; 219 | T duration{}; 220 | std::ostringstream temp_oss; 221 | auto start{std::chrono::high_resolution_clock::now()}; 222 | for (i = 0; i < div; i++) 223 | { 224 | temp_card.generate_card(temp_oss); 225 | } 226 | auto end{std::chrono::high_resolution_clock::now()}; 227 | 228 | return std::chrono::duration_cast(end - start) / div; 229 | } 230 | 231 | /** 232 | * @brief Estimates the average time to generate a CVV using the Card::generate_cvv function. 233 | * 234 | * This function measures the time taken to generate a CVV using the `Card::generate_cvv` 235 | * function multiple times (defaulted to 1000 iterations). It calculates the average time 236 | * per CVV generation and returns it in the specified duration type. 237 | * 238 | * @tparam T The type of duration to return (e.g., std::chrono::milliseconds). 239 | * @return The average time taken to generate a CVV, in the specified duration type. 240 | * 241 | * @see Card::generate_cvv 242 | */ 243 | template 244 | static T estimate_cvv_time() 245 | { 246 | size_t div{1000}; 247 | size_t i{}; 248 | T duration{}; 249 | std::ostringstream temp_oss; 250 | auto start{std::chrono::high_resolution_clock::now()}; 251 | for (i = 0; i < div; i++) 252 | { 253 | Card::generate_cvv(m_delimiter, temp_oss); 254 | } 255 | auto end{std::chrono::high_resolution_clock::now()}; 256 | 257 | return std::chrono::duration_cast(end - start) / div; 258 | } 259 | 260 | /** 261 | * @brief Estimates the average time to generate a date using the Card::generate_date function. 262 | * 263 | * This function measures the time taken to generate a date using the `Card::generate_date` 264 | * function multiple times (defaulted to 1000 iterations). It calculates the average time 265 | * per generation and returns it in the specified duration type. 266 | * 267 | * @tparam T The type of duration to return (e.g., std::chrono::milliseconds). 268 | * @return The average time taken to generate a date, in the specified duration type. 269 | * 270 | * @see Card::generate_date 271 | */ 272 | template 273 | static T estimate_date_time() 274 | { 275 | size_t div{1000}; 276 | size_t i{}; 277 | T duration{}; 278 | std::ostringstream temp_oss; 279 | auto start{std::chrono::high_resolution_clock::now()}; 280 | for (i = 0; i < div; i++) 281 | { 282 | Card::generate_date(m_delimiter, m_date.start, m_date.end, temp_oss); 283 | } 284 | auto end{std::chrono::high_resolution_clock::now()}; 285 | 286 | return std::chrono::duration_cast(end - start) / div; 287 | } 288 | 289 | /** 290 | * @brief Estimates the average time to retrieve a random name from the database. 291 | * 292 | * This function measures the time taken to retrieve a random name from the 293 | * database multiple times (defaulted to 10 iterations). It calculates the 294 | * average time per retrieval and returns it in the specified duration type. 295 | * If any condition fails (e.g., the database does not exist, cannot be opened, 296 | * or no names are found), it returns a zero duration. 297 | * 298 | * @tparam T The type of duration to return (e.g., std::chrono::milliseconds). 299 | * @param db_path The path to the database file. 300 | * @return The average time taken to retrieve a random name from the database, in the specified duration type. 301 | * 302 | * @see DB_API::check_file_exists 303 | * @see DB_API::read_db 304 | * @see DB_API::get_random_name 305 | */ 306 | template 307 | static T estimate_name_time(std::string db_path) 308 | { 309 | size_t div{10}; 310 | size_t i{}; 311 | T duration{}; 312 | std::ostringstream temp_oss; 313 | 314 | if (DB_API::check_file_exists(db_path) == false) 315 | { 316 | return std::chrono::duration_cast(T{0}); 317 | } 318 | 319 | std::shared_ptr db{DB_API::read_db(db_path)}; 320 | 321 | if (db == nullptr) 322 | { 323 | return std::chrono::duration_cast(T{0}); 324 | } 325 | 326 | if (DB_API::get_random_name(db).empty()) 327 | { 328 | return std::chrono::duration_cast(T{0}); 329 | } 330 | 331 | auto start{std::chrono::high_resolution_clock::now()}; 332 | for (i = 0; i < div; i++) 333 | { 334 | DB_API::get_random_name(db); 335 | } 336 | auto end{std::chrono::high_resolution_clock::now()}; 337 | 338 | return std::chrono::duration_cast(end - start) / div; 339 | } 340 | 341 | /** 342 | * @brief Formats a time string for a given duration. 343 | * 344 | * This function takes a std::chrono::... as input and returns a formatted string of it. 345 | * 346 | * @param duration The duration to format. 347 | * @return The formatted duration string as "X Years Y Months Z Days Hours:Minutes:Seconds:Milliseconds". 348 | */ 349 | template 350 | static inline std::string format_time(T duration) 351 | { 352 | std::ostringstream estimated_time; 353 | 354 | auto years{std::chrono::duration_cast>>(duration)}; 355 | duration -= std::chrono::duration_cast>>(years); 356 | 357 | auto months{std::chrono::duration_cast>>(duration)}; 358 | duration -= std::chrono::duration_cast(months); 359 | 360 | auto days{std::chrono::duration_cast>>(duration)}; 361 | duration -= std::chrono::duration_cast(days); 362 | 363 | auto hours{std::chrono::duration_cast(duration)}; 364 | duration -= std::chrono::duration_cast(hours); 365 | 366 | auto minutes{std::chrono::duration_cast(duration)}; 367 | duration -= std::chrono::duration_cast(minutes); 368 | 369 | auto seconds{std::chrono::duration_cast(duration)}; 370 | duration -= std::chrono::duration_cast(seconds); 371 | 372 | auto milliseconds{std::chrono::duration_cast(duration)}; 373 | 374 | if (years.count() > 0) 375 | { 376 | estimated_time << std::to_string(years.count()) << " years "; 377 | } 378 | if (months.count() > 0) 379 | { 380 | estimated_time << std::to_string(months.count()) << " months "; 381 | } 382 | if (days.count() > 0) 383 | { 384 | estimated_time << std::to_string(days.count()) << " days "; 385 | } 386 | 387 | estimated_time 388 | << std::setw(2) << std::setfill('0') << hours.count() << ":" 389 | << std::setw(2) << std::setfill('0') << minutes.count() << ":" 390 | << std::setw(2) << std::setfill('0') << seconds.count() << ":" 391 | << std::setw(3) << std::setfill('0') << milliseconds.count(); 392 | 393 | return estimated_time.str(); 394 | } 395 | 396 | /** 397 | * @brief Estimates the size in human-readable format based on the given amount. 398 | * 399 | * This templated function estimates the size in a human-readable format (e.g., B, KB, MB) 400 | * based on the provided amount. The size is calculated by multiplying the amount with the 401 | * size of a representative string and then converting it to a suitable unit. 402 | * 403 | * @tparam T The type of the amount parameter. 404 | * @param amount The amount for which to estimate the size. 405 | * @return A string representing the estimated size in human-readable format. 406 | * 407 | */ 408 | template 409 | static inline std::string estimate_size(T amount) 410 | { 411 | constexpr double name_size{15}; 412 | constexpr double cvv_size{4}; 413 | constexpr double date_size{11}; 414 | constexpr double card_size{17}; 415 | 416 | double total_size = card_size; 417 | total_size += m_cvv_flag ? cvv_size : 0; 418 | total_size += m_name_flag ? name_size : 0; 419 | total_size += m_date_flag ? date_size : 0; 420 | 421 | double size{amount * total_size}; 422 | static std::array sizes{"B", "KB", "MB", "GB", "TB"}; 423 | size_t si{}; 424 | 425 | for (si = 0; si < sizes.size(); si++) 426 | { 427 | if (size < 1024) 428 | { 429 | break; 430 | } 431 | size /= 1024.0f; 432 | } 433 | si = si < sizes.size() ? si : sizes.size() - 1; 434 | 435 | return std::to_string(size) + " [" + sizes[si] + "]"; 436 | } 437 | 438 | #ifdef __EMSCRIPTEN__ 439 | 440 | /** 441 | * @brief Holds the state for an ongoing export operation. 442 | * 443 | * This structure stores all necessary information required to manage 444 | * the asynchronous export process, including output buffering, 445 | * progress tracking, card selection, and file destination. 446 | */ 447 | struct ExportState 448 | { 449 | std::ostringstream oss; ///< Output buffer used to accumulate export content. 450 | int i = 0; ///< Current export iteration index. 451 | int amount; ///< Total number of cards to export. 452 | std::vector cards_vec; ///< Vector of available cards to export from. 453 | std::vector selection_vec; ///< Selection vector indicating which cards are selected. 454 | std::shared_ptr db; ///< Shared pointer to the SQLite database for name generation. 455 | std::vector indexes_vec; ///< Precomputed list of selected indexes for efficient access. 456 | std::string vfs_path; ///< Virtual filesystem path where the output file will be written. 457 | }; 458 | 459 | /** 460 | * @brief Performs a single asynchronous step in the card export process. 461 | * 462 | * This function is designed to be repeatedly scheduled with `emscripten_async_call` 463 | * to allow non-blocking export of card data to the virtual file system (VFS). 464 | * 465 | * It checks for pause and stop signals, writes data in chunks to avoid memory issues, 466 | * and finalizes the export by flushing the remaining content once all items are processed. 467 | * 468 | * @param Unused A dummy pointer required by `emscripten_async_call`. Ignored in this implementation. 469 | */ 470 | static void export_step(void *) 471 | { 472 | if (g_started == false || export_state == nullptr) 473 | return; 474 | 475 | constexpr int chunk = 4096; 476 | auto &s = *export_state; 477 | 478 | if (g_paused) 479 | { 480 | emscripten_async_call(export_step, nullptr, 250); 481 | return; 482 | } 483 | 484 | if (s.i >= s.amount) 485 | { 486 | // Write any remaining content in the stringstream before closing file 487 | std::streamoff size = s.oss.tellp(); 488 | 489 | if (size > 0) 490 | { 491 | size -= 1; 492 | std::ofstream file(s.vfs_path, std::ios::app); // append mode 493 | s.oss.str(s.oss.str().substr(0, size)); 494 | file << s.oss.str(); 495 | file.close(); 496 | } 497 | 498 | export_finished = true; 499 | g_progress = 1.0f; 500 | g_started = false; 501 | delete export_state; 502 | export_state = nullptr; 503 | return; 504 | } 505 | 506 | int rnd_idx = choose_random_index(s.indexes_vec); 507 | s.cards_vec[rnd_idx].generate_card(s.oss); 508 | 509 | if (m_cvv_flag) 510 | Card::generate_cvv(m_delimiter, s.oss); 511 | if (m_date_flag) 512 | Card::generate_date(m_delimiter, m_date.start, m_date.end, s.oss); 513 | if (m_name_flag && s.db) 514 | { 515 | std::string name = DB_API::get_random_name(s.db); 516 | if (name.empty() == false) 517 | { 518 | s.oss << m_delimiter << name; 519 | } 520 | } 521 | 522 | s.oss << "\n"; 523 | 524 | if (s.oss.tellp() > chunk) 525 | { 526 | std::ofstream file(s.vfs_path, std::ios::app); 527 | file << s.oss.str().substr(0, chunk); 528 | file.close(); 529 | s.oss.str(s.oss.str().substr(chunk)); 530 | } 531 | 532 | g_progress = static_cast(s.i) / s.amount; 533 | s.i++; 534 | 535 | emscripten_async_call(export_step, nullptr, 0); // Schedule next chunk 536 | } 537 | 538 | /** 539 | * @brief Initializes and starts the asynchronous export process. 540 | * 541 | * This function prepares the internal export state, clears the target file in the virtual file system (VFS), 542 | * and begins the asynchronous card export routine via `emscripten_async_call`. 543 | * 544 | * @param cards A vector of `Card` objects used to generate the exported data. 545 | * @param selection A vector of booleans indicating which cards are selected for export. 546 | * @param amount The number of cards to export. 547 | * @param db A shared pointer to the SQLite3 database used for generating additional card data (e.g., names). 548 | * @param vfs_path The VFS path where the export file will be written. This file is truncated at the beginning. 549 | */ 550 | static void start_export(const std::vector &cards, const std::vector &selection, int amount, std::shared_ptr db, const std::string &vfs_path) 551 | { 552 | // Overwrite (truncate) the file at the start 553 | std::ofstream truncate_file(vfs_path); 554 | truncate_file.close(); 555 | 556 | export_state = new ExportState{ 557 | std::ostringstream(std::ios_base::ate), 558 | 0, 559 | amount, 560 | cards, 561 | selection, 562 | db, 563 | get_true_vec(selection), 564 | vfs_path}; 565 | 566 | g_started = true; 567 | export_finished = false; 568 | emscripten_async_call(export_step, nullptr, 0); 569 | } 570 | 571 | static inline ExportState *export_state{nullptr}; 572 | #endif 573 | 574 | static std::mt19937 m_gen; 575 | static inline date_struct m_date; 576 | static inline char m_delimiter{';'}; 577 | static inline bool m_date_flag{false}; 578 | static inline bool m_cvv_flag{false}; 579 | static inline bool m_name_flag{false}; 580 | File() = delete; 581 | }; 582 | -------------------------------------------------------------------------------- /include/Console/Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace console 5 | { 6 | /** 7 | * @brief Function signature for the console application entry point. 8 | * 9 | * This function is the entry point for the console application and is meant 10 | * to be called from external code to start the application. 11 | * 12 | * @param version A string representing the version information. 13 | * @param url A string containing the URL information. 14 | * @param license A string containing the license information. 15 | */ 16 | void run(const std::string& version, const std::string& url, const std::string& license); 17 | } -------------------------------------------------------------------------------- /include/GUI/GUI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace gui 5 | { 6 | /** 7 | * @brief Function signature for the GUI application entry point. 8 | * 9 | * This function is the entry point for the GUI application and is meant 10 | * to be called from external code to start the application. 11 | * 12 | * @param version A string representing the version information. 13 | * @param url A string containing the URL information. 14 | * @param license A string containing the license information. 15 | */ 16 | void run(const std::string& version, const std::string& url, const std::string& license); 17 | } -------------------------------------------------------------------------------- /src/API/Card.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "Card.h" 5 | 6 | std::mt19937 Card::m_rng{std::random_device{}()}; 7 | 8 | /** 9 | * @brief Parses a string representing numeric ranges and populates the Card object. 10 | * 11 | * This function takes a string containing comma-separated numeric ranges and parses 12 | * them, populating the Card object with the extracted ranges. 13 | * 14 | * The input string should have the format "start-end,start-end,..." where start and 15 | * end are integers defining a numeric range. If a single number is provided without 16 | * a dash, it is considered a range with the same start and end values. 17 | * 18 | * @param ranges_str A string containing comma-separated numeric ranges. 19 | * 20 | * @note The function assumes a valid input format. No input validation is performed. 21 | * 22 | * @see Card 23 | */ 24 | void Card::parse_ranges(const std::string &ranges_str) 25 | { 26 | std::istringstream iss(ranges_str); 27 | std::string range_token; 28 | while (std::getline(iss, range_token, ',')) 29 | { 30 | std::istringstream range_stream(range_token); 31 | int start, end; 32 | char dash; 33 | range_stream >> start; 34 | if (range_stream >> dash >> end) 35 | { 36 | // range case 37 | m_ranges.emplace_back(start, end); 38 | } 39 | else 40 | { 41 | // single number case 42 | m_ranges.emplace_back(start, start); 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * @brief Generates a random card number based on predefined ranges and Luhn's algorithm. 49 | * 50 | * This function generates a random card number within the predefined numeric ranges 51 | * associated with the Card object. It utilizes a combination of random number generation, 52 | * Luhn's algorithm, and predefined ranges to create a valid card number. 53 | * 54 | * The generated card number is appended to the provided std::ostringstream. 55 | * 56 | * @param oss The std::ostringstream to which the generated card number is appended. 57 | * 58 | * @note The function assumes that the Card object has valid ranges and length parameters. 59 | * It uses a random number generator (m_rng) associated with the Card object. 60 | * The generated card number adheres to Luhn's algorithm for validity. 61 | * 62 | * @see Card 63 | * @see parse_ranges() 64 | */ 65 | void Card::generate_card(std::ostringstream &oss) const 66 | { 67 | // Randomly select a range 68 | std::uniform_int_distribution range_dist(0, m_ranges.size() - 1); 69 | const auto &range = m_ranges[range_dist(m_rng)]; 70 | 71 | // Generate a random number within the selected range 72 | std::uniform_int_distribution num_dist(range.first, range.second); 73 | int prefix{num_dist(m_rng)}; 74 | 75 | // Generate a random card 76 | std::string rnd_card{std::to_string(prefix)}; 77 | std::uniform_int_distribution dis(0, 9); 78 | 79 | // Reserve memory for the string to avoid reallocations 80 | rnd_card.reserve(m_len); 81 | 82 | for (int i = rnd_card.size(); i < m_len - 1; i++) 83 | { 84 | rnd_card += '0' + dis(m_rng); 85 | } 86 | 87 | // Apply Luhn's algorithm to generate the last digit 88 | int sum{0}; 89 | bool double_digit{true}; 90 | 91 | for (int i{m_len - 2}; i >= 0; i--) 92 | { 93 | int digit = rnd_card[i] - '0'; 94 | 95 | if (double_digit && (digit *= 2) >= 10) 96 | { 97 | digit -= 9; 98 | } 99 | 100 | sum += digit; 101 | double_digit = !double_digit; 102 | } 103 | 104 | // Calculate the last digit to make the entire number valid 105 | rnd_card += '0' + ((10 - (sum % 10)) % 10); 106 | oss << rnd_card; 107 | } 108 | 109 | /** 110 | * @brief Validates the issuer string. 111 | * 112 | * This function checks if the provided issuer string contains at least one non-whitespace character. 113 | * Whitespace characters include space, tab, newline, vertical tab, form feed, and carriage return. 114 | * 115 | * @param issuer The issuer string to be validated. 116 | * @return true if the issuer string contains at least one non-whitespace character, false otherwise. 117 | * 118 | * @note This function considers whitespace characters to be any of the following: space, tab, newline, 119 | * vertical tab, form feed, or carriage return. 120 | */ 121 | bool Card::validate_issuer(const std::string &issuer) 122 | { 123 | return issuer.find_first_not_of(" \t\n\v\f\r") != std::string::npos; 124 | } 125 | 126 | /** 127 | * @brief Validates a comma-separated string of numeric prefixes according to specific rules. 128 | * 129 | * This function validates a comma-separated string of numeric prefixes based on the following rules: 130 | * 1. Each token separated by a comma must be a non-empty string. 131 | * 2. Tokens cannot end with a comma. 132 | * 3. Each token must represent either a single numeric value or a numeric range in the format "start-end". 133 | * 4. Numeric ranges must be in increasing order. 134 | * 5. Numeric values and ranges must be positive integers and must not exceed the specified length. 135 | * 136 | * @param prefix The comma-separated string of numeric prefixes to be validated. 137 | * @param len The maximum length that a valid prefix can have. 138 | * @return true if the input string conforms to the specified rules, false otherwise. 139 | * 140 | * @details This function takes a comma-separated string of numeric prefixes and validates each token 141 | * separately. It checks if each token is a valid positive integer or a valid numeric range with a 142 | * start value less than or equal to the end value. It also ensures that the length of the prefix does 143 | * not exceed the specified maximum length. 144 | * 145 | */ 146 | bool Card::validate_prefix(const std::string &prefix, int len) 147 | { 148 | if (prefix.empty()) 149 | { 150 | return false; 151 | } 152 | if (prefix[prefix.size() - 1] == ',') 153 | { 154 | return false; 155 | } 156 | 157 | std::stringstream ss(prefix); 158 | std::string token; 159 | 160 | while (std::getline(ss, token, ',')) 161 | { 162 | size_t start{token.find_first_not_of(" ")}; 163 | size_t end{token.find_last_not_of(" ")}; 164 | 165 | // if it's empty return false 166 | if (start == std::string::npos || end == std::string::npos) 167 | { 168 | return false; 169 | } 170 | 171 | token = token.substr(start, end - start + 1); 172 | 173 | // range 174 | if (std::regex_match(token, std::regex(R"(\d+\-\d+)"))) 175 | { 176 | std::istringstream iss(token); 177 | int start, end; 178 | char dash; 179 | iss >> start >> dash >> end; 180 | // Range is not in increasing order 181 | if (end < start) 182 | { 183 | return false; 184 | } 185 | // the prefix is larger than the length 186 | if (std::to_string(start).length() > len || std::to_string(end).length() > len || start == 0) 187 | { 188 | return false; 189 | } 190 | } 191 | // digit 192 | else if (std::regex_match(token, std::regex(R"(\d+)"))) 193 | { 194 | // the prefix is larger than the length or if it's zero 195 | if (token.size() > len || std::stoi(token.c_str()) == 0) 196 | { 197 | return false; 198 | } 199 | } 200 | // NaN or negative number 201 | else 202 | { 203 | return false; 204 | } 205 | } 206 | 207 | return true; 208 | } 209 | 210 | /** 211 | * @brief Validates the length of a credit card number. 212 | * 213 | * This function checks whether the provided length is within the valid range 214 | * for a credit card number. Credit card numbers typically have lengths between 215 | * 2 and 32 characters (inclusive). 216 | * 217 | * @param len The length of the credit card number to be validated. 218 | * @return True if the length is within the valid range, false otherwise. 219 | */ 220 | bool Card::validate_length(int len) 221 | { 222 | return len >= 2 && len <= 32; 223 | } 224 | 225 | /** 226 | * @brief Validates a credit card based on issuer, length, and prefixes. 227 | * 228 | * This function checks whether a credit card is valid by validating the issuer, 229 | * length, and prefixes. It combines three validation checks: issuer validation, 230 | * length validation, and prefix validation. 231 | * 232 | * @param issuer The issuer of the credit card. 233 | * @param length The expected length of the credit card number. 234 | * @param prefixes The valid prefixes for the credit card. 235 | * @return True if the credit card is valid, false otherwise. 236 | * 237 | * @see DB_API::validate_issuer() For issuer validation. 238 | * @see DB_API::validate_length() For length validation. 239 | * @see DB_API::validate_prefix() For prefix validation. 240 | * 241 | * @note This function assumes that the individual validation functions are 242 | * implemented and correctly check the issuer, length, and prefixes. 243 | */ 244 | bool Card::validate_card(const std::string &issuer, int length, const std::string &prefixes) 245 | { 246 | return (Card::validate_issuer(issuer) && 247 | Card::validate_length(length) && 248 | Card::validate_prefix(prefixes, length)); 249 | } 250 | 251 | /** 252 | * @brief Generates a 3-digit CVV and appends it to the provided string stream. 253 | * 254 | * This function generates a 3-digit CVV using random numbers between 0 and 9, appends 255 | * it to the given string stream (`std::ostringstream`), and separates the CVV with the 256 | * specified delimiter. 257 | * 258 | * @param delimiter The character used to separate the CVV from other content in the stream. 259 | * @param oss The output string stream where the generated CVV will be appended. 260 | * 261 | * @see std::uniform_int_distribution 262 | */ 263 | void Card::generate_cvv(const char delimiter, std::ostringstream &oss) 264 | { 265 | std::uniform_int_distribution dis(0, 9); 266 | oss << delimiter; 267 | for (size_t i{0}; i < 3; i++) 268 | { 269 | oss << dis(m_rng); 270 | } 271 | } 272 | 273 | /** 274 | * @brief Generates a random date between the given start and end dates and appends it to the provided string stream. 275 | * 276 | * This function calculates a random date within the range specified by `start` and `end` 277 | * using a random number generator. The generated date is then appended to the given string 278 | * stream (`std::ostringstream`) with the specified delimiter. 279 | * 280 | * @param delimiter The character used to separate the date from other content in the stream. 281 | * @param start The starting date of the range. 282 | * @param end The ending date of the range. 283 | * @param oss The output string stream where the generated date will be appended. 284 | * 285 | * @see std::chrono::sys_days 286 | * @see std::uniform_int_distribution 287 | */ 288 | void Card::generate_date(const char delimiter, std::chrono::year_month_day start, std::chrono::year_month_day end, std::ostringstream &oss) 289 | { 290 | // Convert to sys_days (number of days since 1970-01-01) 291 | std::chrono::sys_days start_days{start}; 292 | std::chrono::sys_days end_days{end}; 293 | 294 | // Calculate range in days 295 | auto days_range = (end_days - start_days).count(); 296 | 297 | // Random number generator 298 | std::uniform_int_distribution dis(0, days_range); 299 | 300 | // Random offset from start 301 | std::chrono::sys_days random_day = start_days + std::chrono::days{dis(m_rng)}; 302 | std::chrono::year_month_day random_date{random_day}; 303 | 304 | oss << delimiter; 305 | oss << random_date; 306 | } -------------------------------------------------------------------------------- /src/API/DB_API.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "DB_API_.h" 5 | #include "DB_API.h" 6 | 7 | /** 8 | * @brief Checks if the provided SQLite database is valid and accessible. 9 | * 10 | * This function executes a simple query on the given SQLite database to check its validity. 11 | * If the database is valid and accessible, it returns true. If any error occurs during 12 | * the query execution or if the database is not valid, it returns false. 13 | * 14 | * @param db A reference to the SQLite database object to be checked for validity. 15 | * @return True if the database is valid and accessible; false otherwise. 16 | */ 17 | bool DB_API::is_sqlite_database(sqlite3 *&db) 18 | { 19 | // Execute a simple query to check if the database is valid 20 | const char *query{"SELECT name FROM sqlite_master WHERE type='table' LIMIT 1;"}; 21 | char *err_msg{nullptr}; 22 | int result = sqlite3_exec(db, query, nullptr, nullptr, &err_msg); 23 | 24 | if (result != SQLITE_OK) 25 | { 26 | // Print error message 27 | std::cerr << "Error executing query: " << err_msg << std::endl; 28 | sqlite3_free(err_msg); // Free the error message 29 | sqlite3_close(db); // Close the database immediately after error 30 | return false; 31 | } 32 | 33 | return true; 34 | } 35 | 36 | /** 37 | * @brief Reads an SQLite database from the specified path. 38 | * 39 | * This function attempts to open an SQLite database located at the given 40 | * file path. If the database opens successfully and is a valid SQLite database, 41 | * it returns a shared pointer to the opened database. If any error occurs during 42 | * the opening process, or if the file is not a valid SQLite database, it returns nullptr. 43 | * 44 | * @param db_path The path to the SQLite database file to be opened. 45 | * @return A shared pointer to the opened SQLite database if successful; nullptr otherwise. 46 | * 47 | * @see DB_API::is_sqlite_database(sqlite3* db) 48 | */ 49 | std::shared_ptr DB_API::read_db(const std::string &db_path) 50 | { 51 | sqlite3 *db; 52 | if (sqlite3_open(db_path.c_str(), &db) != SQLITE_OK) 53 | { 54 | return nullptr; 55 | } 56 | if (DB_API::is_sqlite_database(db) == false) 57 | { 58 | return nullptr; 59 | } 60 | return std::shared_ptr{db, [](sqlite3 *ptr) 61 | {if (ptr) { sqlite3_close(ptr); } }}; 62 | } 63 | 64 | /** 65 | * @brief Checks if a file exists in the file system. 66 | * 67 | * This function determines whether a file with the given filename exists 68 | * in the file system. It checks the existence of the file by using the stat 69 | * system call. The function returns true if the file exists and is accessible, 70 | * and false otherwise. 71 | * 72 | * @param filename The path to the file to be checked for existence. 73 | * @return True if the file exists and is accessible; false otherwise. 74 | */ 75 | bool DB_API::check_file_exists(const std::string &filename) 76 | { 77 | struct stat buffer; 78 | return ((filename.empty() == false) && 79 | (stat(filename.c_str(), &buffer) == 0)); 80 | } 81 | 82 | /** 83 | * @brief Reads credit card data from the database. 84 | * 85 | * This function retrieves credit card data from the database and populates 86 | * a vector with Card objects containing valid card information. 87 | * 88 | * @param db A shared pointer to the SQLite database. 89 | * @param data A vector to store Card objects with valid credit card information. 90 | * @param error_msg A string reference to store error messages, if any. 91 | * @return An SQLite error code. SQLITE_OK if successful, otherwise an error code. 92 | * 93 | */ 94 | int DB_API::read_cards(std::shared_ptr db, std::vector &data, std::string &error_msg) 95 | { 96 | const char *selectStatement = "SELECT Issuer, Length, Prefixes FROM cards_table;"; 97 | sqlite3_stmt *stmt = nullptr; 98 | data.clear(); // Ensure the output vector is empty on entry 99 | 100 | int rc = sqlite3_prepare_v2(db.get(), selectStatement, -1, &stmt, nullptr); 101 | if (rc != SQLITE_OK) 102 | { 103 | // Check if the table exists 104 | sqlite3_stmt *check_stmt = nullptr; 105 | const char *check_table = "SELECT name FROM sqlite_master WHERE type='table' AND name='cards_table';"; 106 | 107 | if (sqlite3_prepare_v2(db.get(), check_table, -1, &check_stmt, nullptr) == SQLITE_OK) 108 | { 109 | if (sqlite3_step(check_stmt) != SQLITE_ROW) 110 | { 111 | // Table does not exist — allow graceful fallback (e.g., empty DB) 112 | sqlite3_finalize(check_stmt); 113 | return SQLITE_OK; 114 | } 115 | sqlite3_finalize(check_stmt); 116 | } 117 | 118 | error_msg = "Prepare statement error: " + std::string(sqlite3_errmsg(db.get())); 119 | return rc; 120 | } 121 | 122 | // Table exists — proceed to fetch data 123 | while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) 124 | { 125 | const char *issuer_c = reinterpret_cast(sqlite3_column_text(stmt, 0)); 126 | int length = sqlite3_column_int(stmt, 1); 127 | const char *prefixes_c = reinterpret_cast(sqlite3_column_text(stmt, 2)); 128 | 129 | if (issuer_c && prefixes_c) 130 | { 131 | std::string issuer{issuer_c}; 132 | std::string prefixes{prefixes_c}; 133 | 134 | if (Card::validate_card(issuer, length, prefixes)) 135 | { 136 | data.emplace_back(issuer, length, prefixes); 137 | } 138 | } 139 | } 140 | 141 | if (rc != SQLITE_DONE) 142 | { 143 | error_msg = "Step statement error: " + std::string(sqlite3_errmsg(db.get())); 144 | sqlite3_finalize(stmt); 145 | return rc; 146 | } 147 | 148 | sqlite3_finalize(stmt); 149 | return SQLITE_OK; 150 | } 151 | 152 | /** 153 | * @brief Writes credit card data to the database, updating existing entries. 154 | * 155 | * This function creates a table for credit card data if it doesn't exist, 156 | * then updates existing entries and inserts new ones based on the provided data. 157 | * 158 | * @param db A shared pointer to the SQLite database. 159 | * @param data A vector of Card objects containing credit card information. 160 | * @param error_msg A string reference to store error messages, if any. 161 | * @return An SQLite error code. SQLITE_OK if successful, otherwise an error code. 162 | * 163 | * @note The function assumes that the Card class has methods such as `get_issuer()`, 164 | * `get_len()`, and `get_prefixes()` to retrieve the respective card details. 165 | */ 166 | int DB_API::write_cards(std::shared_ptr db, const std::vector &data, std::string &error_msg) 167 | { 168 | char *err = nullptr; 169 | int rc; 170 | 171 | // Step 1: Ensure main table exists 172 | rc = sqlite3_exec(db.get(), 173 | "CREATE TABLE IF NOT EXISTS cards_table (Issuer TEXT, Length INTEGER, Prefixes TEXT);", 174 | nullptr, nullptr, &err); 175 | if (rc != SQLITE_OK) 176 | { 177 | error_msg = "Failed to create cards_table: " + std::string(err); 178 | sqlite3_free(err); 179 | return rc; 180 | } 181 | 182 | // Step 2: Start transaction 183 | rc = sqlite3_exec(db.get(), "BEGIN TRANSACTION;", nullptr, nullptr, &err); 184 | if (rc != SQLITE_OK) 185 | { 186 | error_msg = "Failed to begin transaction: " + std::string(err); 187 | sqlite3_free(err); 188 | return rc; 189 | } 190 | 191 | // Step 3: Create temporary table 192 | rc = sqlite3_exec(db.get(), 193 | "DROP TABLE IF EXISTS temp_cards;" 194 | "CREATE TEMP TABLE temp_cards (Issuer TEXT, Length INTEGER, Prefixes TEXT);", 195 | nullptr, nullptr, &err); 196 | if (rc != SQLITE_OK) 197 | { 198 | error_msg = "Failed to create temp table: " + std::string(err); 199 | sqlite3_free(err); 200 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr); 201 | return rc; 202 | } 203 | 204 | // Step 4: Prepare insert into temp_cards 205 | sqlite3_stmt *insert_stmt = nullptr; 206 | rc = sqlite3_prepare_v2(db.get(), 207 | "INSERT INTO temp_cards (Issuer, Length, Prefixes) VALUES (?, ?, ?);", 208 | -1, &insert_stmt, nullptr); 209 | if (rc != SQLITE_OK) 210 | { 211 | error_msg = "Failed to prepare insert into temp_cards: " + std::string(sqlite3_errmsg(db.get())); 212 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr); 213 | return rc; 214 | } 215 | 216 | for (const auto &card : data) 217 | { 218 | std::string issuer = card.get_issuer(); 219 | std::string prefixes = card.get_prefixes(); 220 | int length = card.get_len(); 221 | 222 | sqlite3_bind_text(insert_stmt, 1, issuer.c_str(), -1, SQLITE_TRANSIENT); 223 | sqlite3_bind_int(insert_stmt, 2, length); 224 | sqlite3_bind_text(insert_stmt, 3, prefixes.c_str(), -1, SQLITE_TRANSIENT); 225 | 226 | rc = sqlite3_step(insert_stmt); 227 | if (rc != SQLITE_DONE) 228 | { 229 | error_msg = "Failed to insert into temp_cards: " + std::string(sqlite3_errmsg(db.get())); 230 | sqlite3_finalize(insert_stmt); 231 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr); 232 | return rc; 233 | } 234 | 235 | sqlite3_reset(insert_stmt); 236 | sqlite3_clear_bindings(insert_stmt); 237 | } 238 | sqlite3_finalize(insert_stmt); 239 | 240 | // Step 5: Delete cards not in the new input 241 | rc = sqlite3_exec(db.get(), 242 | "DELETE FROM cards_table " 243 | "WHERE NOT EXISTS (" 244 | " SELECT 1 FROM temp_cards " 245 | " WHERE temp_cards.Issuer = cards_table.Issuer " 246 | " AND temp_cards.Length = cards_table.Length " 247 | " AND temp_cards.Prefixes = cards_table.Prefixes" 248 | ");", 249 | nullptr, nullptr, &err); 250 | if (rc != SQLITE_OK) 251 | { 252 | error_msg = "Failed to delete outdated cards: " + std::string(err); 253 | sqlite3_free(err); 254 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr); 255 | return rc; 256 | } 257 | 258 | // Step 6: Insert new records that are not already in cards_table 259 | rc = sqlite3_exec(db.get(), 260 | "INSERT INTO cards_table (Issuer, Length, Prefixes) " 261 | "SELECT Issuer, Length, Prefixes FROM temp_cards " 262 | "WHERE NOT EXISTS (" 263 | " SELECT 1 FROM cards_table " 264 | " WHERE cards_table.Issuer = temp_cards.Issuer " 265 | " AND cards_table.Length = temp_cards.Length " 266 | " AND cards_table.Prefixes = temp_cards.Prefixes" 267 | ");", 268 | nullptr, nullptr, &err); 269 | if (rc != SQLITE_OK) 270 | { 271 | error_msg = "Failed to insert new cards: " + std::string(err); 272 | sqlite3_free(err); 273 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr); 274 | return rc; 275 | } 276 | 277 | // Step 7: Drop the temp table and commit 278 | sqlite3_exec(db.get(), "DROP TABLE IF EXISTS temp_cards;", nullptr, nullptr, nullptr); 279 | rc = sqlite3_exec(db.get(), "COMMIT;", nullptr, nullptr, &err); 280 | if (rc != SQLITE_OK) 281 | { 282 | error_msg = "Failed to commit transaction: " + std::string(err); 283 | sqlite3_free(err); 284 | return rc; 285 | } 286 | 287 | return SQLITE_OK; 288 | } 289 | 290 | /** 291 | * @brief Retrieves a random full name from the database. 292 | * 293 | * This function selects a random first name from the "Fnames" table and a random 294 | * last name from the "Lnames" table in the SQLite database, then concatenates 295 | * them into a full name. If either query fails or returns no result, an empty 296 | * string is returned. 297 | * 298 | * @param db A shared pointer to an open SQLite3 database connection. 299 | * The database must contain "Fnames" and "Lnames" tables, 300 | * each with a "name" column. 301 | * 302 | * @return A string containing the random full name (e.g., "John Doe"), 303 | * or an empty string if an error occurs or no name is found. 304 | */ 305 | std::string DB_API::get_random_name(std::shared_ptr db) 306 | { 307 | const char *f_name_statement = "SELECT name FROM Fnames ORDER BY RANDOM() LIMIT 1;"; 308 | const char *l_name_statement = "SELECT name FROM Lnames ORDER BY RANDOM() LIMIT 1;"; 309 | sqlite3_stmt *stmt = nullptr; 310 | 311 | // Helper lambda to get a name 312 | auto get_name = [&](const char *sql_query) -> std::string 313 | { 314 | sqlite3_stmt *local_stmt = nullptr; 315 | if (sqlite3_prepare_v2(db.get(), sql_query, -1, &local_stmt, nullptr) != SQLITE_OK) 316 | { 317 | sqlite3_finalize(local_stmt); 318 | return ""; 319 | } 320 | 321 | std::string result; 322 | if (sqlite3_step(local_stmt) == SQLITE_ROW) 323 | { 324 | const unsigned char *text = sqlite3_column_text(local_stmt, 0); 325 | if (text) 326 | { 327 | result = reinterpret_cast(text); 328 | } 329 | } 330 | 331 | sqlite3_finalize(local_stmt); 332 | return result; 333 | }; 334 | 335 | std::string first_name{get_name(f_name_statement)}; 336 | std::string last_name{get_name(l_name_statement)}; 337 | 338 | if (first_name.empty() || last_name.empty()) 339 | { 340 | return ""; 341 | } 342 | 343 | return first_name + " " + last_name; 344 | } -------------------------------------------------------------------------------- /src/API/DB_API_.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "sqlite3.h" 3 | 4 | /** 5 | * @namespace DB_API 6 | * @brief Provides functions for interacting with an SQLite database and managing credit card data. 7 | * 8 | * The DB_API namespace contains functions for various database-related operations 9 | * such as checking file existence, reading an SQLite database, and writing/reading 10 | * credit card data. It encapsulates all related database utilities in a single, logical scope. 11 | */ 12 | namespace DB_API 13 | { 14 | // Checks if the provided object is an SQLite database. 15 | bool is_sqlite_database(sqlite3 *&db); 16 | }; -------------------------------------------------------------------------------- /src/API/Date.cpp: -------------------------------------------------------------------------------- 1 | #include "Date.h" 2 | 3 | /** 4 | * @brief Returns the number of days in a given month and year. 5 | * 6 | * This function accounts for leap years when determining the number of days 7 | * in February. For all other months, it returns the standard number of days. 8 | * 9 | * @param year The year used to determine if February has 28 or 29 days. 10 | * @param month The month (1–12) for which to retrieve the number of days. 11 | * @return The number of days in the specified month. 12 | */ 13 | int Date::days_in_month(int year, int month) 14 | { 15 | // Array of days for each month (February will be adjusted for leap year) 16 | static const int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 17 | 18 | // Adjust February for leap year 19 | if (month == 2) 20 | { 21 | if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) 22 | { 23 | return 29; // Leap year 24 | } 25 | } 26 | 27 | return days_in_month[month - 1]; 28 | } 29 | 30 | /** 31 | * @brief Constructs a std::chrono::year_month_day object from day, month, and year values. 32 | * 33 | * This function creates a date representation using the C++20 library types. 34 | * It does not perform validation on the input values. 35 | * 36 | * @param d The day of the month (1–31, depending on the month). 37 | * @param m The month of the year (1–12). 38 | * @param y The year. 39 | * @return A std::chrono::year_month_day object representing the given date. 40 | * 41 | * @see std::chrono::year_month_day 42 | */ 43 | std::chrono::year_month_day Date::get_date_from_ymd(unsigned int d, unsigned int m, int y) 44 | { 45 | return std::chrono::year_month_day{std::chrono::year{y}, std::chrono::month{m}, std::chrono::day{d}}; 46 | } 47 | 48 | /** 49 | * @brief Validates that a second date is not earlier than the first date. 50 | * 51 | * This function checks whether the second date (d2, m2, y2) is greater than 52 | * or equal to the first date (d1, m1, y1). It uses std::chrono::year_month_day 53 | * for comparison and assumes all date components are valid. 54 | * 55 | * @param d1 Day of the first date. 56 | * @param m1 Month of the first date. 57 | * @param y1 Year of the first date. 58 | * @param d2 Day of the second date. 59 | * @param m2 Month of the second date. 60 | * @param y2 Year of the second date. 61 | * @return true if the second date is the same or later than the first date, false otherwise. 62 | * 63 | * @see Date::get_date_from_ymd 64 | * @see std::chrono::year_month_day 65 | */ 66 | bool Date::vali_date(int d1, int m1, int y1, int d2, int m2, int y2) // pun 67 | { 68 | std::chrono::year_month_day date1{get_date_from_ymd(d1, m1, y1)}; 69 | std::chrono::year_month_day date2{get_date_from_ymd(d2, m2, y2)}; 70 | 71 | return date2 >= date1; 72 | } 73 | 74 | /** 75 | * @brief Converts a std::chrono::year_month_day object to a string. 76 | * 77 | * This function formats a given date into a string using the default 78 | * output format of std::ostringstream for std::chrono::year_month_day. 79 | * 80 | * @param date The date to convert. 81 | * @return A string representation of the date. 82 | * 83 | * @see std::chrono::year_month_day 84 | */ 85 | std::string Date::string_from_date(std::chrono::year_month_day date) 86 | { 87 | std::ostringstream oss; 88 | oss << date; 89 | return oss.str(); 90 | } -------------------------------------------------------------------------------- /src/CC_Generator/ProjectInfo_.h: -------------------------------------------------------------------------------- 1 | namespace ProjectInfo { 2 | const char* version = "2.0.2"; 3 | const char* project_url = "https://github.com/ItaiShek/CC_Generator"; 4 | const char* license = "AGPL V3"; 5 | } -------------------------------------------------------------------------------- /src/CC_Generator/console_main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.cpp 3 | * @brief Entry point for the console application. 4 | * 5 | * This file contains the main function which initializes the console application. 6 | * It calls the `console::run` function to start the application with version, URL, and license information. 7 | * 8 | * @see Console.h for the declaration of the console::run function. 9 | * @see ProjectInfo_ for version, project URL, and license details. 10 | */ 11 | 12 | #include "Console.h" 13 | #include "ProjectInfo_.h" 14 | 15 | /** 16 | * @brief Main function to run the console version of the application. 17 | * 18 | * The main function retrieves version, project URL, and license information from 19 | * the `ProjectInfo` class and then calls the `console::run` function to start 20 | * the console application. 21 | * 22 | * @param argc The number of command-line arguments. 23 | * @param argv The array of command-line argument strings. 24 | * 25 | * @return Returns 0 if the application runs successfully. 26 | */ 27 | int main(int argc, char* argv[]) 28 | { 29 | // Run the console application with the specified project details 30 | console::run(ProjectInfo::version, ProjectInfo::project_url, ProjectInfo::license); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /src/CC_Generator/gui_main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.cpp 3 | * @brief Entry point for the GUI application. 4 | * 5 | * This file contains the main function for running the GUI version of the application. 6 | * It handles platform-specific entry points for both Windows and Linux. 7 | * 8 | * On Windows, the `WinMain` function is used as the entry point, while on Linux, 9 | * the regular `main` function is used. 10 | * 11 | * @see GUI.h for the declaration of the gui::run function. 12 | * @see ProjectInfo_ for version, project URL, and license details. 13 | */ 14 | 15 | #if defined(_WIN64) || defined(_WIN32) 16 | #include 17 | #undef MOUSE_MOVED 18 | #endif 19 | 20 | #include "GUI.h" 21 | #include "ProjectInfo_.h" 22 | 23 | /** 24 | * @brief Main function to run the GUI version of the application. 25 | * 26 | * On Windows, this function uses the `WinMain` entry point, while on Linux it uses the regular `main`. 27 | * It initializes the GUI application by calling the `gui::run` function with version, project URL, and license 28 | * information retrieved from the `ProjectInfo` class. 29 | * 30 | * @param hInstance The handle to the application instance (Windows only). 31 | * @param hPrevInstance The handle to the previous instance (Windows only). 32 | * @param lpCmdLine Command line arguments (Windows only). 33 | * @param nCmdShow Controls how the window is shown (Windows only). 34 | * @param argc The number of command-line arguments (Linux only). 35 | * @param argv The array of command-line argument strings (Linux only). 36 | * 37 | * @return Returns 0 if the application runs successfully. 38 | */ 39 | #if defined(_WIN64) || defined(_WIN32) 40 | int WINAPI WinMain( 41 | HINSTANCE hInstance, 42 | HINSTANCE hPrevInstance, 43 | LPSTR lpCmdLine, 44 | int nCmdShow) 45 | #else 46 | int main(int argc, char *argv[]) 47 | #endif 48 | { 49 | // Run the GUI application with the specified project details 50 | gui::run(ProjectInfo::version, ProjectInfo::project_url, ProjectInfo::license); 51 | return 0; 52 | } -------------------------------------------------------------------------------- /src/Console/Console_.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #if defined(_WIN64) || defined(_WIN32) 9 | #define NOMINMAX 10 | #include 11 | #undef MOUSE_MOVED 12 | #include "curses.h" 13 | #else 14 | #include 15 | #include 16 | #define MAX_PATH PATH_MAX 17 | #endif 18 | 19 | #include "sqlite3.h" 20 | #include "Card.h" 21 | // #include "DB_API.h" 22 | 23 | #if defined(__x86_64) || defined(_M_X64) 24 | #define DATATYPE unsigned long long 25 | #elif defined(__i386) || defined(_M_IX86) 26 | #define DATATYPE unsigned int 27 | #endif 28 | 29 | // global variables 30 | extern std::atomic g_paused; 31 | extern std::atomic g_started; 32 | extern std::atomic g_progress; 33 | 34 | namespace console 35 | { 36 | // Represents a button with a label and associated action. 37 | class Button 38 | { 39 | public: 40 | Button(std::string label, int action) : m_label(label), m_action(action) {} 41 | std::string m_label; 42 | int m_action; 43 | }; 44 | 45 | // Internal utility functions for the console application. 46 | 47 | // Prints a banner with version and URL information. 48 | void print_banner(const std::string &version, const std::string &url); 49 | 50 | // Checks if two strings are equal in a case-insensitive manner. 51 | inline bool case_insensitive_equals(const std::string &input, const std::string &comp); 52 | 53 | // Checks if the input string indicates a quit command. 54 | bool check_quit(const std::string &input); 55 | 56 | // Gets a SQLite database and returns it along with potential error messages. 57 | std::shared_ptr get_db(std::string &db_path, std::string &err_msg); 58 | 59 | // Draws buttons on the console. 60 | void draw_buttons(const std::vector &buttons, size_t curr_btn_idx); 61 | 62 | // Displays a yes/no prompt on the console and returns the user's choice. 63 | int yes_no(const std::string &str); 64 | 65 | // Adds a card with user-inputted details. 66 | Card add_card(); 67 | 68 | // Gets a formatted string representation of a card. 69 | inline std::string get_card_string(int max_length, const Card &card); 70 | 71 | // Draws a list of cards on the console. 72 | void draw_cards(const std::vector &cards_vec, int start_row, int visible_rows, int max_offset, int curr_row_idx, const std::vector &selected_rows); 73 | 74 | // Guides the user in choosing cards and returns the user's action. 75 | int choose_cards(std::shared_ptr db, const std::string &db_path, std::vector &cards_vec, std::vector &cards_selection); 76 | 77 | // Guides the user in choosing the amount of data to generate and returns the user's action. 78 | int choose_amount(DATATYPE &amount, const std::string &db_path); 79 | 80 | // Gets a valid file path from the user. 81 | void get_path(std::string &path); 82 | 83 | // Guides the user in choosing a file and returns the user's action. 84 | int choose_file(std::string &exp_path); 85 | 86 | // Guides the user in generating data and returns the user's action. 87 | int generate(const std::string &exp_path, const std::vector &cards_vec, const std::vector &cards_selection, DATATYPE amount, std::shared_ptr db); 88 | 89 | // Let the user to enable/disable CVV, name, and date. 90 | int choose_options(); 91 | 92 | // Let the user to choose expiration date range 93 | int choose_date(); 94 | } -------------------------------------------------------------------------------- /src/GUI/GUI.cpp: -------------------------------------------------------------------------------- 1 | #ifdef __EMSCRIPTEN__ 2 | #include "emscripten_funcs.h" 3 | #endif 4 | 5 | #include "GUI.h" 6 | #include "GUI_.h" 7 | #include "Date.h" 8 | 9 | std::mt19937 File::m_gen(std::random_device{}()); 10 | std::atomic g_paused{false}; 11 | std::atomic g_started{false}; 12 | std::atomic g_progress{0.0f}; 13 | std::string g_current_db_path = "Cards.db"; 14 | 15 | // emscripten flags 16 | bool g_emscripten_open_flag = false; 17 | bool g_emscripten_save_db_flag = false; 18 | bool g_emscripten_generate_flag = false; 19 | extern std::atomic export_finished; 20 | 21 | /** 22 | * @brief Initializes a vector of Card objects from a database. 23 | * 24 | * This function initializes a vector of Card objects by reading data from a database file. 25 | * If the database file does not exist or there is an issue reading the database, an empty 26 | * vector is returned. 27 | * 28 | * @return A vector of Card objects initialized from the database. 29 | */ 30 | std::vector initialize_cards_vec() 31 | { 32 | std::vector temp_vec{}; 33 | 34 | if (DB_API::check_file_exists(g_current_db_path) == false) 35 | { 36 | return temp_vec; 37 | } 38 | 39 | std::shared_ptr db{DB_API::read_db(g_current_db_path)}; 40 | 41 | if (db == nullptr) 42 | { 43 | return temp_vec; 44 | } 45 | 46 | std::string err_msg{}; 47 | DB_API::read_cards(db, temp_vec, err_msg); 48 | 49 | return temp_vec; 50 | } 51 | 52 | class App : public gui::GuiApp 53 | { 54 | public: 55 | App(const std::string &title, const std::string &url, const std::string &license, const int window_w, const int window_h) : GuiApp{title, url, window_w, window_h}, m_title{title}, m_url{url}, m_license{license} {}; 56 | ~App() = default; 57 | 58 | void set_duration() 59 | { 60 | File::m_cvv_flag = false; 61 | File::m_name_flag = false; 62 | File::m_date_flag = false; 63 | m_duration = File::estimate_time(); 64 | m_cvv_duration = File::estimate_cvv_time(); 65 | m_date_duration = File::estimate_date_time(); 66 | m_name_duration = File::estimate_name_time(g_current_db_path); 67 | 68 | m_disable_name_option = m_name_duration == std::chrono::duration_cast(std::chrono::nanoseconds{0}); 69 | } 70 | 71 | void startup() 72 | { 73 | m_window_flags |= ImGuiWindowFlags_NoDecoration; 74 | m_window_flags |= ImGuiWindowFlags_NoMove; 75 | m_window_flags |= ImGuiWindowFlags_NoCollapse; 76 | m_window_flags |= ImGuiWindowFlags_NoTitleBar; 77 | set_duration(); 78 | glfwSwapInterval(1); // idling 79 | } 80 | 81 | void update() 82 | { 83 | const ImGuiViewport *viewport = ImGui::GetMainViewport(); 84 | ImGui::SetNextWindowPos(viewport->WorkPos); 85 | ImGui::SetNextWindowSize(viewport->WorkSize); 86 | 87 | static bool disable_start_btn; 88 | 89 | // ImGui content 90 | ImGui::Begin("MainWindow", NULL, m_window_flags); 91 | 92 | ImVec2 main_window_size{ImGui::GetWindowSize()}; 93 | ImVec2 popup_min_window_size{ImVec2(main_window_size.x * 0.5f, main_window_size.y * 0.5f)}; 94 | 95 | static std::vector cards_vec{initialize_cards_vec()}; 96 | static std::vector cards_selection(cards_vec.size(), false); 97 | static int current_card{-1}; 98 | 99 | ImGui::BeginDisabled(g_started); 100 | // Child 1 - Database 101 | { 102 | static ImGuiTextFilter db_filter{}; 103 | ImVec2 child_window_size{ImGui::GetContentRegionAvail()}; 104 | ImGui::BeginChild("Child_L", ImVec2(child_window_size.x * 0.5f, child_window_size.y), false, ImGuiWindowFlags_NoDecoration); 105 | // Child 1.1 - Database list 106 | { 107 | ImGui::BeginChild("Child_L_1", ImVec2(0, ImGui::GetContentRegionAvail().y - ImGui::GetFrameHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); 108 | 109 | if (ImGui::BeginTable("cards_columns", 4, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) 110 | { 111 | static std::array table_header{"", "Issuer", "Length", "Prefixes"}; 112 | for (const auto &header_col : table_header) 113 | { 114 | ImGui::TableNextColumn(); 115 | ImGui::TextColored(ImVec4(255, 0, 0, 1), "%s", header_col); 116 | } 117 | 118 | bool sel{}; 119 | disable_start_btn = false; 120 | for (size_t i{}; i < cards_vec.size(); i++) 121 | { 122 | std::string issuer_str{cards_vec[i].get_issuer()}; 123 | std::string length_str{std::to_string(cards_vec[i].get_len())}; 124 | std::string prefixes_str{cards_vec[i].get_prefixes()}; 125 | 126 | const char *issuer{issuer_str.c_str()}; 127 | const char *length{length_str.c_str()}; 128 | const char *prefixes{prefixes_str.c_str()}; 129 | if (db_filter.PassFilter(issuer) || db_filter.PassFilter(length) || db_filter.PassFilter(prefixes)) 130 | { 131 | ImGui::TableNextRow(); 132 | ImGui::TableNextColumn(); 133 | // if you have a better and more efficient solution then please suggest it =) 134 | sel = cards_selection[i]; 135 | ImGui::Checkbox(("##checkbox_" + std::to_string(i)).c_str(), &sel); 136 | cards_selection[i] = sel; 137 | disable_start_btn |= sel; 138 | 139 | ImGui::TableNextColumn(); 140 | if (ImGui::Selectable(issuer, current_card == i, ImGuiSelectableFlags_SpanAllColumns)) 141 | { 142 | if (current_card == i) 143 | { 144 | current_card = -1; // deselect 145 | } 146 | else 147 | { 148 | current_card = static_cast(i); // select 149 | } 150 | } 151 | 152 | ImGui::TableNextColumn(); 153 | ImGui::Text("%s", length); 154 | ImGui::TableNextColumn(); 155 | ImGui::Text("%s", prefixes); 156 | } 157 | } 158 | disable_start_btn = !disable_start_btn; 159 | ImGui::EndTable(); 160 | } 161 | ImGui::EndChild(); 162 | } 163 | ImGui::Separator(); 164 | // Child 1.2 - Filter 165 | { 166 | ImGui::BeginChild("Child_L_2", ImVec2(0, 0), false, ImGuiWindowFlags_NoDecoration); 167 | ImGui::Text("Filter:"); 168 | ImGui::SameLine(); 169 | db_filter.Draw("##db_filter"); 170 | ImGui::EndChild(); 171 | } 172 | ImGui::EndChild(); 173 | } 174 | ImGui::EndDisabled(); 175 | 176 | ImGui::SameLine(); 177 | 178 | // Child 2 - Actions 179 | { 180 | ImGui::BeginChild("Child_R", ImVec2(0, ImGui::GetContentRegionAvail().y), false, ImGuiWindowFlags_HorizontalScrollbar); 181 | ImGui::SeparatorText("Database Actions"); 182 | // Child 2.1 - Database actions 183 | { 184 | ImGui::BeginChild("Child_R1", ImVec2(0, ImGui::GetContentRegionAvail().y * 0.3f), false, ImGuiWindowFlags_HorizontalScrollbar); 185 | static const std::array db_actions{ 186 | "Clear", 187 | "Open", 188 | "Save", 189 | "Add", 190 | "Edit", 191 | "Remove", 192 | "Check all", 193 | "Uncheck all", 194 | }; 195 | static std::string err_msg{}; 196 | static size_t action; 197 | action = db_actions.size(); 198 | static constexpr const char *filters{"Sqlite database files (*.db){.db},All files (*.*){.*}"}; 199 | 200 | ImVec2 window_size{ImGui::GetContentRegionAvail()}; 201 | ImVec2 button_size{-FLT_MIN, window_size.y * 0.175f}; 202 | if (ImGui::BeginTable("Database_actions", 3, ImGuiTableFlags_SizingStretchSame)) 203 | { 204 | for (size_t i{}; i < db_actions.size(); i++) 205 | { 206 | ImGui::TableNextColumn(); 207 | ImGui::BeginDisabled(g_started); 208 | if (ImGui::Button(db_actions[i], button_size)) 209 | { 210 | action = i; 211 | } 212 | ImGui::EndDisabled(); 213 | } 214 | ImGui::EndTable(); 215 | } 216 | 217 | // Handle db actions 218 | switch (action) 219 | { 220 | case 0: // clear cards 221 | if (cards_vec.empty() == false) 222 | { 223 | ImGui::OpenPopup("Clear"); 224 | } 225 | break; 226 | case 1: // open database 227 | { 228 | #ifdef __EMSCRIPTEN__ 229 | open_file_dialog("'.db'"); 230 | #else 231 | IGFD::FileDialogConfig config; 232 | config.path = "."; 233 | config.fileName = ""; 234 | config.countSelectionMax = 1; 235 | config.flags = ImGuiFileDialogFlags_Modal; 236 | ImGuiFileDialog::Instance()->OpenDialog( 237 | "OpenDlg", // vKey 238 | "Open Database", // vTitle 239 | filters, // vFilters 240 | config); 241 | #endif 242 | } 243 | break; 244 | case 2: // save database 245 | { 246 | #ifdef __EMSCRIPTEN__ 247 | g_emscripten_save_db_flag = true; 248 | #else 249 | IGFD::FileDialogConfig config; 250 | config.path = "."; 251 | config.fileName = ""; 252 | config.countSelectionMax = 1; 253 | config.flags = ImGuiFileDialogFlags_Modal | ImGuiFileDialogFlags_ConfirmOverwrite; 254 | ImGuiFileDialog::Instance()->OpenDialog( 255 | "SaveDlg", // vKey 256 | "Save Database", // vTitle 257 | filters, // vFilters 258 | config); 259 | #endif 260 | } 261 | break; 262 | case 3: // add new card 263 | ImGui::OpenPopup("Add"); 264 | break; 265 | case 4: // edit card 266 | if (current_card < cards_vec.size()) 267 | { 268 | ImGui::OpenPopup("Edit"); 269 | } 270 | break; 271 | case 5: // remove card 272 | if (current_card < cards_vec.size()) 273 | { 274 | cards_vec.erase(std::next(cards_vec.begin(), current_card), std::next(cards_vec.begin(), current_card + 1)); 275 | cards_selection.erase(std::next(cards_selection.begin(), current_card), std::next(cards_selection.begin(), current_card + 1)); 276 | } 277 | break; 278 | case 6: // select all 279 | std::fill(cards_selection.begin(), cards_selection.end(), true); 280 | break; 281 | case 7: 282 | std::fill(cards_selection.begin(), cards_selection.end(), false); 283 | break; 284 | default: 285 | break; 286 | } 287 | 288 | // clear 289 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX)); 290 | if (ImGui::BeginPopupModal("Clear")) 291 | { 292 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 293 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)}; 294 | ImGui::TextWrapped("Do you want to clear the current database?"); 295 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2)); 296 | 297 | if (ImGui::Button("Yes", button_size)) 298 | { 299 | cards_vec.clear(); 300 | cards_selection.clear(); 301 | ImGui::CloseCurrentPopup(); 302 | } 303 | ImGui::SameLine(); 304 | if (ImGui::Button("No", button_size)) 305 | { 306 | ImGui::CloseCurrentPopup(); 307 | } 308 | ImGui::EndPopup(); 309 | } 310 | 311 | // open database 312 | if (ImGuiFileDialog::Instance()->Display("OpenDlg", ImGuiWindowFlags_NoCollapse, popup_min_window_size) || g_emscripten_open_flag) 313 | { 314 | 315 | // action if OK 316 | if (ImGuiFileDialog::Instance()->IsOk() || g_emscripten_open_flag) 317 | { 318 | #ifdef __EMSCRIPTEN__ 319 | std::string db_path = get_selected_file_path_from_js("selectedFilePath"); 320 | g_emscripten_open_flag = false; 321 | #else 322 | std::string db_path = ImGuiFileDialog::Instance()->GetFilePathName(); 323 | #endif 324 | 325 | if (DB_API::check_file_exists(db_path) == false) 326 | { 327 | ImGui::OpenPopup("DB Error"); 328 | err_msg = "File not found."; 329 | } 330 | else 331 | { 332 | std::shared_ptr db{DB_API::read_db(db_path)}; 333 | 334 | if (db == nullptr) 335 | { 336 | ImGui::OpenPopup("DB Error"); 337 | err_msg = "Failed to open the database."; 338 | } 339 | else 340 | { 341 | if (DB_API::read_cards(db, cards_vec, err_msg) == 0) 342 | { 343 | cards_selection = std::vector(cards_vec.size(), false); 344 | g_current_db_path = db_path; 345 | set_duration(); 346 | } 347 | else 348 | { 349 | ImGui::OpenPopup("DB Error"); 350 | } 351 | } 352 | } 353 | } 354 | ImGuiFileDialog::Instance()->Close(); 355 | 356 | action = db_actions.size(); 357 | } 358 | 359 | // save database 360 | if (ImGuiFileDialog::Instance()->Display("SaveDlg", ImGuiWindowFlags_NoCollapse, popup_min_window_size) || g_emscripten_save_db_flag) 361 | { 362 | if (ImGuiFileDialog::Instance()->IsOk() || g_emscripten_save_db_flag) 363 | { 364 | std::string db_path = ImGuiFileDialog::Instance()->GetFilePathName(); 365 | 366 | std::shared_ptr db{DB_API::read_db(db_path)}; 367 | 368 | if (db == nullptr) 369 | { 370 | ImGui::OpenPopup("DB Error"); 371 | err_msg = "Failed to open the database."; 372 | } 373 | else 374 | { 375 | if (DB_API::write_cards(db, cards_vec, err_msg) != 0) 376 | { 377 | ImGui::OpenPopup("DB Error"); 378 | } 379 | else 380 | { 381 | #ifdef __EMSCRIPTEN__ 382 | download_file(g_current_db_path, "Cards.db", g_emscripten_save_db_flag); 383 | #endif 384 | } 385 | } 386 | } 387 | ImGuiFileDialog::Instance()->Close(); 388 | action = db_actions.size(); 389 | } 390 | 391 | // add new card 392 | static bool first_time{true}; 393 | static std::string issuer_add{}; 394 | static int length_add{}; 395 | static std::string prefixes_add{}; 396 | 397 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX)); 398 | if (ImGui::BeginPopupModal("Add")) 399 | { 400 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 401 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)}; 402 | 403 | if (first_time) 404 | { 405 | issuer_add = ""; 406 | length_add = 16; 407 | prefixes_add = ""; 408 | first_time = false; 409 | } 410 | 411 | ImGui::Text("Issuer: "); 412 | ImGui::SameLine(); 413 | ImGui::InputText("##issuer_input", &issuer_add); 414 | 415 | ImGui::Text("Length: "); 416 | ImGui::SameLine(); 417 | ImGui::DragInt("##length_input", &length_add, 1.0f, 2, 32, "%d", ImGuiSliderFlags_AlwaysClamp); 418 | 419 | ImGui::Text("Prefixes:"); 420 | ImGui::SameLine(); 421 | ImGui::InputText("##prefixes_input", &prefixes_add); 422 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) 423 | { 424 | ImGui::SetTooltip("Comma delimited, either digits and/or ascending ranges larger then the length.\ne.g.: 1,2,4-5,7,89-1000"); 425 | } 426 | 427 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2)); 428 | ImGui::BeginDisabled(Card::validate_card(issuer_add, length_add, prefixes_add) == false); 429 | if (ImGui::Button("Add", button_size)) 430 | { 431 | Card new_card{std::string(issuer_add), length_add, std::string(prefixes_add)}; 432 | auto it = std::find(cards_vec.begin(), cards_vec.end(), new_card); 433 | if (it == cards_vec.end()) 434 | { 435 | cards_vec.push_back(new_card); 436 | cards_selection.push_back(false); 437 | } 438 | first_time = true; 439 | ImGui::CloseCurrentPopup(); 440 | action = db_actions.size(); 441 | } 442 | ImGui::EndDisabled(); 443 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) 444 | { 445 | ImGui::SetTooltip("Duplicates will be ignored"); 446 | } 447 | ImGui::SameLine(); 448 | if (ImGui::Button("Cancel", button_size)) 449 | { 450 | ImGui::CloseCurrentPopup(); 451 | action = db_actions.size(); 452 | first_time = true; 453 | } 454 | ImGui::EndPopup(); 455 | } 456 | 457 | // edit card 458 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX)); 459 | if (ImGui::BeginPopupModal("Edit")) 460 | { 461 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 462 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)}; 463 | 464 | if (first_time) 465 | { 466 | issuer_add = cards_vec[current_card].get_issuer(); 467 | length_add = cards_vec[current_card].get_len(); 468 | prefixes_add = cards_vec[current_card].get_prefixes(); 469 | first_time = false; 470 | } 471 | 472 | ImGui::Text("Issuer: "); 473 | ImGui::SameLine(); 474 | ImGui::InputText("##issuer_input", &issuer_add); 475 | 476 | ImGui::Text("Length: "); 477 | ImGui::SameLine(); 478 | ImGui::DragInt("##length_input", &length_add, 1.0f, 2, 32, "%d", ImGuiSliderFlags_AlwaysClamp); 479 | 480 | ImGui::Text("Prefixes:"); 481 | ImGui::SameLine(); 482 | ImGui::InputText("##prefixes_input", &prefixes_add); 483 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) 484 | { 485 | ImGui::SetTooltip("Comma delimited, either digits and/or ascending ranges larger then the length.\ne.g.: 1,2,4-5,7,89-1000"); 486 | } 487 | 488 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2)); 489 | ImGui::BeginDisabled(Card::validate_card(issuer_add, length_add, prefixes_add) == false); 490 | if (ImGui::Button("Save", button_size)) 491 | { 492 | bool found = std::any_of(cards_vec.begin(), cards_vec.end(), [](const Card &item) -> bool 493 | { return (item.get_issuer() == issuer_add) && (item.get_len() == length_add) && (item.get_prefixes() == prefixes_add); }); 494 | 495 | if (found == false) 496 | { 497 | cards_vec[current_card].set_issuer(issuer_add); 498 | cards_vec[current_card].set_len(length_add); 499 | cards_vec[current_card].set_prefixes(prefixes_add); 500 | } 501 | ImGui::CloseCurrentPopup(); 502 | action = db_actions.size(); 503 | first_time = true; 504 | } 505 | ImGui::EndDisabled(); 506 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) 507 | { 508 | ImGui::SetTooltip("Duplicates will be ignored"); 509 | } 510 | ImGui::SameLine(); 511 | if (ImGui::Button("Cancel", button_size)) 512 | { 513 | ImGui::CloseCurrentPopup(); 514 | action = db_actions.size(); 515 | first_time = true; 516 | } 517 | ImGui::EndPopup(); 518 | } 519 | 520 | // error message box 521 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX)); 522 | if (ImGui::BeginPopupModal("DB Error")) 523 | { 524 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 525 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)}; 526 | ImGui::TextWrapped("%s", err_msg.c_str()); 527 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x / 2, popup_window_size.y - button_size.y * 2)); 528 | 529 | if (ImGui::Button("OK", button_size)) 530 | { 531 | ImGui::CloseCurrentPopup(); 532 | } 533 | ImGui::EndPopup(); 534 | } 535 | 536 | ImGui::EndChild(); 537 | } 538 | 539 | static constexpr DATATYPE min_amount{1}; 540 | static constexpr DATATYPE max_amount{std::numeric_limits::max() / 2}; 541 | static DATATYPE amount{min_amount}; 542 | 543 | // Child 2.2 - Database input 544 | ImGui::Separator(); 545 | ImGui::BeginDisabled(g_started); 546 | { 547 | 548 | ImGui::BeginChild("Child_R2", ImVec2(0, ImGui::GetContentRegionAvail().y * 0.5f), false, ImGuiWindowFlags_HorizontalScrollbar); 549 | { 550 | static bool options_changed{false}; 551 | 552 | ImGui::Text("Amount:"); 553 | ImGui::SameLine(); 554 | static std::string f_time{File::format_time(std::chrono::duration_cast(m_duration * amount))}; 555 | ImGui::DragScalar("##amount_slider", imgui_data_type, &amount, 1.0f, &min_amount, &max_amount, 0, ImGuiSliderFlags_AlwaysClamp); 556 | static std::string size_str{File::estimate_size(amount)}; 557 | 558 | // Calculate the total size of the file including newline characters 559 | if (ImGui::IsItemEdited() || options_changed) 560 | { 561 | options_changed = false; 562 | size_str = File::estimate_size(amount); 563 | f_time = File::format_time(std::chrono::duration_cast(m_duration * amount)); 564 | } 565 | 566 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) 567 | { 568 | ImGui::SetTooltip("Hold and drag, or double click to enter a value."); 569 | } 570 | 571 | // print estimated file size 572 | ImGui::Text("Approximate size:"); 573 | ImGui::SameLine(); 574 | ImGui::TextColored(ImVec4(255, 0, 0, 1), "%s", size_str.c_str()); 575 | 576 | // print estimated time 577 | ImGui::Text("ETA:"); 578 | ImGui::SameLine(); 579 | ImGui::TextColored(ImVec4(255, 0, 0, 1), "%s", f_time.c_str()); 580 | 581 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) 582 | { 583 | ImGui::SetTooltip("HH:mm:ss:ms"); 584 | } 585 | 586 | ImGui::SetNextItemWidth(20.0f); 587 | static char inputBuffer[2] = {File::m_delimiter, '\0'}; 588 | if (ImGui::InputText("Delimiter", inputBuffer, sizeof(inputBuffer))) 589 | { 590 | // If the user entered something, store the first character 591 | if (inputBuffer[0] != '\0') 592 | { 593 | File::m_delimiter = inputBuffer[0]; 594 | } 595 | } 596 | 597 | if (ImGui::Checkbox("Include CVV", &File::m_cvv_flag)) 598 | { 599 | m_duration += File::m_cvv_flag ? m_cvv_duration : -m_cvv_duration; 600 | options_changed = true; 601 | } 602 | 603 | ImGui::BeginDisabled(m_disable_name_option); 604 | if (ImGui::Checkbox("Include name", &File::m_name_flag)) 605 | { 606 | m_duration += File::m_name_flag ? m_name_duration : -m_name_duration; 607 | options_changed = true; 608 | } 609 | ImGui::EndDisabled(); 610 | if (ImGui::Checkbox("Include expiration date", &File::m_date_flag)) 611 | { 612 | m_duration += File::m_date_flag ? m_date_duration : -m_date_duration; 613 | options_changed = true; 614 | } 615 | 616 | static int start_day = static_cast(File::m_date.start.day()), start_month = static_cast(File::m_date.start.month()), start_year = static_cast(File::m_date.start.year()); 617 | static int end_day = static_cast(File::m_date.end.day()), end_month = static_cast(File::m_date.end.month()), end_year = static_cast(File::m_date.end.year()); 618 | 619 | if (ImGui::Button("Set Date Range")) 620 | { 621 | ImGui::OpenPopup("Date Range Picker"); 622 | } 623 | 624 | if (ImGui::BeginPopupModal("Date Range Picker", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) 625 | { 626 | ImGui::Text("Start Date:"); 627 | ImGui::InputInt("Day##Start", &start_day); 628 | ImGui::InputInt("Month##Start", &start_month); 629 | start_month = std::clamp(start_month, 1, 12); 630 | ImGui::InputInt("Year##Start", &start_year); 631 | start_year = std::clamp(start_year, 0, std::numeric_limits::max()); 632 | start_day = std::clamp(start_day, 1, Date::days_in_month(start_year, start_month)); 633 | 634 | ImGui::Separator(); 635 | 636 | ImGui::Text("End Date:"); 637 | ImGui::InputInt("Day##End", &end_day); 638 | ImGui::InputInt("Month##End", &end_month); 639 | end_month = std::clamp(end_month, 1, 12); 640 | ImGui::InputInt("Year##End", &end_year); 641 | end_year = std::clamp(end_year, start_year, std::numeric_limits::max()); 642 | end_day = std::clamp(end_day, 1, Date::days_in_month(end_year, end_month)); 643 | 644 | bool is_valid = Date::vali_date(start_day, start_month, start_year, end_day, end_month, end_year); 645 | 646 | ImGui::Spacing(); 647 | 648 | if (!is_valid) 649 | { 650 | ImGui::TextColored(ImVec4(1, 0, 0, 1), "End date must be after start date."); 651 | } 652 | 653 | ImGui::Spacing(); 654 | ImGui::Separator(); 655 | 656 | if (ImGui::Button("OK")) 657 | { 658 | if (is_valid) 659 | { 660 | File::m_date.start = Date::get_date_from_ymd(start_day, start_month, start_year); 661 | File::m_date.end = Date::get_date_from_ymd(end_day, end_month, end_year); 662 | 663 | ImGui::CloseCurrentPopup(); 664 | } 665 | } 666 | 667 | ImGui::SameLine(); 668 | if (ImGui::Button("Cancel")) 669 | { 670 | ImGui::CloseCurrentPopup(); 671 | } 672 | 673 | ImGui::EndPopup(); 674 | } 675 | } 676 | 677 | ImGui::EndChild(); 678 | } 679 | ImGui::EndDisabled(); 680 | 681 | // Child 2.3 - Generate widgets 682 | { 683 | ImGui::SeparatorText("Generate"); 684 | ImGui::BeginChild("Child_R3", ImVec2(0, ImGui::GetContentRegionAvail().y * 0.5f), false, ImGuiWindowFlags_HorizontalScrollbar); 685 | { 686 | ImVec2 window_size{ImGui::GetContentRegionAvail()}; 687 | ImVec2 button_size{ImVec2(window_size.x * 0.2f, window_size.y * 0.35f)}; 688 | 689 | static std::string start_button_text{"Start"}; 690 | 691 | ImGui::BeginDisabled(disable_start_btn); 692 | if (ImGui::Button(start_button_text.c_str(), button_size)) 693 | { 694 | if (g_started) 695 | { 696 | g_paused = !g_paused; 697 | if (g_paused) 698 | { 699 | start_button_text = "Resume"; 700 | } 701 | else 702 | { 703 | start_button_text = "Pause"; 704 | } 705 | } 706 | else 707 | { 708 | #ifdef __EMSCRIPTEN__ 709 | g_emscripten_generate_flag = true; 710 | #else 711 | IGFD::FileDialogConfig config; 712 | config.path = "."; 713 | config.fileName = ""; 714 | config.countSelectionMax = 1; 715 | config.flags = ImGuiFileDialogFlags_Modal | ImGuiFileDialogFlags_ConfirmOverwrite; 716 | ImGuiFileDialog::Instance()->OpenDialog( 717 | "GenerateDlg", // vKey 718 | "Save Cards", // vTitle 719 | "Text Documents (*.txt){.txt},All files (*.*){.*}", // vFilters 720 | config); 721 | #endif 722 | } 723 | } 724 | ImGui::EndDisabled(); 725 | if (ImGuiFileDialog::Instance()->Display("GenerateDlg", ImGuiWindowFlags_NoCollapse, popup_min_window_size) || g_emscripten_generate_flag) 726 | { 727 | 728 | if (ImGuiFileDialog::Instance()->IsOk() || g_emscripten_generate_flag) 729 | { 730 | #ifdef __EMSCRIPTEN__ 731 | std::string exp_path = "/tmp/temp_output.txt"; 732 | g_emscripten_generate_flag = false; 733 | #else 734 | std::string exp_path = ImGuiFileDialog::Instance()->GetFilePathName(); 735 | #endif 736 | static std::ofstream output_file; 737 | output_file.open(exp_path.c_str(), std::ios::trunc); 738 | 739 | if (output_file.is_open()) 740 | { 741 | start_button_text = "Pause"; 742 | g_started = true; 743 | g_progress = 0.0f; 744 | std::shared_ptr db{DB_API::read_db(g_current_db_path)}; 745 | 746 | #ifdef __EMSCRIPTEN__ 747 | File::start_export(cards_vec, cards_selection, amount, db, "/tmp/temp_output.txt"); 748 | #else 749 | std::thread write_thread(&File::export_cards, std::ref(output_file), cards_vec, cards_selection, amount, db); 750 | write_thread.detach(); 751 | #endif 752 | } 753 | else 754 | { 755 | ImGui::OpenPopup("File Error"); 756 | } 757 | } 758 | ImGuiFileDialog::Instance()->Close(); 759 | } 760 | #ifdef __EMSCRIPTEN__ 761 | if (export_finished.load()) 762 | { 763 | 764 | download_file("/tmp/temp_output.txt", "Cards_output.txt", g_emscripten_generate_flag); // dummy flag 765 | export_finished = false; 766 | } 767 | #endif 768 | 769 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX)); 770 | if (ImGui::BeginPopupModal("File Error")) 771 | { 772 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 773 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)}; 774 | ImGui::TextWrapped("Couldn't open file"); 775 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x / 2, popup_window_size.y - button_size.y * 2)); 776 | 777 | if (ImGui::Button("OK", button_size)) 778 | { 779 | ImGui::CloseCurrentPopup(); 780 | } 781 | ImGui::EndPopup(); 782 | } 783 | 784 | ImGui::SameLine(); 785 | ImGui::BeginDisabled(g_started == false); 786 | static bool old_pause; 787 | if (ImGui::Button("Stop", button_size)) 788 | { 789 | old_pause = g_paused; 790 | g_paused = true; 791 | ImGui::OpenPopup("Stop"); 792 | } 793 | ImGui::EndDisabled(); 794 | 795 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX)); 796 | if (ImGui::BeginPopupModal("Stop")) 797 | { 798 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 799 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)}; 800 | ImGui::TextWrapped("Are you sure you want to stop?"); 801 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2)); 802 | 803 | if (ImGui::Button("Yes", button_size)) 804 | { 805 | g_started = false; 806 | ImGui::CloseCurrentPopup(); 807 | } 808 | ImGui::SameLine(); 809 | if (ImGui::Button("No", button_size)) 810 | { 811 | g_paused = old_pause; 812 | ImGui::CloseCurrentPopup(); 813 | } 814 | ImGui::EndPopup(); 815 | } 816 | 817 | if (g_started == false) 818 | { 819 | g_paused = false; 820 | start_button_text = "Start"; 821 | } 822 | 823 | // Calculate the Y position to align the progress bar 824 | ImVec2 progress_bar_size{-1, window_size.y * 0.35f}; 825 | ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - progress_bar_size.y); 826 | ImGui::ProgressBar(g_progress, progress_bar_size); 827 | } 828 | ImGui::EndChild(); 829 | } 830 | 831 | // Child 2.4 - Style and about widgets 832 | { 833 | ImGui::BeginChild("Child_R4", ImVec2(0, ImGui::GetContentRegionAvail().y), false, ImGuiWindowFlags_HorizontalScrollbar); 834 | 835 | ImVec2 window_size{ImGui::GetContentRegionAvail()}; 836 | ImVec2 button_size{ImVec2(window_size.x * 0.25f, window_size.y * 0.4f)}; 837 | ImGui::SetCursorPosY(ImGui::GetCursorPosY() + window_size.y - button_size.y); 838 | 839 | static bool enable_dark_mode{true}; 840 | static std::string style_button_text{"Light Mode"}; 841 | // Style button 842 | if (ImGui::Button(style_button_text.c_str(), button_size)) 843 | { 844 | enable_dark_mode = !enable_dark_mode; 845 | if (enable_dark_mode) 846 | { 847 | style_button_text = "Light Mode"; 848 | ImGui::StyleColorsDark(); 849 | } 850 | else 851 | { 852 | style_button_text = "Dark Mode"; 853 | ImGui::StyleColorsLight(); 854 | } 855 | 856 | #ifdef __EMSCRIPTEN__ 857 | if (enable_dark_mode) 858 | { 859 | set_background_dark_mode(); 860 | } 861 | else 862 | { 863 | set_background_light_mode(); 864 | } 865 | #endif 866 | } 867 | 868 | ImGui::SameLine(); 869 | 870 | // About button 871 | if (ImGui::Button("About", button_size)) 872 | { 873 | ImGui::OpenPopup("About"); 874 | } 875 | 876 | ImGui::SetNextWindowSizeConstraints(popup_min_window_size, ImVec2(FLT_MAX, FLT_MAX)); 877 | if (ImGui::BeginPopupModal("About")) 878 | { 879 | ImGui::Text("%s", m_title.c_str()); 880 | ImGui::Separator(); 881 | #ifdef __EMSCRIPTEN__ 882 | static std::string about_str = "An open-source tool designed to generate random credit card numbers. It operates offline, ensuring your privacy.\nThe database is stored locally in an SQLite3 file.\n\nThe software is released under the " + m_license + " license." + "\n\nThe online version is significantly slower than the desktop app (available in the url below)."; 883 | #else 884 | static std::string about_str = "An open-source tool designed to generate random credit card numbers. It operates offline, ensuring your privacy.\nThe database is stored locally in an SQLite3 file.\n\nThe software is released under the " + m_license + " license."; 885 | #endif 886 | ImGui::TextWrapped("%s", about_str.c_str()); 887 | 888 | ImVec2 cur_pos = ImGui::GetCursorPos(); 889 | ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "%s", m_url.c_str()); 890 | if (ImGui::IsItemHovered()) 891 | { 892 | ImGui::SetCursorPos(cur_pos); 893 | ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", m_url.c_str()); 894 | } 895 | if (ImGui::IsItemClicked()) 896 | { 897 | 898 | #if defined(_WIN64) || defined(_WIN32) 899 | static std::string open_url = "start " + m_url; 900 | #elif __linux__ 901 | static std::string open_url = "xdg-open " + m_url; 902 | #elif __APPLE__ 903 | static std::string open_url = "open " + m_url; 904 | #endif 905 | #ifdef EMSCRIPTEN 906 | EM_ASM_({ 907 | var url = UTF8ToString($0); 908 | window.open(url, '_blank'); }, m_url.c_str()); 909 | #else 910 | system(open_url.c_str()); 911 | #endif 912 | } 913 | ImVec2 popup_window_size{ImGui::GetWindowSize()}; 914 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.25f, popup_window_size.y * 0.1f)}; 915 | ImGui::SetCursorPos(ImVec2((popup_window_size.x - button_size.x) / 2, popup_window_size.y - button_size.y * 1.5f)); 916 | 917 | if (ImGui::Button("Close", button_size)) 918 | { 919 | ImGui::CloseCurrentPopup(); 920 | } 921 | ImGui::EndPopup(); 922 | } 923 | ImGui::EndChild(); 924 | } 925 | ImGui::EndChild(); 926 | } 927 | 928 | // draw a vertical separator in the middle 929 | float spaceBetween = ImGui::GetStyle().ItemSpacing.x; 930 | ImGui::GetWindowDrawList()->AddLine(ImVec2(main_window_size.x * 0.5f + spaceBetween * 0.5f, 0), ImVec2(main_window_size.x * 0.5f + spaceBetween * 0.5f, main_window_size.y), ImGui::GetColorU32(ImGuiCol_Separator)); 931 | 932 | ImGui::End(); 933 | } 934 | 935 | private: 936 | ImGuiWindowFlags m_window_flags{}; 937 | std::string m_title{}; 938 | std::string m_url{}; 939 | std::string m_license{}; 940 | std::chrono::nanoseconds m_cvv_duration{}; 941 | std::chrono::nanoseconds m_date_duration{}; 942 | std::chrono::nanoseconds m_name_duration{}; 943 | std::chrono::nanoseconds m_duration{}; 944 | bool m_disable_name_option{false}; 945 | }; 946 | 947 | // The pointer is just for emscripten 948 | std::unique_ptr app; 949 | 950 | /** 951 | * @brief Runs the GUI application with a specified version and URL. 952 | * 953 | * This function initializes and runs the GUI application using the provided version 954 | * and URL information. It creates an instance of the App class with the specified title, 955 | * URL, and window dimensions and then starts the application loop. 956 | * 957 | * @param version The version information to be displayed in the application title. 958 | * @param url The URL information to be used by the application. 959 | */ 960 | void gui::run(const std::string &version, const std::string &url, const std::string &license) 961 | { 962 | const std::string title{"CC_Generator - Version " + version}; 963 | app = std::make_unique(title, url, license, 1080, 640); 964 | 965 | #if __EMSCRIPTEN__ 966 | static auto main_loop = []() 967 | { 968 | if (app) 969 | { 970 | if (!app->should_close()) 971 | app->run_frame(); 972 | else 973 | { 974 | emscripten_cancel_main_loop(); 975 | app.reset(); 976 | } 977 | } 978 | }; 979 | 980 | emscripten_set_main_loop(+main_loop, 0, 1); 981 | app->startup(); 982 | #else 983 | app->run(); 984 | #endif 985 | } -------------------------------------------------------------------------------- /src/GUI/GUI_.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "imgui.h" 4 | #include "imgui_impl_glfw.h" 5 | #include "imgui_impl_opengl3.h" 6 | #include "GLFW/glfw3.h" 7 | 8 | #include "ImGuiFileDialog.h" 9 | #include "misc/cpp/imgui_stdlib.h" 10 | 11 | #include "DB_API.h" 12 | #include "Card.h" 13 | #include "File.h" 14 | 15 | #if defined(_WIN64) || defined(_WIN32) 16 | #define NOMINMAX 17 | #endif 18 | 19 | #if defined(__x86_64) || defined(_M_X64) 20 | static ImGuiDataType imgui_data_type = ImGuiDataType_U64; 21 | #define DATATYPE ImU64 22 | #elif defined(__i386) || defined(_M_IX86) 23 | static ImGuiDataType imgui_data_type = ImGuiDataType_U32; 24 | #define DATATYPE ImU32 25 | #else 26 | // WASM 27 | static ImGuiDataType imgui_data_type = ImGuiDataType_U32; 28 | #define DATATYPE ImU32 29 | #endif 30 | 31 | // global variables 32 | extern std::atomic g_paused; 33 | extern std::atomic g_started; 34 | extern std::atomic g_progress; 35 | 36 | namespace gui 37 | { 38 | /** 39 | * @brief Template class for creating GUI applications using GLFW and ImGui. 40 | * 41 | * This template provides a basic structure for creating GUI applications using 42 | * GLFW for window management and ImGui for GUI rendering. 43 | * 44 | * @tparam DerivedClass The derived class implementing specific functionality. 45 | */ 46 | template 47 | class GuiApp 48 | { 49 | public: 50 | /** 51 | * @brief Constructor for the GuiApp class. 52 | * 53 | * Initializes GLFW, creates a window, and sets up ImGui. 54 | * 55 | * @param title The title of the application window. 56 | * @param url A string containing the URL information. 57 | * @param window_w The width of the application window. 58 | * @param window_h The height of the application window. 59 | */ 60 | GuiApp(const std::string &title, const std::string &url, const int window_w, const int window_h) 61 | { 62 | // Initialize GLFW 63 | if (!glfwInit()) 64 | { 65 | std::cerr << "Couldn't initialize GLFW" << std::endl; 66 | std::exit(1); 67 | } 68 | 69 | // Create a windowed mode window and its OpenGL context 70 | m_window = glfwCreateWindow(window_w, window_h, title.c_str(), NULL, NULL); 71 | if (m_window == NULL) 72 | { 73 | glfwTerminate(); 74 | std::cerr << "Couldn't create window" << std::endl; 75 | std::exit(1); 76 | } 77 | 78 | // center the window 79 | { 80 | // Get the primary monitor 81 | GLFWmonitor *primaryMonitor = glfwGetPrimaryMonitor(); 82 | 83 | // Get the video mode of the primary monitor 84 | const GLFWvidmode *mode = glfwGetVideoMode(primaryMonitor); 85 | 86 | // Calculate the center position of the screen 87 | int screenWidth = mode->width; 88 | int screenHeight = mode->height; 89 | int windowWidth, windowHeight; 90 | glfwGetWindowSize(m_window, &windowWidth, &windowHeight); 91 | 92 | int xPos = (screenWidth - windowWidth) / 2; 93 | int yPos = (screenHeight - windowHeight) / 2; 94 | 95 | // Set the window position 96 | glfwSetWindowPos(m_window, xPos, yPos); 97 | } 98 | 99 | // Initialize Dear ImGui 100 | IMGUI_CHECKVERSION(); 101 | ImGui::CreateContext(); 102 | 103 | glfwMakeContextCurrent(m_window); 104 | ImGui_ImplGlfw_InitForOpenGL(m_window, true); 105 | 106 | ImGuiIO &io = ImGui::GetIO(); 107 | (void)io; 108 | 109 | #ifdef __EMSCRIPTEN__ 110 | ImGui_ImplOpenGL3_Init("#version 300 es"); 111 | #else 112 | ImGui_ImplOpenGL3_Init("#version 330"); 113 | #endif 114 | } 115 | 116 | /** 117 | * @brief Destructor for the GuiApp class. 118 | * 119 | * Cleans up resources allocated during the initialization. 120 | */ 121 | ~GuiApp() 122 | { 123 | // Cleanup 124 | ImGui_ImplOpenGL3_Shutdown(); 125 | ImGui_ImplGlfw_Shutdown(); 126 | ImGui::DestroyContext(); 127 | glfwDestroyWindow(m_window); 128 | glfwTerminate(); 129 | } 130 | 131 | /** 132 | * @brief Main loop of the GUI application. 133 | * 134 | * Enters the main loop where events are polled, ImGui frames are started, 135 | * and rendering is performed until the window is closed. 136 | */ 137 | void run() 138 | { 139 | startup(); 140 | 141 | // Main loop 142 | while (!glfwWindowShouldClose(m_window)) 143 | { 144 | run_frame(); 145 | } 146 | } 147 | 148 | /** 149 | * @brief Checks whether the application window should close. 150 | * 151 | * This function queries the underlying GLFW window to determine if a close 152 | * request has been made (e.g., by clicking the window close button). 153 | * 154 | * @return true if the window should close, false otherwise. 155 | */ 156 | bool should_close() const 157 | { 158 | return glfwWindowShouldClose(m_window); 159 | } 160 | 161 | /** 162 | * @brief Executes a single frame of the application loop. 163 | * 164 | * This function performs the following operations in order: 165 | * - Polls window events (e.g., keyboard, mouse, window close). 166 | * - Starts a new ImGui frame using OpenGL3 and GLFW backends. 167 | * - Calls the `update()` method to build the ImGui interface. 168 | * - Renders the ImGui draw data using OpenGL. 169 | * - Swaps the front and back buffers to present the rendered frame. 170 | */ 171 | void run_frame() 172 | { 173 | // Poll events and handle window close 174 | glfwPollEvents(); 175 | if (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 176 | { 177 | } 178 | // Start the ImGui frame 179 | ImGui_ImplOpenGL3_NewFrame(); 180 | ImGui_ImplGlfw_NewFrame(); 181 | ImGui::NewFrame(); 182 | 183 | update(); 184 | 185 | // Rendering 186 | ImGui::Render(); 187 | int display_w, display_h; 188 | glfwGetFramebufferSize(m_window, &display_w, &display_h); 189 | glViewport(0, 0, display_w, display_h); 190 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 191 | glClear(GL_COLOR_BUFFER_BIT); 192 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); 193 | 194 | // Swap buffers 195 | glfwSwapBuffers(m_window); 196 | } 197 | 198 | /** 199 | * @brief Function called to update the GUI application state. 200 | * 201 | * This function should be implemented in the derived class to handle 202 | * application-specific updates. 203 | */ 204 | void update() 205 | { 206 | static_cast(this)->update(); 207 | } 208 | 209 | /** 210 | * @brief Function called at the start of the GUI application. 211 | * 212 | * This function should be implemented in the derived class to handle 213 | * application-specific startup procedures. 214 | */ 215 | void startup() 216 | { 217 | static_cast(this)->startup(); 218 | } 219 | 220 | GLFWwindow *m_window{}; ///< Pointer to the GLFW window object. 221 | }; 222 | } -------------------------------------------------------------------------------- /src/GUI/emscripten_funcs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef __EMSCRIPTEN__ 3 | #include 4 | #include 5 | #include 6 | 7 | extern bool g_emscripten_save_db_flag; 8 | extern bool g_emscripten_open_flag; 9 | extern bool g_emscripten_generate_flag; 10 | 11 | /** 12 | * @brief Retrieves a selected file path from a JavaScript global variable. 13 | * 14 | * This function queries the specified JavaScript variable (e.g., set by a file input dialog) 15 | * and returns its value as a C++ string. If the variable is undefined or null, an empty string is returned. 16 | * 17 | * @param var The name of the global JavaScript variable holding the file path (without `window.` prefix). 18 | * @return The file path as a std::string, or an empty string if not set. 19 | */ 20 | std::string get_selected_file_path_from_js(const std::string &var) 21 | { 22 | std::string str = "window." + var + " ? window." + var + " : ''"; 23 | const char *path = emscripten_run_script_string(str.c_str()); 24 | return std::string(path); 25 | } 26 | 27 | /** 28 | * @brief Opens a file dialog in the browser and loads the selected file into Emscripten's virtual file system (VFS). 29 | * 30 | * This function triggers a file input dialog using JavaScript and, upon file selection, reads the file into memory 31 | * and writes it to the VFS under the `/tmp/` directory. It also sets a global JavaScript variable `window.selectedFilePath` 32 | * and updates a shared C++ boolean flag (`g_emscripten_open_flag`) to signal completion. 33 | * 34 | * @param filter The file type filter (e.g., ".db") to restrict selectable files in the dialog. 35 | */ 36 | void open_file_dialog(const std::string &filter) 37 | { 38 | uintptr_t flag_ptr = (uintptr_t)&g_emscripten_open_flag; 39 | const char *filter_cstr = filter.c_str(); // ensure pointer remains valid 40 | 41 | EM_ASM_({ 42 | // Reset flag initially (0 = false) 43 | // Write 0 to the C++ bool flag memory 44 | HEAPU8[$0] = 0; 45 | 46 | let input = document.createElement('input'); 47 | window.selectedFilePath = null; 48 | input.type = 'file'; 49 | // input.accept = '.db'; 50 | input.accept = UTF8ToString($1); 51 | 52 | input.onchange = e => { 53 | let file = e.target.files[0]; 54 | let reader = new FileReader(); 55 | 56 | reader.onload = function () { 57 | let data = new Uint8Array(reader.result); 58 | let filename = "/tmp/" + file.name; 59 | 60 | FS.writeFile(filename, data); 61 | console.log("File written to VFS:", filename); 62 | window.selectedFilePath = filename; 63 | // Set C++ flag to true by writing 1 into the memory location 64 | HEAPU8[$0] = 1; 65 | }; 66 | 67 | reader.readAsArrayBuffer(file); 68 | }; 69 | 70 | input.click(); }, flag_ptr, filter_cstr); 71 | } 72 | 73 | /** 74 | * @brief Triggers a download of a file from Emscripten's virtual file system (VFS) to the user's local machine. 75 | * 76 | * This function reads the specified file from the VFS, creates a downloadable Blob in the browser, 77 | * and simulates a click to start the download. The download is named according to `download_file`. 78 | * After triggering the download, it sets the referenced C++ flag to `false` (0) to signal completion. 79 | * 80 | * @param vfs_path Path to the file in Emscripten's virtual file system. 81 | * @param download_file Desired name for the downloaded file. 82 | * @param flag Reference to a boolean flag updated after the download is triggered. 83 | */ 84 | void download_file(const std::string &vfs_path, const std::string &download_file, bool &flag) 85 | { 86 | uintptr_t flag_ptr = reinterpret_cast(&flag); 87 | 88 | EM_ASM_({ 89 | const path = UTF8ToString($0); 90 | const downloadName = UTF8ToString($1); 91 | const flagPtr = $2; 92 | 93 | try 94 | { 95 | const data = FS.readFile(path); 96 | const blob = new Blob([data], 97 | { type: 'application/octet-stream' }); 98 | const url = URL.createObjectURL(blob); 99 | 100 | const a = document.createElement('a'); 101 | a.href = url; 102 | a.download = downloadName; 103 | a.setAttribute('download', downloadName); 104 | a.click(); 105 | 106 | URL.revokeObjectURL(url); 107 | console.log("Download triggered:", path); 108 | } 109 | catch (e) 110 | { 111 | console.error("Failed to download file:", e); 112 | } 113 | 114 | // Set the C++ flag to false (0) 115 | HEAPU8[flagPtr] = 0; }, vfs_path.c_str(), download_file.c_str(), flag_ptr); 116 | } 117 | 118 | /** 119 | * @brief Sets the background color of the HTML and elements. 120 | * 121 | * This function is implemented in JavaScript via Emscripten and modifies the 122 | * background color of both the `` and `` elements using the given 123 | * hexadecimal color code. 124 | * 125 | * @param color A C-style string representing the color in hex format (e.g., "#FFFFFF"). 126 | */ 127 | EM_JS(void, set_background_color, (const char *color), { 128 | document.documentElement.style.setProperty('background-color', UTF8ToString(color)); 129 | document.body.style.setProperty('background-color', UTF8ToString(color)); 130 | }); 131 | 132 | /** 133 | * @brief Sets the webpage background to a dark color. 134 | * 135 | * Internally calls `set_background_color()` with a dark color value. 136 | * Intended for toggling to dark mode. 137 | */ 138 | void set_background_dark_mode() 139 | { 140 | set_background_color("#0E0E0E"); 141 | } 142 | 143 | /** 144 | * @brief Sets the webpage background to a light color. 145 | * 146 | * Internally calls `set_background_color()` with a light color value. 147 | * Intended for toggling to light mode. 148 | */ 149 | void set_background_light_mode() 150 | { 151 | set_background_color("#F0F0F0"); 152 | } 153 | 154 | #endif --------------------------------------------------------------------------------