Initial commit.

This commit is contained in:
Relintai 2023-04-07 11:11:45 +02:00
commit 8633761916
41 changed files with 2379 additions and 0 deletions

189
.clang-format Normal file
View File

@ -0,0 +1,189 @@
# Commented out parameters are those with the same value as base LLVM style.
# We can uncomment them if we want to change their value, or enforce the
# chosen value in case the base style changes (last sync: Clang 13.0).
---
### General config, applies to all languages ###
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
# AlignArrayOfStructures: None
# AlignConsecutiveMacros: None
# AlignConsecutiveAssignments: None
# AlignConsecutiveBitFields: None
# AlignConsecutiveDeclarations: None
# AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments: false
# AllowAllArgumentsOnNextLine: true
# AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
# AllowShortEnumsOnASingleLine: true
# AllowShortBlocksOnASingleLine: Never
# AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
# AllowShortLambdasOnASingleLine: All
# AllowShortIfStatementsOnASingleLine: Never
# AllowShortLoopsOnASingleLine: false
# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
# AlwaysBreakBeforeMultilineStrings: false
# AlwaysBreakTemplateDeclarations: MultiLine
# AttributeMacros:
# - __capability
# BinPackArguments: true
# BinPackParameters: true
# BraceWrapping:
# AfterCaseLabel: false
# AfterClass: false
# AfterControlStatement: Never
# AfterEnum: false
# AfterFunction: false
# AfterNamespace: false
# AfterObjCDeclaration: false
# AfterStruct: false
# AfterUnion: false
# AfterExternBlock: false
# BeforeCatch: false
# BeforeElse: false
# BeforeLambdaBody: false
# BeforeWhile: false
# IndentBraces: false
# SplitEmptyFunction: true
# SplitEmptyRecord: true
# SplitEmptyNamespace: true
# BreakBeforeBinaryOperators: None
# BreakBeforeConceptDeclarations: true
# BreakBeforeBraces: Attach
# BreakBeforeInheritanceComma: false
# BreakInheritanceList: BeforeColon
# BreakBeforeTernaryOperators: true
# BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
# BreakStringLiterals: true
ColumnLimit: 0
# CommentPragmas: '^ IWYU pragma:'
# CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
# DeriveLineEnding: true
# DerivePointerAlignment: false
# DisableFormat: false
# EmptyLineAfterAccessModifier: Never
# EmptyLineBeforeAccessModifier: LogicalBlock
# ExperimentalAutoDetectBinPacking: false
# FixNamespaceComments: true
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IfMacros:
# - KJ_IF_MAYBE
# IncludeBlocks: Preserve
IncludeCategories:
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
# IncludeIsMainSourceRegex: ''
# IndentAccessModifiers: false
IndentCaseLabels: true
# IndentCaseBlocks: false
# IndentGotoLabels: true
# IndentPPDirectives: None
# IndentExternBlock: AfterExternBlock
# IndentRequires: false
IndentWidth: 4
# IndentWrappedFunctionNames: false
# InsertTrailingCommas: None
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
# LambdaBodyIndentation: Signature
# MacroBlockBegin: ''
# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 19
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyBreakTemplateDeclaration: 10
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 60
# PenaltyIndentedWhitespace: 0
# PointerAlignment: Right
# PPIndentWidth: -1
# ReferenceAlignment: Pointer
# ReflowComments: true
# ShortNamespaceLines: 1
# SortIncludes: CaseSensitive
# SortJavaStaticImport: Before
# SortUsingDeclarations: true
# SpaceAfterCStyleCast: false
# SpaceAfterLogicalNot: false
# SpaceAfterTemplateKeyword: true
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeCaseColon: false
# SpaceBeforeCpp11BracedList: false
# SpaceBeforeCtorInitializerColon: true
# SpaceBeforeInheritanceColon: true
# SpaceBeforeParens: ControlStatements
# SpaceAroundPointerQualifiers: Default
# SpaceBeforeRangeBasedForLoopColon: true
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
# SpaceInEmptyBlock: false
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
# SpacesInAngles: Never
# SpacesInContainerLiterals: true
# SpacesInConditionalStatement: false
# SpacesInContainerLiterals: true
# SpacesInCStyleCastParentheses: false
## Pandemonium TODO: We'll want to use a min of 1, but we need to see how to fix
## our comment capitalization at the same time.
SpacesInLineCommentPrefix:
Minimum: 0
Maximum: -1
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
# SpaceBeforeSquareBrackets: false
# BitFieldColonSpacing: Both
# StatementAttributeLikeMacros:
# - Q_EMIT
# StatementMacros:
# - Q_UNUSED
# - QT_REQUIRE_VERSION
TabWidth: 4
# UseCRLF: false
UseTab: Always
# WhitespaceSensitiveMacros:
# - STRINGIZE
# - PP_STRINGIZE
# - BOOST_PP_STRINGIZE
# - NS_SWIFT_NAME
# - CF_SWIFT_NAME
---
### C++ specific config ###
Language: Cpp
Standard: c++14
---
### ObjC specific config ###
Language: ObjC
# ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
# ObjCBreakBeforeNestedBlockParam: true
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
---
### Java specific config ###
Language: Java
# BreakAfterJavaFieldAnnotations: false
JavaImportGroups: ['net.relintai.pandemonium', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
...

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: relintai
open_collective: # Replace with a single Open Collective username
ko_fi: relintai
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
engine
pandemonium_engine
modules/*
logs/*
__pycache__/**
*.pyc
*.d
*.o
*.meta
game/.import/**
game/.prop_tool_temp/**
.sconsign.dblite
.DS_Store
export/**
release/**
.vs/*
.kdev4/*
.vscode/*
TestRWTextures
_build/*
_binaries/*
game/android/build/*
*.blend1
.dir-locals.el
build.config
__pycache__/*

1
HEADS Normal file
View File

@ -0,0 +1 @@
{"engine": {"3.2": "94a0fc47f7b4e90f8973f9adbfd3312579ed2825", "master": "8c73e813134001e575b6f59e3b0100471c007410", "3.x": "c4864a0e5f73a375259503ea1485794a6aad6df7"}, "world_generator": {"master": "260c430f11b0b591eaf4714516419aa327d2842c"}, "entity_spell_system": {"master": "3536f01bacf5f54cefb32b768cd020a1f94d0ade"}, "ui_extensions": {"master": "80a3b96fc56991a0f88a1d441ed1e3cebaf3307a"}, "voxelman": {"master": "65485930a20f65844d496b4ba47dec5b6ed70b91"}, "texture_packer": {"master": "ae4d222fbaade063ed6f0bc9f3aaa53df68a7fed"}, "fastnoise": {"master": "46bb1f610bfb7171613b5c708d312bcf94e89356"}, "mesh_data_resource": {"master": "a062d871d49d954c5466b9de54b4075cb61cbef4"}, "procedural_animations": {"master": "f8aae42bf06b3936cc6bd24cb18e1c3ec9f78f4f"}, "ess_data": {"master": "3bd637fdd3304b64a18287a49a6b7387acf2f5de"}, "props": {"master": "983090d21a08ebed30a5ce06681269819ab12e48"}, "mesh_utils": {"master": "b52a261c31f04fad624e5cfbcdcc4a45d61136da"}, "broken_seals_module": {"master": "52c5a81350db1c29d375c63d95010260911ec034"}, "thread_pool": {"master": "0917511d04bb1aa308385b63ec88d3c182990628"}, "terraman": {"master": "c72d8fc03295588fc18c5168ce351bd0c321ec5f"}, "pandemonium_engine": {"master": "a76df86ef34bf1989c61aad611ed35418ba1522b"}}

19
LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2023-present Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

220
README.md Normal file
View File

@ -0,0 +1,220 @@
# WP Saver
Port of https://github.com/Relintai/wp_saver_rcpp_fw to the pandemonium engine.
## Project overview
The project's workflow has been set up so you can easily compile the proper version of the engine for yourself if you want to.
See the [Compiling](#compiling) section if you want to know how to do this.
## Compiling
First make sure, that you have everything installed to be able to compile the engine.
See the [official docs for compiling Godot](https://docs.godotengine.org/en/3.4/development/compiling/index.html) for more info
(the pandemonium engine is a godot fork, the same instructions will work).
My setup/compile script uses the same tools, so you don't need to install anything else.
Even though the project doesn't use godot anymore, their docs are still sufficient.
Now let's clone this repository:
``` git clone https://github.com/Relintai/pandemonium_cms ```
cd into the new folder:
``` cd pandemonium_cms ```
Now let's run the project's setup script, by calling scons without arguments.
``` scons ```
This will clone and setup the engine, and all of the required modules into a new `engine` folder inside the project, using http.
(If you want to use the github's ssh links append `repository_type=ssh` like ``` scons repository_type=ssh ```)
Once it is done you can compile the engine.
To build the editor on windows with 4 threads run the following command:
``` scons bew -j4 ```
To build the editor on linux with 4 threads run the following command:
``` scons bel -j4 ```
I call this feature of the setup script build words. [See](#build-words).
Once the build finishes you can find the editor executable inside the `./engine/bin/` folder.
For convenience there is a provided `editor.sh`, or `editor.bat` for running it from the project's folder.
These will create a copy, so you can even compile while the editor is running.
Alternatively if you don't want to use build words, you can also just go into the engine folder:
``` cd engine ```
And compile godot as per the [official docs](https://docs.godotengine.org/en/latest/development/compiling/index.html).
### Build words
The project's setup script contains support for "build words". These can be used from the root of this project.
For example to build the editor for windows with 4 threads you can use:
``` scons bew -j4 ```
The first argument must start with b (build), then it needs to be followed by a few abbreviations (the order does not matters)
The rest of the arguments will be passed directly to godot's scons script.
#### Editor
Append `e` to build with `tools=yes` a.k.a. the editor.
``` scons bew -j4 ```
if you omit `e`, the system will build the export template for you. For example:
``` scons bw -j4 ```
This will be the `release_debug` windows export template.
#### Platform abbreviations
`l`: linux \
`w`: windows \
`a`: android \
`j`: Javascript \
`i`: iphone (Not yet finished, use `build_ios.sh`, and `build_ios_release.sh`) \
Mac OSX: Not yet finished, use `build_osx.sh`
#### Target abbreviations
By default the system builds in release_debug.
Append `d` for debug, or `r` for release.
``` scons bewd -j4 ```
build editor windows debug
``` scons bwr -j4 ```
build windows release (this will build the windows release export template)
#### Shared modules
Note: This only works on linux!
append `s` to the build string.
Optionally you can also make the build system only build a target module, by appending one of these:
`E`: Entity Spell System \
`T`: Texture Packer \
`V`: Voxelman \
`W`: World Generator \
`P`: Procedural Animations
Example:
``` scons belsE -j4 ```
build editor linux shared (Entity Spell System) with 4 threads
Note: to easily run the editor you can use the `editor.sh` or `editor.bat` in the root of the project.
#### Other
Append `v` to pass the `vsproj=yes` parameter to the build script. This will generate Visual Studio project files.\
Append `c` to pass the `compiledb=yes` parameter to the build script. This is a new feature in 3.x to have this disabled by default to lessen compile times.
#### Postfixes
There are a few postfixes for the build words. These are more complex options. You have to append them to your build word with an underscore.
You can use as many as you want.
For example:
``` scons bel_slim_latomic -j4 ```
##### slim
With this postfix you can build a slimmed down version of the engine. This disables quite a few unneeded modules.
``` scons bel_slim -j4 ```
##### latomic
If you get linker errors while building the game/editor about undefined referenced with atomic related functions you can use this postfix.
It will add the ` -latomic ` command line switch to the linker flags.
I ran into this issue while building on a raspberry pi 4 with the x11 platform. It might be related to the recent reworks to threading.
``` scons bel_latomic -j4 ```
##### strip
Appends `debug_symbols=no` to the build command, which will strip the resulting binary from debug symbols.
``` scons bel_strip -j4 ```
##### threads
Appends `threads_enabled=yes` to the build command. Useful for building the editor for html.
``` scons bej_threads -j4 ```
#### Scons cache, and sdk locations
In order to use scons cache and to tell the build system where some of the required sdks are located you usually
have to use environment variables. Most of the time you might just want to add them globally,
howewer this is sometimes unfeasible (e.g. you don't have administrator access, or you just want to have
multiple sdk versions installed).
In order to solve this a build config file was added.
If you want to use the config simply rename the provided `build.config.example` to `build.config`, and customize
the settings inside.
### Manual Setup
If you you don't want to use the setup script (or just want to know what it actually does),
this section will explain how to set everything up manually.
First clone the engine:
``` git clone https://github.com/Relintai/pandemonium_engine ```
Now if you look at the [HEADS file](https://github.com/Relintai/pandemonium_cms/blob/master/HEADS).
It contains the commit hashes for that particular revision for every module and the engine.
The engine now contains all the modules, so at the moment only worry about the engine's commit hash.
You need to go and checkout the proper commit for it.
Now you can go ahead and compile the engine normally.
## Pulling upstream changes
First pull the changes by calling
``` git pull orgin master ```
Then just run `scons`, to will update the modules.
## Upgrading the modules
Note: this is how to update the HEADS file. Normally you don't need to do this.
If you want to update the modules, and the engine to the latest, you can use (`action=update`):
``` scons a=u ```
You can also update different targets: `all`, `engine`, `modules`, `all_addons`, `addons`, `third_party_addons`
For example to update the engine to the latest: ``` scons a=u target=engine ```

173
SConstruct Normal file
View File

@ -0,0 +1,173 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2019-2021 Péter Magyar
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import subprocess
import json
import sys
import module_config
repository_index = 0
clone_command = 'git clone {0} {1}'
target_commits = {}
def setup_repository(data, clone_path, branch = 'master'):
cwd = os.getcwd()
full_path = cwd + clone_path + data[1] + '/'
if not os.path.isdir(full_path):
os.chdir(cwd + clone_path)
subprocess.call(clone_command.format(data[0][repository_index], data[1]), shell=True)
os.chdir(full_path)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git checkout -B ' + branch + ' origin/' + branch, shell=True)
subprocess.call('git pull origin ' + branch, shell=True)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
target = ""
if data[1] in target_commits:
target = target_commits[data[1]][branch]
subprocess.call('git checkout -B ' + branch + ' ' + target, shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
os.chdir(cwd)
def update_repository(data, clone_path, branch = 'master'):
cwd = os.getcwd()
full_path = cwd + clone_path + data[1] + '/'
if not os.path.isdir(full_path):
os.chdir(cwd + clone_path)
subprocess.call(clone_command.format(data[0][repository_index], data[1]), shell=True)
os.chdir(full_path)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git checkout -B ' + branch + ' origin/' + branch, shell=True)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git pull origin ' + branch, shell=True)
process = subprocess.Popen('git rev-parse HEAD', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = process.communicate()[0].decode().strip()
if data[1] not in target_commits:
target_commits[data[1]] = {}
target_commits[data[1]][branch] = output
os.chdir(cwd)
def validate_repository_origin(data, clone_path, branch = 'master'):
full_path = os.path.abspath(clone_path)
if not os.path.isdir(full_path):
return
cwd = os.getcwd()
os.chdir(full_path)
res = subprocess.run('git remote -v', shell=True, capture_output=True)
resstr = res.stdout.decode('ascii')
resarr = resstr.split("\n")
res_orig = []
for l in resarr:
if "origin" in l:
res_orig.append(l)
if len(res_orig) == 0:
print("The repository " + clone_path + " does not seem to have an origin remote. Adding it.")
subprocess.call('git remote add origin ' + data[0][repository_index], shell=True)
os.chdir(cwd)
return
for l in data[0]:
for ll in res_orig:
if l in ll:
os.chdir(cwd)
return
rind = 0
if 'git@' in res_orig[0]:
rind = 1
subprocess.call('git remote remove origin', shell=True)
subprocess.call('git remote add origin ' + data[0][rind], shell=True)
subprocess.call('git pull origin', shell=True)
subprocess.call('git checkout origin/' + branch, shell=True)
print('Updated git remote origin in ' + clone_path)
os.chdir(cwd)
def update_engine():
validate_repository_origin(module_config.engine_repository, './pandemonium_engine/', module_config.pandemonium_branch)
update_repository(module_config.engine_repository, '/', module_config.pandemonium_branch)
engine_abspath = os.path.abspath(module_config.engine_repository[1])
if not os.path.isdir(engine_abspath):
if not os.path.isfile('./HEADS'):
print("Error! HEADS file doesn't exists! Exiting.")
exit()
with open('./HEADS', 'r') as infile:
target_commits = json.load(infile)
if 'repository_type=ssh' in sys.argv:
repository_index = 1
setup_repository(module_config.engine_repository, '/', module_config.pandemonium_branch)
else:
if not os.path.isfile('pandemonium_engine/misc/scripts_app/SConstruct'):
update_engine()
SConscript("pandemonium_engine/misc/scripts_app/SConstruct")

45
build.config.example Normal file
View File

@ -0,0 +1,45 @@
# Copyright (c) 2019-2021 Péter Magyar
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Rename this file to build.config to use it
# Lines starting with # are comments. (Only works at the start of the line!)
# Note:
# ~ will be converted to %userprofile% on windows
# / will be converted to \ on windows
# so you don't have to worry about it
# Visual studio related setup:
visual_studio_call_vcvarsall True
visual_studio_vcvarsall_path C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat
visual_studio_arch amd64
# You can export variables with the export keyword
# You can run commands with the run keywords
# <export/run> <target platform> <exported variable/command>
# available export/run targets: global, linux, windows, android, javascript
export global SCONS_CACHE=~/.scons_cache
export global SCONS_CACHE_LIMIT=5000
export android ANDROID_HOME=~/SDKs/Android/SDK
run javascript source ~/SDKs/emsdk/emsdk_env.sh

6
editor.bat Normal file
View File

@ -0,0 +1,6 @@
copy "pandemonium_engine\bin\pandemonium.windows.opt.tools.64.exe" "pandemonium_engine\bin\run_pandemonium.windows.opt.tools.64.exe" /y
copy "pandemonium_engine\bin\pandemonium.windows.opt.tools.64.pdb" "pandemonium_engine\bin\run_pandemonium.windows.opt.tools.64.pdb" /y
copy "pandemonium_engine\bin\pandemonium.windows.opt.tools.64.exp" "pandemonium_engine\bin\run_pandemonium.windows.opt.tools.64.exp" /y
cmd /c pandemonium_engine\bin\run_pandemonium.windows.opt.tools.64.exe

6
editor.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
cp -u ./pandemonium_engine/bin/pandemonium.x11.opt.tools.64 ./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64
export LD_LIBRARY_PATH=`pwd`/pandemonium_engine/bin/
./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64 -v

4
export_all.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
./pandemonium_engine/misc/scripts_app/export_all.sh wp_saver wps $1

16
game/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
\exports/
\.import/
addons/scene_notes/
addons/todo/
scene-notes\.ini
todo\.cache\.ini
todo\.config\.ini
export_presets\.cfg
export.cfg

3
game/Main.tscn Normal file
View File

@ -0,0 +1,3 @@
[gd_scene format=2]
[node name="Main" type="Node"]

7
game/default_env.tres Normal file
View File

@ -0,0 +1,7 @@
[gd_resource type="Environment3D" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

BIN
game/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

35
game/icon.png.import Normal file
View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

25
game/project.pandemonium Normal file
View File

@ -0,0 +1,25 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
[application]
config/name="WP Saver"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[physics]
common/enable_pause_aware_picking=true
[rendering]
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres"

6
ged.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
cp -u ./pandemonium_engine/bin/pandemonium.x11.opt.tools.64 ./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64
export LD_LIBRARY_PATH=`pwd`/pandemonium_engine/bin/
./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64 -e --path ./game/

6
leditor.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
cp -u ./pandemonium_engine/bin/pandemonium.x11.opt.tools.64.llvm ./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64.llvm
export LD_LIBRARY_PATH=`pwd`/pandemonium_engine/bin/
./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64.llvm

6
lged.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
cp -u ./pandemonium_engine/bin/pandemonium.x11.opt.tools.64.llvm ./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64.llvm
export LD_LIBRARY_PATH=`pwd`/pandemonium_engine/bin/
./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64.llvm -e --path ./game/

4
make_release.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
./pandemonium_engine/misc/scripts_app/make_release.sh wp_saver wps $1

20
module_config.py Normal file
View File

@ -0,0 +1,20 @@
pandemonium_branch = 'master'
engine_repository = [ ['https://github.com/Relintai/pandemonium_engine.git', 'git@github.com:Relintai/pandemonium_engine.git'], 'pandemonium_engine', '' ]
module_repositories = [
]
removed_modules = [
]
addon_repositories = [
]
third_party_addon_repositories = [
]
custom_module_folders = ""
slim_args = 'module_webm_enabled=no module_arkit_enabled=no module_visual_script_enabled=no module_gdnative_enabled=no module_mobile_vr_enabled=no module_theora_enabled=no module_xatlas_unwrap_enabled=no'

6
play.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
cp -u ./pandemonium_engine/bin/pandemonium.x11.opt.tools.64 ./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64
export LD_LIBRARY_PATH=`pwd`/pandemonium_engine/bin/
./pandemonium_engine/bin/run.pandemonium.x11.opt.tools.64 -v --path ./game/

View File

@ -0,0 +1,128 @@
# Commented out parameters are those with the same value as base LLVM style
# We can uncomment them if we want to change their value, or enforce the
# chosen value in case the base style changes (last sync: Clang 6.0.1).
---
### General config, applies to all languages ###
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
# AlignConsecutiveAssignments: false
# AlignConsecutiveDeclarations: false
# AlignEscapedNewlines: Right
# AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
# AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: true
# AllowShortLoopsOnASingleLine: false
# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
# AlwaysBreakBeforeMultilineStrings: false
# AlwaysBreakTemplateDeclarations: false
# BinPackArguments: true
# BinPackParameters: true
# BraceWrapping:
# AfterClass: false
# AfterControlStatement: false
# AfterEnum: false
# AfterFunction: false
# AfterNamespace: false
# AfterObjCDeclaration: false
# AfterStruct: false
# AfterUnion: false
# AfterExternBlock: false
# BeforeCatch: false
# BeforeElse: false
# IndentBraces: false
# SplitEmptyFunction: true
# SplitEmptyRecord: true
# SplitEmptyNamespace: true
# BreakBeforeBinaryOperators: None
# BreakBeforeBraces: Attach
# BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
# BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
# BreakStringLiterals: true
ColumnLimit: 0
# CommentPragmas: '^ IWYU pragma:'
# CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
# DerivePointerAlignment: false
# DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# FixNamespaceComments: true
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IncludeBlocks: Preserve
IncludeCategories:
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
# IndentPPDirectives: None
IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
# KeepEmptyLinesAtTheStartOfBlocks: true
# MacroBlockBegin: ''
# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 19
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right
# RawStringFormats:
# - Delimiter: pb
# Language: TextProto
# BasedOnStyle: google
# ReflowComments: true
# SortIncludes: true
# SortUsingDeclarations: true
# SpaceAfterCStyleCast: false
# SpaceAfterTemplateKeyword: true
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeParens: ControlStatements
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
# SpacesInAngles: false
# SpacesInContainerLiterals: true
# SpacesInCStyleCastParentheses: false
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Always
---
### C++ specific config ###
Language: Cpp
Standard: Cpp03
---
### ObjC specific config ###
Language: ObjC
Standard: Cpp03
ObjCBlockIndentWidth: 4
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
---
### Java specific config ###
Language: Java
# BreakAfterJavaFieldAnnotations: false
JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
...

2
wp_saver_rcpp_fw/.clangd Normal file
View File

@ -0,0 +1,2 @@
CompileFlags:
CompilationDatabase: ./engine/

35
wp_saver_rcpp_fw/.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
engine
modules/*
logs/*
*.d
*.o
*.meta
game/.import/**
game/.prop_tool_temp/**
.sconsign.dblite
.DS_Store
settings.ini
data/**
export/**
release/**
.vs/*
.kdev4/*
.vscode/*
.cache/**
TestRWTextures
_build/*
_binaries/*
game/android/build/*
*.blend1
.dir-locals.el
build.config
database.sqlite

1
wp_saver_rcpp_fw/HEADS Normal file
View File

@ -0,0 +1 @@
{"engine": {"master": "86b890eb8f911d1fcdae28dcbe6330f421eeae3d"}}

19
wp_saver_rcpp_fw/LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2021 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

501
wp_saver_rcpp_fw/SConstruct Normal file
View File

@ -0,0 +1,501 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2019-2021 Péter Magyar
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
EnsureSConsVersion(0, 98, 1)
import sys
import os
import subprocess
import json
import shutil
import traceback
folders = [
'app',
]
module_folders = [
'../custom_modules',
]
databases=True
main_file = 'main.cpp'
repository_index = 0
module_clone_path = '/modules/'
clone_command = 'git clone {0} {1}'
visual_studio_call_vcvarsall = False
visual_studio_vcvarsall_path = 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat'
visual_studio_arch = 'amd64'
exports = {
'global': [],
'linux': [],
'windows': [],
'android': [],
'javascript': [],
}
engine_repository = [ ['https://github.com/Relintai/rcpp_cms.git', 'git@github.com:Relintai/rcpp_cms.git'], 'engine', '' ]
module_repositories = [
]
addon_repositories = [
]
third_party_addon_repositories = [
]
target_commits = {}
engine_branch = 'master'
def onerror(func, path, exc_info):
"""
https://stackoverflow.com/questions/2656322/shutil-rmtree-fails-on-windows-with-access-is-denied
Because Windows.
Error handler for ``shutil.rmtree``.
If the error is due to an access error (read only file)
it attempts to add write permission and then retries.
If the error is for another reason it re-raises the error.
Usage : ``shutil.rmtree(path, onerror=onerror)``
"""
import stat
if not os.access(path, os.W_OK):
# Is the error an access error ?
os.chmod(path, stat.S_IWUSR)
func(path)
else:
raise
def load_target_commits_array():
global target_commits
if os.path.isfile('./HEADS'):
with open('./HEADS', 'r') as infile:
target_commits = json.load(infile)
else:
target_commits = {}
def save_target_commits_array():
with open('./HEADS', 'w') as outfile:
json.dump(target_commits, outfile)
def update_repository(data, clone_path, branch = 'master'):
cwd = os.getcwd()
full_path = cwd + clone_path + data[1] + '/'
if not os.path.isdir(full_path):
os.chdir(cwd + clone_path)
subprocess.call(clone_command.format(data[0][repository_index], data[1]), shell=True)
os.chdir(full_path)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git checkout -B ' + branch + ' origin/' + branch, shell=True)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git pull origin ' + branch, shell=True)
process = subprocess.Popen('git rev-parse HEAD', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = process.communicate()[0].decode().strip()
if data[1] not in target_commits:
target_commits[data[1]] = {}
target_commits[data[1]][branch] = output
os.chdir(cwd)
def setup_repository(data, clone_path, branch = 'master'):
cwd = os.getcwd()
full_path = cwd + clone_path + data[1] + '/'
if not os.path.isdir(full_path):
os.chdir(cwd + clone_path)
subprocess.call(clone_command.format(data[0][repository_index], data[1]), shell=True)
os.chdir(full_path)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git checkout -B ' + branch + ' origin/' + branch, shell=True)
subprocess.call('git pull origin ' + branch, shell=True)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
if data[1] in target_commits:
target = target_commits[data[1]][branch]
subprocess.call('git checkout -B ' + branch + ' ' + target, shell=True)
subprocess.call('git clean -f -d', shell=True)
subprocess.call('git reset', shell=True)
subprocess.call('git reset --hard', shell=True)
os.chdir(cwd)
def copy_repository(data, target_folder, clone_path):
copytree(os.path.abspath(clone_path + data[1] + '/' + data[2]), os.path.abspath(target_folder + data[1]))
def copytree(src, dst):
for item in os.listdir(src):
sp = os.path.join(src, item)
dp = os.path.join(dst, item)
if os.path.isdir(sp):
if os.path.isdir(dp):
shutil.rmtree(dp, onerror=onerror)
shutil.copytree(sp, dp)
else:
if not os.path.isdir(dst):
os.makedirs(dst)
shutil.copy2(sp, dp)
def update_engine():
update_repository(engine_repository, '/', engine_branch)
def update_modules():
for rep in module_repositories:
update_repository(rep, module_clone_path)
copy_repository(rep, './engine/modules/', '.' + module_clone_path)
def update_addons():
for rep in addon_repositories:
update_repository(rep, module_clone_path)
copy_repository(rep, './game/addons/', '.' + module_clone_path)
def update_addons_third_party_addons():
for rep in third_party_addon_repositories:
update_repository(rep, module_clone_path)
copy_repository(rep, './game/addons/', '.' + module_clone_path)
def update_all():
update_engine()
update_modules()
update_addons()
update_addons_third_party_addons()
save_target_commits_array()
def setup_engine():
setup_repository(engine_repository, '/', engine_branch)
def setup_modules():
for rep in module_repositories:
setup_repository(rep, module_clone_path)
copy_repository(rep, './engine/modules/', '.' + module_clone_path)
def setup_addons():
for rep in addon_repositories:
setup_repository(rep, module_clone_path)
copy_repository(rep, './game/addons/', '.' + module_clone_path)
def setup_addons_third_party_addons():
for rep in third_party_addon_repositories:
setup_repository(rep, module_clone_path)
copy_repository(rep, './game/addons/', '.' + module_clone_path)
def setup_all():
setup_engine()
setup_modules()
setup_addons()
setup_addons_third_party_addons()
def format_path(path):
if 'win' in sys.platform:
path = path.replace('/', '\\')
path = path.replace('~', '%userprofile%')
return path
def get_exports_for(platform):
export_command = 'export '
command_separator = ';'
if 'win' in sys.platform:
command_separator = '&'
export_command = 'set '
command = ''
for p in exports[platform]:
command += export_command + p + command_separator
return command
def parse_config():
global visual_studio_vcvarsall_path
global visual_studio_arch
global visual_studio_call_vcvarsall
global exports
if not os.path.isfile('build.config'):
return
with open('build.config', 'r') as f:
for line in f:
ls = line.strip()
if ls == '' or ls.startswith('#'):
continue
words = line.split()
if (len(words) < 2):
print('This build.config line is malformed, and got ignored: ' + ls)
continue
if words[0] == 'visual_studio_vcvarsall_path':
visual_studio_vcvarsall_path = format_path(ls[29:])
elif words[0] == 'visual_studio_arch':
visual_studio_arch = format_path(ls[19:])
elif words[0] == 'visual_studio_call_vcvarsall':
visual_studio_call_vcvarsall = words[1].lower() in [ 'true', '1', 't', 'y', 'yes' ]
elif words[0] == 'export':
if (len(words) < 3) or not words[1] in exports:
print('This build.config line is malformed, and got ignored: ' + ls)
continue
export_path = format_path(ls[8 + len(words[1]):])
exports[words[1]].append(export_path)
parse_config()
env = Environment()
if len(sys.argv) > 1:
arg = sys.argv[1]
arg_split = arg.split('_')
arg = arg_split[0]
arg_split = arg_split[1:]
if arg[0] == 'b':
build_string = get_exports_for('global') + 'scons '
build_string += 'target='
if 'r' in arg:
build_string += 'release'
elif 'd' in arg:
build_string += 'debug'
else:
build_string += 'release_debug'
build_string += ' '
if 'm' in arg:
build_string += 'use_mingw=yes'
else:
if 'win' in sys.platform and visual_studio_call_vcvarsall:
build_string = 'call "{0}" {1}&'.format(visual_studio_vcvarsall_path, visual_studio_arch) + build_string
if 'o' in arg:
build_string += 'use_llvm=yes'
if 'v' in arg:
build_string += 'vsproj=yes'
if databases:
build_string += " databases=yes "
build_string += 'folders="'
for f in folders:
build_string += '../' + f
build_string += ';'
build_string += '" '
build_string += 'main_file="../' + main_file + '" '
for i in range(2, len(sys.argv)):
build_string += ' ' + sys.argv[i] + ' '
cwd = os.getcwd()
full_path = cwd + '/engine/'
if not os.path.isdir(full_path):
print('engine directory doesnt exists.')
exit()
os.chdir(full_path)
if 'l' in arg:
build_string += 'platform=x11'
build_string = get_exports_for('linux') + build_string
print('Running command: ' + build_string)
subprocess.call(build_string, shell=True)
elif 'w' in arg:
build_string += 'platform=windows'
build_string = get_exports_for('windows') + build_string
print('Running command: ' + build_string)
subprocess.call(build_string, shell=True)
elif 'a' in arg:
build_string += 'platform=android'
build_string = get_exports_for('android') + build_string
print('Running command: ' + build_string + ' android_arch=armv7')
subprocess.call(build_string + ' android_arch=armv7', shell=True)
print('Running command: ' + build_string + ' android_arch=arm64v8')
subprocess.call(build_string + ' android_arch=arm64v8', shell=True)
print('Running command: ' + build_string + ' android_arch=x86')
subprocess.call(build_string + ' android_arch=x86', shell=True)
os.chdir(full_path + 'platform/android/java/')
print('Running command: ' + get_exports_for('global') + get_exports_for('android') + './gradlew generateGodotTemplates')
subprocess.call(get_exports_for('global') + get_exports_for('android') + './gradlew generateGodotTemplates', shell=True)
elif 'j' in arg:
build_string += 'platform=javascript'
build_string = get_exports_for('javascript') + build_string
print('Running command: ' + build_string)
subprocess.call(build_string, shell=True)
else:
print('No platform specified')
exit()
exit()
elif arg[0] == 'p':
if arg == 'p':
#print("Applies a patch. Append c for the compilation database patch. For example: pc")
print("Applies a patch. No Patches right now.")
exit()
cwd = os.getcwd()
full_path = cwd + '/engine/'
if not os.path.isdir(full_path):
print('engine directory doesnt exists.')
exit()
os.chdir(full_path)
#apply the patch to just the working directory, without creating a commit
#if 'c' in arg:
# subprocess.call('git apply --index ../patches/compilation_db.patch', shell=True)
#unstage all files
subprocess.call('git reset', shell=True)
exit()
opts = Variables(args=ARGUMENTS)
opts.Add('a', 'What to do', '')
opts.Add(EnumVariable('action', 'What to do', 'setup', ('setup', 'update')))
opts.Add('t', 'Action target', '')
opts.Add(EnumVariable('target', 'Action target', 'all', ('all', 'engine', 'modules', 'all_addons', 'addons', 'third_party_addons')))
opts.Add(EnumVariable('repository_type', 'Type of repositories to clone from first', 'http', ('http', 'ssh')))
opts.Update(env)
Help(opts.GenerateHelpText(env))
load_target_commits_array()
rt = env['repository_type']
if rt == 'ssh':
repository_index = 1
action = env['action']
target = env['target']
if env['a']:
action = env['a']
if env['t']:
target = env['t']
if not os.path.isdir('./modules'):
os.mkdir('./modules')
if 'm' in action:
godot_branch = 'master'
if 'setup' in action or action[0] == 's':
if target == 'all':
setup_all()
elif target == 'engine':
setup_engine()
elif target == 'modules':
setup_modules()
elif target == 'all_addons':
setup_addons()
setup_addons_third_party_addons()
elif target == 'addons':
setup_addons()
elif target == 'third_party_addons':
setup_addons_third_party_addons()
elif 'update' in action or action[0] == 'u':
if target == 'all':
update_all()
elif target == 'engine':
update_engine()
save_target_commits_array()
elif target == 'modules':
update_modules()
save_target_commits_array()
elif target == 'all_addons':
update_addons()
update_addons_third_party_addons()
save_target_commits_array()
elif target == 'addons':
update_addons()
save_target_commits_array()
elif target == 'third_party_addons':
update_addons_third_party_addons()
save_target_commits_array()

View File

@ -0,0 +1,292 @@
#include "wp_application.h"
#include "core/http/request.h"
#include <iostream>
#include "core/file_cache.h"
#include "core/http/handler_instance.h"
#include "core/database/database_manager.h"
#include "core/database/query_builder.h"
#include "core/database/query_result.h"
#include "core/html/html_builder.h"
#include "core/http/http_session.h"
#include "core/http/session_manager.h"
#include "core/utils.h"
void WPApplication::index_fun(Object *instance, Request *request) {
WPApplication *app = Object::cast_to<WPApplication>(instance);
app->index(request);
}
void WPApplication::blog_fun(Object *instance, Request *request) {
WPApplication *app = Object::cast_to<WPApplication>(instance);
app->blog(request);
}
void WPApplication::index(Request *request) {
request->head += header;
HTMLBuilder b;
b.div("content");
b.div("content_head")->f()->w("Saved blogs:")->cdiv();
for (int i = 0; i < _blog_data.size(); ++i) {
BlogData &bd = _blog_data[i];
b.div("content_row")->f()->fa("/blog/" + bd.name + "/", bd.name, "blog_link")->cdiv();
}
b.cdiv();
request->body += b.result;
request->body += footer;
request->compile_and_send_body();
}
void WPApplication::blog(Request *request) {
request->head += header;
String blog = request->get_current_path_segment();
Database *db = nullptr;
for (int i = 0; i < _blog_data.size(); ++i) {
BlogData &bd = _blog_data[i];
if (bd.name == blog) {
db = bd.db;
break;
}
}
if (!db) {
request->send_error(404);
return;
}
request->push_path();
HTMLBuilder b;
int page = 1;
String action_segment = request->get_current_path_segment();
if (action_segment == "") {
// nothign to do
} else if (action_segment == "page") {
request->push_path();
page = request->get_current_path_segment().to_int();
} else if (action_segment == "post") {
request->push_path();
int post_id = request->get_current_path_segment().to_int();
PostData *p = get_post(db, post_id);
if (!p) {
request->send_error(404);
return;
}
b.div("content");
b.div("blog_content")->f()->w(p->data)->cdiv();
b.cdiv();
request->body += b.result;
request->body += footer;
request->compile_and_send_body();
return;
} else {
request->send_error(404);
return;
}
if (page <= 0) {
page = 1;
}
--page;
Vector<PostData *> posts = get_posts(db, page);
int post_count = (get_post_count(db) / 5.0) + 0.9;
b.div("content");
b.w(Utils::get_pagination("/blog/" + blog + "/page/", post_count, page));
if (posts.size() != 0) {
for (int i = 0; i < posts.size(); ++i) {
PostData *p = posts[i];
b.div("blog_content_row");
b.div("blog_entry_link")->f()->fa("/blog/" + blog + "/post/" + String::num(p->id), "Open")->cdiv();
b.div("blog_content")->f()->w(p->data)->cdiv();
b.cdiv();
}
} else {
b.fdiv("No saved blog posts.", "blog_content_row");
}
b.w(Utils::get_pagination("/blog/" + blog + "/page/", post_count, page));
b.cdiv();
request->body += b.result;
request->body += footer;
request->compile_and_send_body();
}
Vector<WPApplication::PostData *> WPApplication::get_posts(Database *db, const int page, const int num_per_page) {
Ref<QueryBuilder> qb = db->get_query_builder();
qb->select("id,url,extracted_data")->from("data")->order_by_desc("id")->corder_by()->limit(num_per_page)->offset(page * num_per_page)->end_command();
Ref<QueryResult> res = qb->run();
Vector<PostData *> r;
while (res->next_row()) {
PostData *p = new PostData();
p->id = res->get_cell_int(0);
p->url = res->get_cell(1);
p->data = res->get_cell(2);
r.push_back(p);
}
return r;
}
int WPApplication::get_post_count(Database *db) {
Ref<QueryBuilder> qb = db->get_query_builder();
qb->select("COUNT(id)")->from("data")->end_command();
Ref<QueryResult> res = qb->run();
if (!res->next_row()) {
return 0;
}
return res->get_cell_int(0);
}
WPApplication::PostData *WPApplication::get_post(Database *db, const int id) {
Ref<QueryBuilder> qb = db->get_query_builder();
qb->select("id,url,extracted_data")->from("data")->where()->wp("id", id)->end_command();
Ref<QueryResult> res = qb->run();
if (!res->next_row()) {
return nullptr;
}
PostData *p = new PostData();
p->id = res->get_cell_int(0);
p->url = res->get_cell(1);
p->data = res->get_cell(2);
return p;
}
void WPApplication::routing_middleware(Object *instance, Request *request) {
String path = request->get_path_full();
WPApplication *app = Object::cast_to<WPApplication>(instance);
if (FileCache::get_singleton()->wwwroot_has_file(path)) {
app->send_file(path, request);
return;
}
bool handled = false;
if (request->get_path_segment_count() == 0) {
handled = true;
request->handler_instance = app->index_func;
} else {
const String main_route = request->get_current_path_segment();
request->push_path();
if (main_route == "blog") {
handled = true;
request->handler_instance = app->blog_func;
}
}
if (!handled) {
app->send_error(404, request);
return;
}
request->next_stage();
}
void WPApplication::setup_routes() {
DWebApplication::setup_routes();
index_func = HandlerInstance(index_fun, this);
blog_func = HandlerInstance(blog_fun, this);
}
void WPApplication::setup_middleware() {
middlewares.push_back(HandlerInstance(routing_middleware, this));
}
void WPApplication::migrate() {
}
void WPApplication::add_blog(const String &name, Database *db) {
BlogData bd;
bd.name = name;
bd.db = db;
_blog_data.push_back(bd);
}
void WPApplication::compile_menu() {
HTMLBuilder bh;
bh.meta()->charset_utf_8();
bh.title();
bh.w("WPSaver");
bh.ctitle();
bh.link()->rel_stylesheet()->href("/site.css");
bh.write_tag();
header = bh.result;
HTMLBuilder bf;
bf.cdiv();
bf.footer();
bf.cfooter();
footer = bf.result;
}
WPApplication::WPApplication() :
DWebApplication() {
compile_menu();
}
WPApplication::~WPApplication() {
}

View File

@ -0,0 +1,58 @@
#ifndef WP_APPLICATION_H
#define WP_APPLICATION_H
//#include "core/http/web_application.h"
#include "core/object.h"
#include "core/string.h"
#include "modules/drogon/web_application.h"
class Database;
class WPApplication : public DWebApplication {
RCPP_OBJECT(WPApplication, DWebApplication);
public:
static void index_fun(Object *instance, Request *request);
static void blog_fun(Object *instance, Request *request);
void index(Request *request);
void blog(Request *request);
struct PostData {
int id;
String url;
String data;
};
Vector<PostData *> get_posts(Database *db, const int page, const int num_per_page = 5);
PostData * get_post(Database *db, const int id);
int get_post_count(Database *db);
static void routing_middleware(Object *instance, Request *request);
virtual void setup_routes();
virtual void setup_middleware();
virtual void migrate();
void add_blog(const String &name, Database *db);
void compile_menu();
WPApplication();
~WPApplication();
HandlerInstance blog_func;
String header;
String footer;
struct BlogData {
String name;
Database *db;
};
Vector<BlogData> _blog_data;
};
#endif

View File

@ -0,0 +1,250 @@
#include "wp_downloader.h"
#include <string.h>
#include <chrono>
#include <iostream>
#include <string>
#include "core/math/math.h"
#include "core/database/database_manager.h"
#include "core/database/query_builder.h"
#include "core/database/query_result.h"
#include "core/database/table_builder.h"
#include "core/html/html_parser.h"
#include "core/settings.h"
#include "modules/drogon/drogon/lib/inc/drogon/HttpClient.h"
#include "modules/drogon/drogon/lib/inc/http/HttpRequest.h"
void WPDownloader::setup_database() {
Ref<QueryBuilder> qb = db->get_query_builder();
qb->select("name")->from("sqlite_master")->where()->wp("type", "table")->land()->wp("name", "settings")->end_command();
Ref<QueryResult> res = qb->run();
if (res->next_row()) {
return;
}
qb->reset();
Ref<TableBuilder> tb = db->get_table_builder();
tb->create_table("settings");
tb->integer("id")->auto_increment()->next_row();
tb->varchar("last_url", 1000)->not_null()->next_row();
tb->integer("table_version")->not_null()->next_row();
tb->primary_key("id");
tb->ccreate_table();
tb->create_table("data");
tb->integer("id")->auto_increment()->next_row();
tb->varchar("url", 1000)->not_null()->next_row();
tb->text("full_data")->not_null()->next_row();
tb->text("extracted_data")->not_null()->next_row();
tb->primary_key("id");
tb->ccreate_table();
tb->run_query();
qb->insert("settings", "id,last_url,table_version")->values()->val(1)->val("")->val(1)->cvalues()->end_command();
qb->run_query();
}
String WPDownloader::get_last_url() {
Ref<QueryBuilder> qb = db->get_query_builder();
qb->select("last_url")->from("settings")->where()->wp("id", 1)->end_command();
Ref<QueryResult> res = qb->run();
if (!res->next_row()) {
RLOG_ERR("get_last_url: !res->next_row()");
return "";
}
return String(res->get_cell(0));
}
void WPDownloader::save_page(const String &url, const String &full_data, const String &extracted_data) {
Ref<QueryBuilder> qb = db->get_query_builder();
qb->begin_transaction();
qb->insert("data", "url,full_data,extracted_data")->values()->val(url)->val(full_data)->val(extracted_data)->cvalues()->end_command();
qb->update("settings")->set()->setp("last_url", url)->cset()->end_command();
qb->commit();
qb->run();
}
void WPDownloader::query_page(trantor::EventLoop *loop, const String &url, const String &path) {
drogon::HttpClientPtr http_client = drogon::HttpClient::newHttpClient(url, loop, false, false);
http_client->setUserAgent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0");
drogon::HttpRequestPtr request = drogon::HttpRequest::newHttpRequest();
request->setMethod(drogon::HttpMethod::Get);
request->setPath(path);
// request->setCustomContentTypeString("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\nAccept-Language: en-US,en;q=0.5\n");
bool done = false;
http_client->sendRequest(request, [this, &done](drogon::ReqResult res, const drogon::HttpResponsePtr &resptr) {
if (res != drogon::ReqResult::Ok) {
RLOG_ERR("sendRequest: res != ReqResult::Ok!");
done = true;
return;
}
RLOG_MSG("Got response. Saving.");
ss = new String(resptr->getBody().data());
done = true;
});
while (!done) {
// todo remove
}
}
void WPDownloader::download_posts(const String &site) {
setup_database();
String url = Settings::get_singleton()->get_value(site + ".url");
String port = Settings::get_singleton()->get_value(site + ".port");
String first_url = Settings::get_singleton()->get_value(site + ".first_url");
String last_url = get_last_url();
// String url = "127.0.0.1";
// String port = "http";
// String first_url = "/";
// String last_url = get_last_url();
String full_site_url = port + "://" + url;
String full_site_url_repl = full_site_url;
if (full_site_url_repl.ends_with("/")) {
full_site_url_repl.pop_back();
}
int wait_seconds_min = Settings::get_singleton()->get_value_int(site + ".wait_seconds_min", 10);
int wait_seconds_max = Settings::get_singleton()->get_value_int(site + ".wait_seconds_max", 20);
bool should_skip = true;
if (last_url == "") {
should_skip = false;
last_url = first_url;
}
RLOG_MSG("Post downloading started for " + site + " | last url: " + last_url);
while (!done) {
RLOG_MSG("Sending query to: " + full_site_url + last_url);
query_page(main_event_loop, full_site_url, last_url);
if (ss) {
HTMLParser p;
p.parse(*ss);
HTMLParserTag *article_tag = p.root->get_first("article");
String extracted_data = "";
String next_link;
if (article_tag) {
extracted_data = article_tag->to_string();
} else {
RLOG_WARN("Couldn't extract data!");
}
HTMLParserTag *n_link_tag = p.root->get_first("a", "rel", "next");
if (n_link_tag) {
next_link = n_link_tag->get_attribute_value("href");
if (next_link == "") {
RLOG_WARN("Couldn't extract link!");
}
} else {
next_link = "";
RLOG_WARN("Couldn't extract link tag!");
}
if (should_skip) {
should_skip = false;
RLOG_MSG("Continuing from last session, this page is already saved, skipping.");
} else {
save_page(last_url, *ss, extracted_data);
}
if (next_link == "") {
done = true;
} else {
int wait_seconds = Math::rand(wait_seconds_min, wait_seconds_max);
RLOG_MSG("Waiting for " + String::num(wait_seconds) + " seconds!");
std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(wait_seconds * 1000));
last_url = next_link;
if (last_url.starts_with(full_site_url_repl)) {
last_url.replace(full_site_url_repl, "", 1);
}
}
} else {
done = true;
}
delete ss;
ss = nullptr;
}
}
void WPDownloader::setup(const String &site, Database *p_db) {
site_name = site;
db = p_db;
}
void WPDownloader::run() {
download_posts(site_name);
}
void WPDownloader::stop() {
done = true;
}
void WPDownloader::_thread_func() {
main_event_loop = new trantor::EventLoop();
main_event_loop->loop();
delete main_event_loop;
main_event_loop = nullptr;
}
WPDownloader::WPDownloader() {
done = false;
save_original_data = true;
main_event_loop = nullptr;
ss = nullptr;
t = nullptr;
db = nullptr;
t = new std::thread(&WPDownloader::_thread_func, this);
while (main_event_loop == nullptr) {
// todo sleep
}
}
WPDownloader::~WPDownloader() {
main_event_loop->quit();
t->join();
delete t;
t = nullptr;
}

View File

@ -0,0 +1,38 @@
#ifndef WP_DOWNLOADER_H
#define WP_DOWNLOADER_H
#include "core/reference.h"
#include "core/database/database.h"
#include "modules/drogon/trantor/net/EventLoop.h"
class WPDownloader : public Reference {
RCPP_OBJECT(WPDownloader, Reference);
public:
void setup_database();
String get_last_url();
void save_page(const String &url, const String &full_data, const String &extracted_data);
void query_page(trantor::EventLoop *loop, const String &url, const String &path);
void download_posts(const String &site);
void setup(const String &site, Database *p_db);
void run();
void stop();
void _thread_func();
WPDownloader();
~WPDownloader();
bool done;
bool save_original_data;
String site_name;
trantor::EventLoop *main_event_loop;
String *ss;
std::thread *t;
Database *db;
};
#endif

View File

@ -0,0 +1,44 @@
# Copyright (c) 2019-2020 Péter Magyar
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Rename this file to build.config to use it
# Lines starting with # are comments. (Only works at the start of the line!)
# Note:
# ~ will be converted to %userprofile% on windows
# / will be converted to \ on windows
# so you don't have to worry about it
# Visual studio related setup:
visual_studio_call_vcvarsall True
visual_studio_vcvarsall_path C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat
visual_studio_arch amd64
# export related setup
# available export targets: global, linux, windows, android, javascript
export global SCONS_CACHE=~/.scons_cache
export global SCONS_CACHE_LIMIT=5000
export android ANDROID_NDK_ROOT=~/SDKs/Android/NDK/android-ndk-r20b
export android ANDROID_NDK_HOME=~/SDKs/Android/NDK/android-ndk-r20b
export android ANDROID_HOME=~/SDKs/Android/SDK

1
wp_saver_rcpp_fw/build.sh Executable file
View File

@ -0,0 +1 @@
scons bl -j4

106
wp_saver_rcpp_fw/main.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <string.h>
#include "core/file_cache.h"
#include "core/math/math.h"
#include "core/os/platform.h"
#include "core/settings.h"
#include "database/db_init.h"
// Backends
#include "backends/hash_hashlib/setup.h"
#include "core/database/database_manager.h"
#include "platform/platform_initializer.h"
#include "core/settings.h"
#include "app/wp_application.h"
#include "app/wp_downloader.h"
void initialize_backends() {
initialize_database_backends();
backend_hash_hashlib_install_providers();
}
int main(int argc, char **argv, char **envp) {
PlatformInitializer::allocate_all();
PlatformInitializer::arg_setup(argc, argv, envp);
initialize_backends();
String database_folder = "./data/";
Settings *settings = new Settings(true);
settings->parse_ini_file("settings.ini");
DatabaseManager *dbm = new DatabaseManager();
bool download = Platform::get_singleton()->arg_parser.has_arg("-d");
if (download) {
Vector<Ref<WPDownloader> > downloaders;
bool save_original_data = settings->get_value_bool("save_original_data");
if (save_original_data) {
String sites = settings->get_value("sites");
int sc = sites.get_slice_count(',');
for (int i = 0; i < sc; ++i) {
String s = sites.get_slice(',', i);
uint32_t index = dbm->create_database("sqlite");
Database *db = dbm->databases[index];
db->connect(database_folder + s + ".sqlite");
Ref<WPDownloader> d;
d.instance();
d->setup(s, db);
// todo
// downloaders.push_back(d);
d->run();
}
}
} else {
FileCache *file_cache = new FileCache(true);
file_cache->wwwroot = "./www";
file_cache->wwwroot_refresh_cache();
WPApplication *app = new WPApplication();
app->load_settings();
app->setup_routes();
app->setup_middleware();
app->add_listener("127.0.0.1", 8080);
String sites = settings->get_value("sites");
int sc = sites.get_slice_count(',');
for (int i = 0; i < sc; ++i) {
String s = sites.get_slice(',', i);
uint32_t index = dbm->create_database("sqlite");
Database *db = dbm->databases[index];
db->connect(database_folder + s + ".sqlite");
app->add_blog(s, db);
}
LOG_INFO << "Server running on 127.0.0.1:8080";
printf("Initialized!\n");
app->run();
delete app;
delete file_cache;
}
delete dbm;
delete settings;
PlatformInitializer::free_all();
return 0;
}

1
wp_saver_rcpp_fw/migrate.sh Executable file
View File

@ -0,0 +1 @@
./engine/bin/server m

1
wp_saver_rcpp_fw/run.sh Executable file
View File

@ -0,0 +1 @@
./engine/bin/server

View File

@ -0,0 +1,12 @@
sites=test1,test2
save_original_data=true
original_data_backend=database
a.url=https://test1.net/
a.directory=test1
a.original_data_table=test1
b.url=https://test2.net/
b.directory=test2
b.original_data_table=test2

1
wp_saver_rcpp_fw/wg Normal file
View File

@ -0,0 +1 @@
wget -E -H -k -p -T 15 -nd

View File

@ -0,0 +1,44 @@
.content {
width: 1000px;
margin: 0 auto;
}
.pagination {
display: inline-block;
margin: 2em auto;
width: 900px;
list-style-type: none;
}
.pagination .disabled {
background-color: rgb(68, 68, 68);
color: rgb(223, 223, 223);
float: left;
padding: 8px 16px;
text-decoration: none;
border: 1px solid #ddd;
}
.pagination a {
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
border: 1px solid #ddd;
}
.pagination a:hover:not(.active) {
background-color: #ddd;
}
.blog_content_row {
margin: 2em 0;
border: 1px solid #ddd;
padding: 1em;
}
.blog_content {
margin: 2em 0;
border: 1px solid #ddd;
padding: 1em;
}